Index: lib/Mail/SpamAssassin.pm =================================================================== RCS file: /cvsroot/spamassassin/spamassassin/lib/Mail/SpamAssassin.pm,v retrieving revision 1.100 diff -u -p -d -b -r1.100 SpamAssassin.pm --- lib/Mail/SpamAssassin.pm 20 Jun 2002 17:02:41 -0000 1.100 +++ lib/Mail/SpamAssassin.pm 23 Jun 2002 19:12:23 -0000 @@ -416,16 +416,17 @@ sub remove_spamassassin_markup { } # remove the headers we added - 1 while $hdrs =~ s/\nX-Spam-[^\n]*?\n/\n/gs; - - my $tag = $self->{conf}->{subject_tag}; + $hdrs =~ s/^X-Spam-[[:alnum:]-]+: .*?\n//gm; - while ( $tag =~ /(_HITS_|_REQD_)/g ) { - my $typeoftag = $1; - $hdrs =~ s/^Subject: (\D*)\d\d\.\d\d/Subject: $1$typeoftag/m; - } # Wow. Very Hackish. + my $tag = $self->{conf}->{tag_header_string}; + $tag = quotemeta($tag); + $tag =~ s/_HITS_/\\d{2}\\.\\d{2}/g; + $tag =~ s/_REQD_/\\d{2}\\.\\d{2}/g; - 1 while $hdrs =~ s/^Subject: \Q${tag}\E /Subject: /gm; + $hdrs =~ s/^Subject: ${tag} /Subject: /gm; + $tag = '\(' . $tag . '\)'; + $hdrs =~ s/^(From: .*?)\t${tag}$/$1/gm; + $hdrs =~ s/^(To: .*?)\t${tag}$/$1/gm; # ok, next, the report. # This is a little tricky since we can have either 0, 1 or 2 reports; Index: lib/Mail/SpamAssassin/Conf.pm =================================================================== RCS file: /cvsroot/spamassassin/spamassassin/lib/Mail/SpamAssassin/Conf.pm,v retrieving revision 1.72 diff -u -p -d -b -r1.72 Conf.pm --- lib/Mail/SpamAssassin/Conf.pm 10 Jun 2002 07:59:38 -0000 1.72 +++ lib/Mail/SpamAssassin/Conf.pm 23 Jun 2002 19:12:24 -0000 @@ -6,7 +6,7 @@ Mail::SpamAssassin::Conf - SpamAssassin # a comment - rewrite_subject 1 + tag_header subject from full PARA_A_2_C_OF_1618 /Paragraph .a.{0,10}2.{0,10}C. of S. 1618/i describe PARA_A_2_C_OF_1618 Claims compliance with senate bill 1618 @@ -120,10 +120,10 @@ sub new { $self->{auto_whitelist_file_mode} = '0600'; # as string, with --x bits $self->{auto_whitelist_factor} = 0.5; - $self->{rewrite_subject} = 1; + $self->{tag_header} = ['subject']; + $self->{tag_header_string} = '*****SPAM*****'; $self->{spam_level_stars} = 1; $self->{spam_level_char} = '*'; - $self->{subject_tag} = '*****SPAM*****'; $self->{report_header} = 0; $self->{use_terse_report} = 0; $self->{defang_mime} = 1; @@ -327,16 +327,86 @@ SpamAssassin as a handle for that test; $self->{scores}->{$1} = $2+0.0; next; } -=item rewrite_subject { 0 | 1 } (default: 1) +=item tag_header { subject | from | to | none } (default: subject) -By default, the subject lines of suspected spam will be tagged. This can be -disabled here. +By default, the subject lines of suspected spam will be tagged. With this +space-separated list the tagging can be extended to other headers (From and +To) or disabled completely. The use of the old option C is +deprecated. =cut - if (/^rewrite[-_]subject\s+(\d+)$/) { - $self->{rewrite_subject} = $1+0; next; + if (/^tag[-_]headers?\s+(.+)$/) { + my @h = sort(split(/\s+/, $1)); + unshift(@h, ''); + for (my $i = 1; $i < scalar(@h); $i++) { + if ($h[$i] eq 'none') { + @h = ('none'); + last; + } + $h[$i] = ucfirst(lc($h[$i])); + if (($h[$i] !~ /^(?:Subject|From|To)$/) or + ($h[$i] eq $h[$i - 1])) { + splice(@h, $i, 1); + redo; + } + } + shift(@h); + + if(@h) { + @{$self->{tag_header}} = @h; + } else { + $self->{tag_header} = undef; + } + next; + } + if (/^rewrite[-_]subject\s+(\d+)$/) { # for backward compatibility + dbg('config option rewrite_subject is deprecated; please use tag_header'); + my @h = defined($self->{tag_header}) ? @{$self->{tag_header}} : (); + + my $missing = 1; + for (my $i = 0; $i < scalar(@h); $i++) { + if ($h[$i] eq 'Subject') { + $missing = 0; + unless ($1) { + splice(@h, $i, 1); + } + last; + } + } + if ($1 and $missing) { + push(@h, 'Subject'); + } + + if(@h) { + @{$self->{tag_header}} = @h; + } else { + $self->{tag_header} = undef; } + next; + } + +=item tag_header_string STRING ... (default: *****SPAM*****) + +Text added to the headers of mails that are considered spam. It will be +applied to the C, C and/or C header, according to +the C option. +The string _HITS_ in the tag will be replace with the calculated score +for this message. _REQD_ will be replaced with the threshold. + +=cut + + if (/^tag[-_]headers?[-_]string\s+(.+?)\s*$/) { + $self->{tag_header_string} = $1; next; + } + if (/^subject[-_]tag\s+(.+?)\s*$/) { # for backward compatibility. + dbg('config option subject_tag is deprecated; please use tag_header_string'); + $self->{tag_header_string} = $1; next; + } + +=item rewrite_subject { 0 | 1 } (default: 1) + +This option is deprecated. Please use C. =item spam_level_stars { 0 | 1 } (default: 1) @@ -369,18 +439,6 @@ Some people don't like escaping *'s thou if(/^spam[-_]level[-_]char\s+(.)$/) { $self->{spam_level_char} = $1; next; } - -=item subject_tag STRING ... (default: *****SPAM*****) - -Text added to the C line of mails that are considered spam, -if C is 1. _HITS_ in the tag will be replace with the calculated -score for this message. _REQD_ will be replaced with the threshold. - -=cut - - if (/^subject[-_]tag\s+(.+?)\s*$/) { - $self->{subject_tag} = $1; next; - } =item report_header { 0 | 1 } (default: 0) Index: lib/Mail/SpamAssassin/PerMsgStatus.pm =================================================================== RCS file: /cvsroot/spamassassin/spamassassin/lib/Mail/SpamAssassin/PerMsgStatus.pm,v retrieving revision 1.125 diff -u -p -d -b -r1.125 PerMsgStatus.pm --- lib/Mail/SpamAssassin/PerMsgStatus.pm 14 Jun 2002 22:28:35 -0000 1.125 +++ lib/Mail/SpamAssassin/PerMsgStatus.pm 23 Jun 2002 19:12:25 -0000 @@ -257,11 +257,11 @@ The modifications made are as follows: =over 4 -=item Subject: header for spam mails +=item Subject:, From: and/or To: header for spam mails -The string C<*****SPAM*****> (changeable with C config option) is -prepended to the subject, unless the C configuration option -is given. +The string C<*****SPAM*****> (changeable with C config +option) is prepended to the subject and/or appended as a comment to the +from and/or to, depending on the config option C. =item X-Spam-Status: header for spam mails @@ -364,22 +364,27 @@ sub rewrite_as_spam { $self->{msg}->delete_header ("X-Spam-Level"); } - # First, rewrite the subject line. - if ($self->{conf}->{rewrite_subject}) { - $_ = $srcmsg->get_header ("Subject"); - $_ ||= ''; - - my $tag = $self->{conf}->{subject_tag}; - - my $hit = sprintf ("%05.2f", $self->{hits}); - $tag =~ s/_HITS_/$hit/; + # First, rewrite the headers. + if ($self->{conf}->{tag_header}) { + my $tag = $self->{conf}->{tag_header_string}; + my $hits = sprintf ("%05.2f", $self->{hits}); + $tag =~ s/_HITS_/$hits/g; my $reqd = sprintf ("%05.2f", $self->{conf}->{required_hits}); - $tag =~ s/_REQD_/$reqd/; + $tag =~ s/_REQD_/$reqd/g; - s/^(?:\Q${tag}\E |)/${tag} /g; + foreach my $header (@{$self->{conf}->{tag_header}}) { + $_ = $srcmsg->get_header($header) || ''; - $self->{msg}->replace_header ("Subject", $_); + if ($header eq 'Subject') { + s/^(?:$\Q{tag}\E |)/${tag} /; + } + elsif ($header =~ /From|To/) { + s/(?:\t\Q(${tag})\E|)$/\t(${tag})/; + } + + $self->{msg}->replace_header($header, $_); + } } # add some headers... @@ -862,7 +867,7 @@ sub get_decoded_stripped_body_text_array if ($html) { # Convert tags - $text =~ s/<\/?Q\b[^>]*>/"/gis; + $text =~ s/<\/?Q\b[^>]*>/"/gis; #dummy"# because KWrite's highlighting sucks } if ($entities) {