View | Details | Raw Unified | Return to bug 5238
Collapse All | Expand All

(-)lib/Mail/SpamAssassin/PerMsgStatus.pm (-14 / +63 lines)
Lines 96-103 Link Here
96
  };
96
  };
97
  #$self->{main}->{use_rule_subs} = 1;
97
  #$self->{main}->{use_rule_subs} = 1;
98
98
99
  if (defined $opts && $opts->{disable_auto_learning}) {
99
  if (defined $opts) {
100
    $self->{disable_auto_learning} = 1;
100
    $self->{disable_auto_learning} = $opts->{disable_auto_learning};
101
    $self->{network_tests}         = $opts->{network_tests};
101
  }
102
  }
102
103
103
  # used with "mass-check --loghits"
104
  # used with "mass-check --loghits"
Lines 113-123 Link Here
113
  }
114
  }
114
115
115
  bless ($self, $class);
116
  bless ($self, $class);
117
118
  # Resident Mail::SpamAssassin code will possibly never change score
119
  # sets, even if bayes becomes available.  So we should do a quick check
120
  # to see if we should go from {0,1} to {2,3}.  We of course don't need
121
  # to do this switch if we're already using bayes ... ;)
122
  my $set = $self->{conf}->get_score_set();
123
  if (($set & 2) == 0 && $main->{bayes_scanner} && $main->{bayes_scanner}->is_scan_available()) {
124
    dbg("check: scoreset $set but bayes is available, switching scoresets");
125
    $set |= 2;
126
    $self->{conf}->set_score_set ($set);
127
  }
128
129
  if (defined $self->{network_tests}) {
130
    if ($self->{network_tests} == 0) {
131
      $set &= ~1;
132
    }
133
    elsif ($self->{network_tests} == 1) {
134
      if ($main->{local_tests_only}) {
135
        warn("check: options request network tests, but network tests are " .
136
             "off.");
137
      }
138
      else {
139
        $set |= 1;
140
      }
141
    }
142
  }
143
  $self->set_score_set($set);
144
116
  $self;
145
  $self;
117
}
146
}
118
147
119
###########################################################################
148
###########################################################################
120
149
150
=item $status->set_score_set ()
151
152
Sets scoreset used for this particular message.
153
154
=cut
155
156
sub set_score_set {
157
  my ($self, $set) = @_;
158
159
  $self->{scores}           = $self->{conf}->{scoreset}->[$set];
160
  $self->{scoreset_current} = $set;
161
}
162
163
###########################################################################
164
165
=item $status->get_score_set ()
166
167
Get scoreset used for this particular message.
168
169
=cut
170
171
sub get_score_set {
172
  my ($self) = @_;
173
174
  return $self->{scoreset_current};
175
}
176
177
178
###########################################################################
179
121
=item $status->check ()
180
=item $status->check ()
122
181
123
Runs the SpamAssassin rules against the message pointed to by the object.
182
Runs the SpamAssassin rules against the message pointed to by the object.
Lines 146-161 Link Here
146
  # TVD: we may want to do more than just clearing out the headers, but ...
205
  # TVD: we may want to do more than just clearing out the headers, but ...
147
  $self->{msg}->delete_header('X-Spam-.*');
206
  $self->{msg}->delete_header('X-Spam-.*');
148
207
149
  # Resident Mail::SpamAssassin code will possibly never change score
150
  # sets, even if bayes becomes available.  So we should do a quick check
151
  # to see if we should go from {0,1} to {2,3}.  We of course don't need
152
  # to do this switch if we're already using bayes ... ;)
153
  my $set = $self->{conf}->get_score_set();
154
  if (($set & 2) == 0 && $self->{main}->{bayes_scanner} && $self->{main}->{bayes_scanner}->is_scan_available()) {
155
    dbg("check: scoreset $set but bayes is available, switching scoresets");
156
    $self->{conf}->set_score_set ($set|2);
157
  }
158
159
  # The primary check functionality occurs via a plugin call.  For more
208
  # The primary check functionality occurs via a plugin call.  For more
160
  # information, please see: Mail::SpamAssassin::Plugin::Check
209
  # information, please see: Mail::SpamAssassin::Plugin::Check
161
  if (!$self->{main}->call_plugins ("check_main", { permsgstatus => $self }))
210
  if (!$self->{main}->call_plugins ("check_main", { permsgstatus => $self }))
Lines 331-339 Link Here
331
380
332
  # This function needs to use use sum($score[scoreset % 2]) not just {score}.
381
  # This function needs to use use sum($score[scoreset % 2]) not just {score}.
333
  # otherwise we shift what we autolearn on and it gets really wierd.  - tvd
382
  # otherwise we shift what we autolearn on and it gets really wierd.  - tvd
334
  my $orig_scoreset = $self->{conf}->get_score_set();
383
  my $orig_scoreset = $self->get_score_set();
335
  my $new_scoreset = $orig_scoreset;
384
  my $new_scoreset = $orig_scoreset;
336
  my $scores = $self->{conf}->{scores};
385
  my $scores = $self->{scores};
337
386
338
  if (($orig_scoreset & 2) == 0) { # we don't need to recompute
387
  if (($orig_scoreset & 2) == 0) { # we don't need to recompute
339
    dbg("learn: auto-learn: currently using scoreset $orig_scoreset");
388
    dbg("learn: auto-learn: currently using scoreset $orig_scoreset");
(-)lib/Mail/SpamAssassin/Plugin/Check.pm (-7 / +8 lines)
Lines 182-188 Link Here
182
  }
182
  }
183
183
184
  while (my ($rulename, $test) = each %{$pms->{conf}->{rbl_evals}}) {
184
  while (my ($rulename, $test) = each %{$pms->{conf}->{rbl_evals}}) {
185
    my $score = $pms->{conf}->{scores}->{$rulename};
185
    my $score = $pms->{scores}->{$rulename};
186
    next unless $score;
186
    next unless $score;
187
187
188
    $pms->{test_log_msgs} = ();        # clear test state
188
    $pms->{test_log_msgs} = ();        # clear test state
Lines 348-361 Link Here
348
        # rule referred to in a meta...
348
        # rule referred to in a meta...
349
        $meta{$rulename} .= "(\$h->{'$token'} || 0) ";
349
        $meta{$rulename} .= "(\$h->{'$token'} || 0) ";
350
      
350
      
351
        if (!exists $conf->{scores}->{$token}) {
351
        if (!exists $pms->{scores}->{$token}) {
352
          dbg("rules: meta test $rulename has undefined dependency '$token'");
352
          dbg("rules: meta test $rulename has undefined dependency '$token'");
353
        }
353
        }
354
        elsif ($conf->{scores}->{$token} == 0) {
354
        elsif ($pms->{scores}->{$token} == 0) {
355
          # bug 5040: net rules in a non-net scoreset
355
          # bug 5040: net rules in a non-net scoreset
356
          # there are some cases where this is expected; don't warn
356
          # there are some cases where this is expected; don't warn
357
          # in those cases.
357
          # in those cases.
358
          unless ((($conf->get_score_set()) & 1) == 0 &&
358
          unless ((($pms->get_score_set()) & 1) == 0 &&
359
              ($conf->{tflags}->{$token}||'') =~ /\bnet\b/)
359
              ($conf->{tflags}->{$token}||'') =~ /\bnet\b/)
360
          {
360
          {
361
            info("rules: meta test $rulename has dependency '$token' with a zero score");
361
            info("rules: meta test $rulename has dependency '$token' with a zero score");
Lines 853-859 Link Here
853
  # clean up priority value so it can be used in a subroutine name 
853
  # clean up priority value so it can be used in a subroutine name 
854
  my $clean_priority;
854
  my $clean_priority;
855
  ($clean_priority = $priority) =~ s/-/neg/;
855
  ($clean_priority = $priority) =~ s/-/neg/;
856
  my $scoreset = $conf->get_score_set();
856
  my $scoreset = $pms->get_score_set();
857
  my $package_name = __PACKAGE__;
857
  my $package_name = __PACKAGE__;
858
858
859
  my $methodname = '_eval_tests'.
859
  my $methodname = '_eval_tests'.
Lines 989-995 Link Here
989
    sub ${methodname} {
989
    sub ${methodname} {
990
      my (\$self, \@extraevalargs) = \@_;
990
      my (\$self, \@extraevalargs) = \@_;
991
991
992
      my \$scoresptr = \$self->{conf}->{scores};
992
#      my \$scoresptr = \$self->{conf}->{scores};
993
      my \$scoresptr = \$self->{scores};
993
      my \$prepend2desc = q#$prepend2desc#;
994
      my \$prepend2desc = q#$prepend2desc#;
994
      my \$rulename;
995
      my \$rulename;
995
      my \$result;
996
      my \$result;
Lines 1039-1045 Link Here
1039
  my $evalstr = '
1040
  my $evalstr = '
1040
1041
1041
      # start_rules_plugin_code '.$ruletype.' '.$pri.'
1042
      # start_rules_plugin_code '.$ruletype.' '.$pri.'
1042
      my $scoresptr = $self->{conf}->{scores};
1043
      my $scoresptr = $self->{scores};
1043
1044
1044
  ';
1045
  ';
1045
1046
(-)lib/Mail/SpamAssassin/Plugin/Razor2.pm (-1 / +1 lines)
Lines 436-442 Link Here
436
  # continue.
436
  # continue.
437
  return unless $self->{razor2_available};
437
  return unless $self->{razor2_available};
438
  return unless $self->{main}->{conf}->{use_razor2};
438
  return unless $self->{main}->{conf}->{use_razor2};
439
  return unless $self->{main}->{conf}->{scores}->{'RAZOR2_CHECK'};
439
  return unless $permsgstatus->{scores}->{'RAZOR2_CHECK'};
440
440
441
  # If Razor2 hasn't been checked yet, go ahead and run it.
441
  # If Razor2 hasn't been checked yet, go ahead and run it.
442
  unless (defined $permsgstatus->{razor2_result}) {
442
  unless (defined $permsgstatus->{razor2_result}) {
(-)lib/Mail/SpamAssassin/Plugin/P595Body.pm (-1 / +1 lines)
Lines 136-142 Link Here
136
  }
136
  }
137
137
138
  my $do_dbg = (would_log('dbg', 'zoom') > 1);
138
  my $do_dbg = (would_log('dbg', 'zoom') > 1);
139
  my $scoresptr = $conf->{scores};
139
  my $scoresptr = $scanner->{scores};
140
140
141
  dbg("zoom: run_body_fast_scan for $ruletype start");
141
  dbg("zoom: run_body_fast_scan for $ruletype start");
142
142
(-)lib/Mail/SpamAssassin/Plugin/AWL.pm (-1 / +1 lines)
Lines 335-341 Link Here
335
      }
335
      }
336
    }
336
    }
337
337
338
    my $scores = $pms->{conf}->{scores};
338
    my $scores = $pms->{scores};
339
    my $tflags = $pms->{conf}->{tflags};
339
    my $tflags = $pms->{conf}->{tflags};
340
    my $points = 0;
340
    my $points = 0;
341
341
(-)lib/Mail/SpamAssassin/Plugin/RabinKarpBody.pm (-1 / +1 lines)
Lines 131-137 Link Here
131
  }
131
  }
132
132
133
  my $do_dbg = (would_log('dbg', 'zoom') > 1);
133
  my $do_dbg = (would_log('dbg', 'zoom') > 1);
134
  my $scoresptr = $conf->{scores};
134
  my $scoresptr = $scanner->{scores};
135
135
136
  dbg("zoom: run_body_fast_scan for $ruletype start");
136
  dbg("zoom: run_body_fast_scan for $ruletype start");
137
137
(-)spamc/libspamc.h (+3 lines)
Lines 128-133 Link Here
128
/* Jan 16, 2007 jm: get markup headers from spamd */
128
/* Jan 16, 2007 jm: get markup headers from spamd */
129
#define SPAMC_HEADERS         (1<<15)
129
#define SPAMC_HEADERS         (1<<15)
130
130
131
/* Sep 27, 2007 mc: tell spamd to not perform network tests */
132
#define SPAMC_LOCAL           (1<<14)
133
131
#define SPAMC_MESSAGE_CLASS_SPAM 1
134
#define SPAMC_MESSAGE_CLASS_SPAM 1
132
#define SPAMC_MESSAGE_CLASS_HAM  2
135
#define SPAMC_MESSAGE_CLASS_HAM  2
133
136
(-)spamc/spamc.c (+8 lines)
Lines 200-205 Link Here
200
    usg("  -z                  Compress mail message sent to spamd.\n");
200
    usg("  -z                  Compress mail message sent to spamd.\n");
201
#endif
201
#endif
202
    usg("  -f                  (Now default, ignored.)\n");
202
    usg("  -f                  (Now default, ignored.)\n");
203
    usg("  --local             Tell spamd not to perform any network tests\n"
204
        "                      on this message.\n");
203
205
204
    usg("\n");
206
    usg("\n");
205
}
207
}
Lines 252-257 Link Here
252
       { "help", no_argument, 0, 'h' },
254
       { "help", no_argument, 0, 'h' },
253
       { "version", no_argument, 0, 'V' },
255
       { "version", no_argument, 0, 'V' },
254
       { "compress", no_argument, 0, 'z' },
256
       { "compress", no_argument, 0, 'z' },
257
       { "local", no_argument, 0, 3},
255
       { 0, 0, 0, 0} /* last element _must_ be all zeroes */
258
       { 0, 0, 0, 0} /* last element _must_ be all zeroes */
256
    };
259
    };
257
    
260
    
Lines 471-476 Link Here
471
                flags |= SPAMC_HEADERS;
474
                flags |= SPAMC_HEADERS;
472
                break;
475
                break;
473
            }
476
            }
477
            case 3:
478
            {
479
                flags |= SPAMC_LOCAL;
480
                break;
481
            }
474
        }
482
        }
475
    }
483
    }
476
484
(-)spamc/libspamc.c (+3 lines)
Lines 1247-1252 Link Here
1247
      if (zlib_on) {
1247
      if (zlib_on) {
1248
	len += snprintf(buf + len, 8192-len, "Compress: zlib\r\n");
1248
	len += snprintf(buf + len, 8192-len, "Compress: zlib\r\n");
1249
      }
1249
      }
1250
      if (flags & SPAMC_LOCAL) {
1251
          len += snprintf(buf + len, 8192-len, "Network-tests: off\r\n");
1252
      }
1250
      if ((m->msg_len > SPAMC_MAX_MESSAGE_LEN) || ((len + 27) >= (bufsiz - len))) {
1253
      if ((m->msg_len > SPAMC_MAX_MESSAGE_LEN) || ((len + 27) >= (bufsiz - len))) {
1251
	_use_msg_for_out(m);
1254
	_use_msg_for_out(m);
1252
	return EX_DATAERR;
1255
	return EX_DATAERR;
(-)spamd/PROTOCOL (-3 / +23 lines)
Lines 27-35 Link Here
27
The first line from spamc is the command for spamd to execute (PROCESS a
27
The first line from spamc is the command for spamd to execute (PROCESS a
28
message is the command in protocol<=1.3) followed by the protocol version.
28
message is the command in protocol<=1.3) followed by the protocol version.
29
29
30
There may be additional headers following the command, which are as yet
30
There may be additional headers following the command, which are
31
undefined.  Servers should ignore these, and keep looking for headers which
31
described at the end of this document.  Servers should ignore headers
32
they do support, or the "\r\n\r\n" end-of-headers marker.
32
they don't understand and keep looking for headers which they do
33
support, or the "\r\n\r\n" end-of-headers marker.
33
34
34
The first line of the response from spamd is the protocol version (note this is
35
The first line of the response from spamd is the protocol version (note this is
35
SPAMD here, where it was SPAMC on the other side) followed by a response code
36
SPAMD here, where it was SPAMC on the other side) followed by a response code
Lines 191-196 Link Here
191
    by the client is compressed using Zlib compression.  (This is new in
192
    by the client is compressed using Zlib compression.  (This is new in
192
    SpamAssassin 3.2.0.)
193
    SpamAssassin 3.2.0.)
193
194
195
Set
196
197
    Set remote or local database for the TELL command.
198
199
Remove
200
201
    Remove remote or local database for the TELL command.
202
203
Network-tests
204
205
    If checking a message to see if it's spam or net, turn on or off
206
    network tests.  Requesting that network tests be turned on has
207
    no effect as of now, since if spamd is run with the local tests
208
    only option (-L or --local) then clients can't override this,
209
    and if the local tests only option isn't set then network tests
210
    are always run.  Requests for network tests to be turned off when
211
    spamd is run with the local tests only option will be silently
212
    ignored.
213
194
As-yet-undefined headers should not be treated as errors, and instead
214
As-yet-undefined headers should not be treated as errors, and instead
195
should be ignored.  Multiple headers can appear in requests and responses
215
should be ignored.  Multiple headers can appear in requests and responses
196
(this was not clearly defined until protocol version 1.3).
216
(this was not clearly defined until protocol version 1.3).
(-)spamd/spamd.raw (-1 / +25 lines)
Lines 1438-1443 Link Here
1438
  local ($_);
1438
  local ($_);
1439
  my $expected_length;
1439
  my $expected_length;
1440
  my $compress_zlib;
1440
  my $compress_zlib;
1441
  my $network_tests;
1441
1442
1442
  # used to ensure we don't accidentally fork (bug 4370)
1443
  # used to ensure we don't accidentally fork (bug 4370)
1443
  my $starting_self_pid = $$;
1444
  my $starting_self_pid = $$;
Lines 1452-1457 Link Here
1452
1453
1453
    $expected_length = $hdrs->{expected_length};
1454
    $expected_length = $hdrs->{expected_length};
1454
    $compress_zlib = $hdrs->{compress_zlib};
1455
    $compress_zlib = $hdrs->{compress_zlib};
1456
    $network_tests = $hdrs->{network_tests};
1455
  }
1457
  }
1456
1458
1457
  return 0 unless do_user_handling();
1459
  return 0 unless do_user_handling();
Lines 1490-1496 Link Here
1490
1492
1491
  # Go ahead and check the message
1493
  # Go ahead and check the message
1492
  $spamtest->init(1);
1494
  $spamtest->init(1);
1493
  my $status = Mail::SpamAssassin::PerMsgStatus->new($spamtest, $mail);
1495
  my $options = {network_tests => $network_tests};
1496
  my $status = Mail::SpamAssassin::PerMsgStatus->new($spamtest, $mail,
1497
                                                     $options);
1494
  $status->check();
1498
  $status->check();
1495
1499
1496
  my $msg_score     = sprintf( "%.1f", $status->get_score );
1500
  my $msg_score     = sprintf( "%.1f", $status->get_score );
Lines 1840-1845 Link Here
1840
    elsif ($header eq 'Compress') {
1844
    elsif ($header eq 'Compress') {
1841
      return 0 unless &got_compress_header($hdrs, $header, $value);
1845
      return 0 unless &got_compress_header($hdrs, $header, $value);
1842
    }
1846
    }
1847
    elsif ($header eq 'Network-tests') {
1848
      return 0 unless got_net_tests_header($hdrs, $header, $value);
1849
    }
1843
  }
1850
  }
1844
1851
1845
  # avoid too-many-headers DOS attack
1852
  # avoid too-many-headers DOS attack
Lines 1984-1989 Link Here
1984
  return 1;
1991
  return 1;
1985
}
1992
}
1986
1993
1994
sub got_net_tests_header {
1995
  my ($hdrs, $header, $value) = @_;
1996
1997
  if ($value =~ /^on\s*$/i) {
1998
    $hdrs->{network_tests} = 1;
1999
  }
2000
  elsif ($value =~ /^off\s*$/i) {
2001
    $hdrs->{network_tests} = 0;
2002
  }
2003
  else {
2004
      protocol_error("(Network-tests header can only have values 'on' or " .
2005
                     "'off')");
2006
      return 0;
2007
  }
2008
  return 1;
2009
}
2010
1987
sub protocol_error {
2011
sub protocol_error {
1988
  my ($err) = @_;
2012
  my ($err) = @_;
1989
  my $resp = "EX_PROTOCOL";
2013
  my $resp = "EX_PROTOCOL";

Return to bug 5238