Mail-SpamAssassin

 view release on metacpan or  search on metacpan

CREDITS  view on Meta::CPAN


  - Klaus Heinz, <klaus.heinz(at)onlinehome.de>: changes to rules;
    packaging fixes for UNIX package; German translation.

  - Ed Henderson, <ed.henderson(at)certainty.net>: fix for vpopmail support in
    spamd.

  - David Hull, <hull(at)paracel.com> <hull(at)davidhull.org>:
    rewrite_subject and report_header; rules

  - Morbus Iff, <morbus(at)disobey.com>: don't create prefs patch.

  - Steve Keay, <steve-spamassassin-bugzilla(at)keay.com>: spamd -A network
    ranges support.

  - Vivek Khera, <khera(at)kcilink.com>: contributed to Razor2 patch.

  - Alexander Kourakos, <awk(at)bnt.com>: bug fixes.

  - Juergen Kreileder, <kreilede(at)issan.informatik.uni-dortmund.de>:
    misc fixes; Bayes ignore Gnus annotation

MANIFEST  view on Meta::CPAN

lib/Mail/SpamAssassin/Util/ScopedTimer.pm
lib/Mail/SpamAssassin/Util/TieOneStringHash.pm
lib/spamassassin-run.pod
procmailrc.example
rules/active.list
rules/init.pre
rules/languages
rules/local.cf
rules/regression_tests.cf
rules/sa-update-pubkey.txt
rules/user_prefs.template
rules/v310.pre
rules/v312.pre
rules/v320.pre
rules/v330.pre
rules/v340.pre
rules/v341.pre
rules/v342.pre
rules/v343.pre
rules/v400.pre
rules/v401.pre

MANIFEST  view on Meta::CPAN

t/html_utf8.t
t/html_visibility.t
t/idn_dots.t
t/if_can.t
t/if_else.t
t/ifversion.t
t/ip_addrs.t
t/lang_lint.t
t/lang_pl_tests.t
t/line_endings.t
t/lint_nocreate_prefs.t
t/local_tests_only.t
t/memory_cycles.t
t/metadata.t
t/mimeheader.t
t/mimeparse.t
t/missing_hb_separator.t
t/mkrules.t
t/mkrules_else.t
t/nonspam.t
t/olevbmacro.t
t/originating_ip_hdr.t
t/parameter_header.t
t/pdfinfo.t
t/phishing.t
t/plugin.t
t/plugin_file.t
t/plugin_priorities.t
t/prefs_include.t
t/priorities.t
t/priorities_welcome_block.t
t/perlcritic.t
t/perlcritic.pl
t/podchecker.t
t/pyzor.t
t/razor2.t
t/rcvd_parser.t
t/re_base_extraction.t
t/recips.t

MANIFEST  view on Meta::CPAN

t/spamd_parallel.t
t/spamd_plugin.t
t/spamd_port.t
t/spamd_prefork_stress.t
t/spamd_prefork_stress_2.t
t/spamd_prefork_stress_3.t
t/spamd_prefork_stress_4.t
t/spamd_protocol_10.t
t/spamd_report.t
t/spamd_report_ifspam.t
t/spamd_sql_prefs.t
t/spamd_ssl.t
t/spamd_ssl_z.t
t/spamd_ssl_accept_fail.t
t/spamd_stop.t
t/spamd_symbols.t
t/spamd_syslog.t
t/spamd_unix.t
t/spamd_unix_and_tcp.t
t/spamd_user_rules_leak.t
t/spamd_utf8.t

Makefile.PL  view on Meta::CPAN


    'PMLIBDIRS' => [ 'lib' ],

    'PM_FILTER' => '$(PREPROCESS) -Mconditional -Mvars -DVERSION="$(VERSION)" \
	-DPREFIX="$(I_PREFIX)" \
	-DDEF_RULES_DIR="$(I_DATADIR)" \
	-DLOCAL_RULES_DIR="$(I_CONFDIR)" \
	-DLOCAL_STATE_DIR="$(I_LOCALSTATEDIR)"',

    'macro' => {
        DATAFILES => 'user_prefs.template languages sa-update-pubkey.txt'
    },

    # be quite explicit about this; afaik CPAN.pm is sensible using this
    'PREREQ_PM' => {
        'File::Spec'           => 0.8,           # older versions lack some routines we need
        'File::Copy'           => 2.02,          # this version is shipped with 5.005_03, the oldest version known to work
        'Pod::Usage'           => 1.10,          # all versions prior to this do seem to be buggy
        'HTML::Parser'         => 3.43,          # the HTML code is based on this parser, older versions have utf-8 bugs
        'Archive::Tar'         => 1.23,          # for sa-update
        'IO::Zlib'             => 1.04,          # for sa-update

README  view on Meta::CPAN

        Plugin control files, installed from the distribution. These are
        used to control what plugins are loaded.  Modifications here will
        be loaded before any configuration loaded from the above
        directories.
        
        You want to modify these files if you want to load additional
        plugins, or inhibit loading a plugin that is enabled by default.
        If the files exist in /etc/mail/spamassassin, they will not
        be overwritten during future installs.

  - /usr/share/spamassassin/user_prefs.template:

	Distributed default user preferences. Do not modify this, as it is
	overwritten when you upgrade.

  - /etc/mail/spamassassin/user_prefs.template:

	Default user preferences, for system admins to create, modify, and
	set defaults for users' preferences files.  Takes precedence over
	the above prefs file, if it exists.

        Do not put system-wide settings in here; put them in a file in the
        "/etc/mail/spamassassin" directory ending in ".cf". This file is
        just a template, which will be copied to a user's home directory
        for them to change.

  - $USER_HOME/.spamassassin:

  	User state directory.  Used to hold spamassassin state, such
	as a per-user automatic welcomelist, and the user's preferences
	file.

  - $USER_HOME/.spamassassin/user_prefs:

  	User preferences file.  If it does not exist, one of the
	default prefs file from above will be copied here for the
	user to edit later, if they wish.

	Unless you're using spamd, there is no difference in
	interpretation between the rules file and the preferences file, so
	users can add new rules for their own use in the
	"~/.spamassassin/user_prefs" file, if they like.  (spamd disables
	this for security and increased speed.)

  - $USER_HOME/.spamassassin/bayes*

	Statistics databases used for Bayesian filtering.  If they do
	not exist, they will be created by Apache SpamAssassin.

	Spamd users may wish to create a shared set of bayes databases;
	the "bayes_path" and "bayes_file_mode" configuration settings
	can be used to do this.

README  view on Meta::CPAN

        '__local_rules_dir__'
        '__prefix__/etc/mail/spamassassin'
        '__prefix__/etc/spamassassin'
        '/usr/local/etc/spamassassin'
        '/usr/pkg/etc/spamassassin'
        '/usr/etc/spamassassin'
        '/etc/mail/spamassassin'
        '/etc/spamassassin'

  - Default User Preferences File
        '__local_rules_dir__/user_prefs.template'
        '__prefix__/etc/mail/spamassassin/user_prefs.template'
        '__prefix__/share/spamassassin/user_prefs.template'
        '/etc/spamassassin/user_prefs.template'
        '/etc/mail/spamassassin/user_prefs.template'
        '/usr/local/share/spamassassin/user_prefs.template'
        '/usr/share/spamassassin/user_prefs.template'


In addition, the "Distributed Configuration Files" location is overridden
by a "Local State Directory", used to store an updated copy of the
ruleset:

  __prefix__    __local_state_dir__
  -------------------------------------------------------------------------
  /usr          /var/lib/spamassassin/__version__
  /usr/local    /var/lib/spamassassin/__version__

README  view on Meta::CPAN

default: experimental code, slow code, or code that depends on
non-open-source software or services that are not always free.  These
disabled tests include:

  - DCC: depends on non-open-source software (disabled in init.pre)
  - MAPS: commercial service (disabled in 50_scores.cf)
  - TextCat: slow (disabled in init.pre)
  - various optional plugins, disabled for speed (disabled in *.pre)

To turn on tests disabled in 50_scores.cf, simply assign them a non-zero
score, e.g. by adding score lines to your ~/.spamassassin/user_prefs file.

To turn on tests disabled by commenting out the required plugin in
init.pre, you need to uncomment the loadplugin line and make sure the
prerequisites for proper operation of the plugin are present.


Automatic Reputation System
--------------------------

Apache SpamAssassin includes an automatic reputation system. The way it works is

USAGE  view on Meta::CPAN

    will be overwritten when you upgrade.  Any changes you make in
    files in the /etc/mail/spamassassin directory,  however, will
    override these files.


  - Rules can be turned off by setting their scores to 0 in a
    configuration or user-preference file.


  - Speakers of Chinese, Japanese, Korean or Arabic may find it useful to
    turn off the rules listed at the end of the "user_prefs.template"
    file; we've found out that these rules are still triggering on
    non-spam CJK mails.


  - If you have an unusual network configuration, you should probably
    set 'trusted_networks'.  This allows SpamAssassin to determine where
    your internal network ends and the internet begins, and allows DNS
    checks to be more accurate. If your mail host is NATed, you will
    almost certainly need to set 'trusted_networks' to get correct
    results.

build/mkrules  view on Meta::CPAN

    loadplugin Mail::SpamAssassin::Plugin::Check
    loadplugin Mail::SpamAssassin::Plugin::URIDNSBL
    util_rb_tld com # skip "need to run sa-update" warn
    use_bayes 0
  };

  my $mailsa = Mail::SpamAssassin->new({
      rules_filename => "./rules",
      # debug => 1,
      local_tests_only => 1,
      dont_copy_prefs => 1,
      config_text => $pretext.$text
  });

  my $errors = 0;
  $mailsa->{lint_callback} = sub {
    my %opts = @_;

    return if ($opts{msg} =~ /
          (?:score\sset\sfor\snon-existent|description\sexists)
      /x);

ldap/README  view on Meta::CPAN


Using SpamAssassin With An LDAP Server
--------------------------------------

SpamAssassin can now load users' score files from an LDAP server.  The concept
here is to have a web application (PHP/perl/ASP/etc.) that will allow users to
be able to update their local preferences on how SpamAssassin will filter their
e-mail.  The most common use for a system like this would be for users to be
able to update the white list of addresses (welcomelist_from, previously whitelist_from) 
without the need for them to update their $HOME/.spamassassin/user_prefs file.  
It is also quite common for users listed in /etc/passwd to not have a home directory,
therefore, the only way to have their own local settings would be through a
database or LDAP server.

SpamAssassin will check the global configuration file (ie. any file matching
/etc/mail/spamassassin/*.cf) for the following settings:

  user_scores_dsn ldap://host:port/dc=basedn,dc=de?attr?scope?uid=__USERNAME__
  user_scores_ldap_username	bind dn
  user_scores_ldap_password	password

ldap/README  view on Meta::CPAN

To test your LDAP setup, and debug any possible problems, you should start
spamd with the -D option, which will keep spamd in the foreground, and will
output debug message to the terminal. You should then test spamd with a
message by calling spamc.  You can use the sample-spam.txt file with the
following command:

  cat sample-spam.txt | spamc

Watch the debug output from spamd and look for the following debug line:

  retrieving LDAP prefs for <username>: <value>

If you do not see the above text, then the LDAP query was not successful, and
you should see any error messages reported. <username> should be the user
that was passed to spamd and is usually the user executing spamc.

To test LDAP support using the SpamAssassin test suite, you need to
perform a little bit of manual configuration first.  See the file
"ldap/README.testing" for details.


lib/Mail/SpamAssassin.pm  view on Meta::CPAN

  '__local_rules_dir__',
  '__prefix__/etc/mail/spamassassin',
  '__prefix__/etc/spamassassin',
  '/usr/local/etc/spamassassin',
  '/usr/pkg/etc/spamassassin',
  '/usr/etc/spamassassin',
  '/etc/mail/spamassassin',
  '/etc/spamassassin',
);

our @default_prefs_path = (
  '__local_rules_dir__/user_prefs.template',
  '__prefix__/etc/mail/spamassassin/user_prefs.template',
  '__prefix__/share/spamassassin/user_prefs.template',
  '__local_state_dir__/__version__/updates_spamassassin_org/user_prefs.template',
  '__def_rules_dir__/user_prefs.template',
  '/etc/spamassassin/user_prefs.template',
  '/etc/mail/spamassassin/user_prefs.template',
  '/usr/local/share/spamassassin/user_prefs.template',
  '/usr/share/spamassassin/user_prefs.template',
);

our @default_userprefs_path = (
  '~/.spamassassin/user_prefs',
);

our @default_userstate_dir = (
  '~/.spamassassin',
);

###########################################################################

=item $t = Mail::SpamAssassin-E<gt>new( { opt =E<gt> val, ... } )

lib/Mail/SpamAssassin.pm  view on Meta::CPAN


=item rules_filename

The filename/directory to load spam-identifying rules from. (optional)

=item site_rules_filename

The filename/directory to load site-specific spam-identifying rules from.
(optional)

=item userprefs_filename

The filename to load preferences from. (optional)

=item userstate_dir

The directory user state is stored in. (optional)

=item config_tree_recurse

Set to C<1> to recurse through directories when reading configuration
files, instead of just reading a single level.  (optional, default 0)

=item config_text

The text of all rules and preferences.  If you prefer not to load the rules
from files, read them in yourself and set this instead.  As a result, this will
override the settings for C<rules_filename>, C<site_rules_filename>,
and C<userprefs_filename>.

=item pre_config_text

Similar to C<config_text>, this text is placed before config_text to allow an
override of config files.

=item post_config_text

Similar to C<config_text>, this text is placed after config_text to allow an
override of config files.

lib/Mail/SpamAssassin.pm  view on Meta::CPAN


=item require_rules

If set to 1, init() will die if no valid rules could be loaded. This is the
default behaviour when called by C<spamassassin> or C<spamd>.

=item languages_filename

If you want to be able to use the language-guessing rule
C<UNWANTED_LANGUAGE_BODY>, and are using C<config_text> instead of
C<rules_filename>, C<site_rules_filename>, and C<userprefs_filename>, you will
need to set this.  It should be the path to the B<languages> file normally
found in the SpamAssassin B<rules> directory.

=item local_tests_only

If set to 1, no tests that require internet access will be performed. (default:
0)

=item need_tags

lib/Mail/SpamAssassin.pm  view on Meta::CPAN

  need_tags =E<gt>    'TIMING,noLANGUAGES,RELAYCOUNTRY,ASN,noASNCIDR',
or:
  need_tags =E<gt> [qw(TIMING noLANGUAGES RELAYCOUNTRY ASN noASNCIDR)],

=item ignore_site_cf_files

If set to 1, any rule files found in the C<site_rules_filename> directory will
be ignored.  *.pre files (used for loading plugins) found in the
C<site_rules_filename> directory will still be used. (default: 0)

=item dont_copy_prefs

If set to 1, the user preferences file will not be created if it doesn't
already exist. (default: 0)

=item save_pattern_hits

If set to 1, the patterns hit can be retrieved from the
C<Mail::SpamAssassin::PerMsgStatus> object.  Used for debugging.

=item home_dir_for_helpers

lib/Mail/SpamAssassin.pm  view on Meta::CPAN


This option should only be set by a caller if it calls srand() upon spawning
child processes.  Unless you are certain you need it, leave this setting as
false.

NOTE: The skip_prng_reseeding feature is implemented in spamd as of 3.4.0
which allows spamd to call srand() right after forking a child process.

=back

If none of C<rules_filename>, C<site_rules_filename>, C<userprefs_filename>, or
C<config_text> is set, the C<Mail::SpamAssassin> module will search for the
configuration files in the usual installed locations using the below variable
definitions which can be passed in.

=over 4

=item PREFIX

Used as the root for certain directory paths such as:

lib/Mail/SpamAssassin.pm  view on Meta::CPAN


=cut

sub set_persistent_address_list_factory {
  my ($self, $fac) = @_;
  $self->{pers_addr_list_factory} = $fac;
}

###########################################################################

=item $f-E<gt>compile_now ($use_user_prefs, $keep_userstate)

Compile all patterns, load all configuration files, and load all
possibly-required Perl modules.

Normally, Mail::SpamAssassin uses lazy evaluation where possible, but if you
plan to fork() or start a new perl interpreter thread to process a message,
this is suboptimal, as each process/thread will have to perform these actions.

Call this function in the master thread or process to perform the actions
straight away, so that the sub-processes will not have to.

If C<$use_user_prefs> is 0, this will initialise the SpamAssassin
configuration without reading the per-user configuration file and it will
assume that you will call C<read_scoreonly_config> at a later point.

If C<$keep_userstate> is true, compile_now() will revert any configuration
options which have a default with I<__userstate__> in it post-init(),
and then re-change the option before returning.  This lets you change
I<$ENV{'HOME'}> to a temp directory, have compile_now() and create any
files there as necessary without disturbing the actual files as changed
by a configuration option.  By default, this is disabled.

=cut

sub compile_now {
  my ($self, $use_user_prefs, $deal_with_userstate) = @_;

  my $timer = $self->time_method("compile_now");

  # Backup default values which deal with userstate.
  # This is done so we can create any new files in, presumably, a temp dir.
  # see bug 2762 for more details.
  my %backup;
  if (defined $deal_with_userstate && $deal_with_userstate) {
    while(my($k,$v) = each %{$self->{conf}}) {
      $backup{$k} = $v if (defined $v && !ref($v) && $v =~/__userstate__/);
    }
  }

  $self->init($use_user_prefs);

  # if init() didn't change the value from default, forget about it.
  # if the value is different, remember the new version, and reset the default.
  while(my($k,$v) = each %backup) {
    if ($self->{conf}->{$k} eq $v) {
      delete $backup{$k};
    }
    else {
      my $backup = $backup{$k};
      $backup{$k} = $self->{conf}->{$k};
      $self->{conf}->{$k} = $backup;
    }
  }

  dbg("ignore: test message to precompile patterns and load modules");

  # tell plugins we are about to send a message for compiling purposes
  $self->call_plugins("compile_now_start",
		      { use_user_prefs => $use_user_prefs,
			keep_userstate => $deal_with_userstate});

  # note: this may incur network access. Good.  We want to make sure
  # as much as possible is preloaded!
  my @testmsg = ("From: ignore\@compiling.spamassassin.taint.org\n", 
    "Message-Id:  <".time."\@spamassassin_spamd_init>\n", "\n",
    "I need to make this message body somewhat long so TextCat preloads\n"x20);

  my $mail = $self->parse(\@testmsg, 1, { master_deadline => undef });
  my $status = Mail::SpamAssassin::PerMsgStatus->new($self, $mail,

lib/Mail/SpamAssassin.pm  view on Meta::CPAN

    if ($dsn =~ /^ldap:/i) {
      Mail::SpamAssassin::Conf::LDAP::load_modules();
    } else {
      Mail::SpamAssassin::Conf::SQL::load_modules();
    }
  }

  # make sure things are ready for scanning
  $self->{bayes_scanner}->force_close() if $self->{bayes_scanner};
  $self->call_plugins("compile_now_finish",
		      { use_user_prefs => $use_user_prefs,
			keep_userstate => $deal_with_userstate});

  # Reset any non-default values to the post-init() version.
  while(my($k,$v) = each %backup) {
    $self->{conf}->{$k} = $v;
  }

  # clear sed_path_cache
  delete $self->{conf}->{sed_path_cache};

lib/Mail/SpamAssassin.pm  view on Meta::CPAN


  dbg("ignore: using a test message to lint rules");
  my @testmsg = ("From: ignore\@compiling.spamassassin.taint.org\n", 
    "Subject: \n",
    "Message-Id:  <".CORE::time()."\@lint_rules>\n", "\n",
    "I need to make this message body somewhat long so TextCat preloads\n"x20);

  $self->{lint_rules} = $self->{conf}->{lint_rules} = 1;
  $self->{syntax_errors} = 0;

  my $olddcp = $self->{dont_copy_prefs};
  $self->{dont_copy_prefs} = 1;

  $self->init(1);
  $self->{syntax_errors} += $self->{conf}->{errors};

  $self->{dont_copy_prefs} = $olddcp;       # revert back to previous

  # bug 5048: override settings to ensure a faster lint
  $self->{'conf'}->{'use_auto_welcomelist'} = 0;
  $self->{'conf'}->{'bayes_auto_learn'} = 0;

  my $mail = $self->parse(\@testmsg, 1, { master_deadline => undef });
  my $status = Mail::SpamAssassin::PerMsgStatus->new($self, $mail,
                        { disable_auto_learning => 1 } );
  $status->check();

lib/Mail/SpamAssassin.pm  view on Meta::CPAN


  my $timer = $self->time_method("init");
  # Note that this PID has run init()
  $self->{_initted} = $$;

  # if spamd or other forking, wait for spamd_child_init
  if (!$self->{skip_prng_reseeding}) {
    $self->set_global_state_dir();
  }

  #fix spamd reading root prefs file
  if (!defined $use_user_pref) {
    $use_user_pref = 1;
  }

  if (!defined $self->{config_text}) {
    $self->{config_text} = '';

    # read a file called "init.pre" in site rules dir *before* all others;
    # even the system config.
    my $siterules = $self->{site_rules_filename};

lib/Mail/SpamAssassin.pm  view on Meta::CPAN

      $self->{languages_filename} = $self->find_rule_support_file("languages");
    }

    if ($siterules && !$self->{ignore_site_cf_files}) {
      $self->{config_text} .= $self->read_cf($siterules, 'site rules dir');
    }

    if ( $use_user_pref != 0 ) {
      $self->get_and_create_userstate_dir();

      # user prefs file
      my $fname = $self->{userprefs_filename};
      $fname ||= $self->first_existing_path (@default_userprefs_path);

      if (!$self->{dont_copy_prefs}) {
        # bug 4932: if the userprefs path doesn't exist, we need to make it, so
        # just use the last entry in the array as the default path.
        $fname ||= $self->sed_path($default_userprefs_path[-1]);

        my $stat_errn = stat($fname) ? 0 : 0+$!;
        if ($stat_errn == 0 && -f _) {
          # exists and is a regular file, nothing to do
        } elsif ($stat_errn == 0) {
          warn "config: default user preference file $fname is not a regular file\n";
        } elsif ($stat_errn != ENOENT) {
          warn "config: default user preference file $fname not accessible: $!\n";
        } elsif (!$self->create_default_prefs($fname)) {
          warn "config: failed to create default user preference file $fname\n";
        }
      }

      $self->{config_text} .= $self->read_cf($fname, 'user prefs file');
    }
  }

  if ($self->{pre_config_text}) {
    $self->{pre_config_text} .= "\n" unless $self->{pre_config_text} =~ /\n\z/;
    $self->{config_text} = "file start (pre_config_text)\n".
                           $self->{pre_config_text}.
                           "file end (pre_config_text)\n".
                           $self->{config_text};
  }

lib/Mail/SpamAssassin.pm  view on Meta::CPAN

  elsif (defined $self->{user_dir}) {
    $fname = File::Spec->catdir ($self->{user_dir}, ".spamassassin");
  }

  $fname ||= $self->first_existing_path (@default_userstate_dir);

  # bug 4932: use the last default_userstate_dir entry if none of the others
  # already exist
  $fname ||= $self->sed_path($default_userstate_dir[-1]);

  if (!$self->{dont_copy_prefs}) {
    dbg("config: using \"$fname\" for user state dir");
  }

  # if this is not a dir, not readable, or we are unable to create the dir,
  # this is not (yet) a serious error; in fact, it's not even worth
  # a warning at all times, so use dbg().  see bug 6268
  my $stat_errn = stat($fname) ? 0 : 0+$!;
  if ($stat_errn == 0 && !-d _) {
    dbg("config: $fname exists but is not a directory");
  } elsif ($stat_errn != 0 && $stat_errn != ENOENT) {

lib/Mail/SpamAssassin.pm  view on Meta::CPAN

    push @paths, $self->{rules_filename}
  }
  # updates sub-directory missing from @default_rules_path
  push @paths, '__local_state_dir__/__version__/updates_spamassassin_org';
  push @paths, @default_rules_path;

  return $self->first_existing_path(
    map { my $p = $_; $p =~ s{$}{/$filename}; $p } @paths );
}

=item $f-E<gt>create_default_prefs ($filename, $username [ , $userdir ] )

Copy default preferences file into home directory for later use and
modification, if it does not already exist and C<dont_copy_prefs> is
not set.

=cut

sub create_default_prefs {
  # $userdir will only exist if vpopmail config is enabled thru spamd
  # Its value will be the virtual user's maildir
  #
  my ($self, $fname, $user, $userdir) = @_;

  if ($self->{dont_copy_prefs}) {
    return(0);
  }

#  if ($userdir && $userdir ne $self->{user_dir}) {
#    warn "config: hooray! user_dirs don't match! '$userdir' vs '$self->{user_dir}'\n";
#  }

  my $stat_errn = stat($fname) ? 0 : 0+$!;
  if ($stat_errn == 0) {
    # fine, it already exists
  } elsif ($stat_errn != ENOENT) {
    dbg("config: cannot access user preferences file $fname: $!");
  } else {
    # Pass on the value of $userdir for virtual users in vpopmail
    # otherwise it is empty and the user's normal homedir is used
    $self->get_and_create_userstate_dir($userdir);

    # copy in the default one for later editing
    my $defprefs =
      $self->first_existing_path(@Mail::SpamAssassin::default_prefs_path);

    local(*IN,*OUT);
    $fname = Mail::SpamAssassin::Util::untaint_file_path($fname);
    if (!defined $defprefs) {
      warn "config: can not determine default prefs path\n";
    } elsif (!open(IN, "<$defprefs")) {
      warn "config: cannot open $defprefs: $!\n";
    } elsif (!open(OUT, ">$fname")) {
      warn "config: cannot create user preferences file $fname: $!\n";
    } else {
      # former code skipped lines beginning with '#* ', the following copy
      # procedure no longer does so, as it avoids reading line-by-line
      my($inbuf,$nread);
      while ( $nread=read(IN,$inbuf,16384) ) {
        print OUT $inbuf  or die "cannot write to $fname: $!";
      }
      defined $nread  or die "error reading $defprefs: $!";
      undef $inbuf;
      close OUT or die "error closing $fname: $!";
      close IN  or die "error closing $defprefs: $!";

      if (($< == 0) && ($> == 0) && defined($user)) { # chown it
        my ($uid,$gid) = (getpwnam(untaint_var($user)))[2,3];
        unless (chown($uid, $gid, $fname)) {
          warn "config: couldn't chown $fname to $uid:$gid for $user: $!\n";
        }
      }
      warn "config: created user preferences file: $fname\n";
      return(1);
    }

lib/Mail/SpamAssassin/Conf.pm  view on Meta::CPAN

C<~user/> are supported.

Where appropriate below, default values are listed in parentheses.

Test names ("SYMBOLIC_TEST_NAME") can only contain alphanumerics/underscores,
can not start with digit, and must be less than 128 characters.

=head1 USER PREFERENCES

The following options can be used in both site-wide (C<local.cf>) and
user-specific (C<user_prefs>) configuration files to customize how
SpamAssassin handles incoming email messages.

=cut

package Mail::SpamAssassin::Conf;

use strict;
use warnings;
# use bytes;
use re 'taint';

lib/Mail/SpamAssassin/Conf.pm  view on Meta::CPAN

    aliases => ['whitelist_from'], # backward compatible - to be removed for 4.1
    type => $CONF_TYPE_ADDRLIST,
  });

=item unwelcomelist_from user@example.com

Previously unwelcomelist_from which will work interchangeably until 4.1.

Used to remove a default welcomelist_from entry, so for example a distribution
welcomelist_from can be overridden in a local.cf file, or an individual user can
override a welcomelist_from entry in their own C<user_prefs> file.
The specified email address has to match exactly (although case-insensitively)
the address previously used in a welcomelist_from line, which implies that a
wildcard only matches literally the same wildcard (not 'any' address).

e.g.

  unwelcomelist_from joe@example.com fred@example.com
  unwelcomelist_from *@example.com

=cut

lib/Mail/SpamAssassin/Conf.pm  view on Meta::CPAN

    type => $CONF_TYPE_ADDRLIST,
  });

=item unwelcomelist_from_rcvd user@example.com

Previously unwhitelist_from_rcvd which will work interchangeably until 4.1.

Used to remove a default welcomelist_from_rcvd or def_welcomelist_from_rcvd
entry, so for example a distribution welcomelist_from_rcvd can be overridden
in a local.cf file, or an individual user can override a welcomelist_from_rcvd
entry in their own C<user_prefs> file.

The specified email address has to match exactly the address previously
used in a welcomelist_from_rcvd line.

e.g.

  unwelcomelist_from_rcvd joe@example.com fred@example.com
  unwelcomelist_from_rcvd *@axkit.org

=cut

lib/Mail/SpamAssassin/Conf.pm  view on Meta::CPAN

    type => $CONF_TYPE_ADDRLIST,
  });

=item unblocklist_from user@example.com

Previously unblacklist_from which will work interchangeably until 4.1.

Used to remove a default blocklist_from entry, so for example a
distribution blocklist_from can be overridden in a local.cf file, or
an individual user can override a blocklist_from entry in their own
C<user_prefs> file. The specified email address has to match exactly
the address previously used in a blocklist_from line.


e.g.

  unblocklist_from joe@example.com fred@example.com
  unblocklist_from *@spammer.com

=cut

lib/Mail/SpamAssassin/Conf.pm  view on Meta::CPAN


  push (@cmds, {
    setting => 'report_charset',
    default => 'UTF-8',
    type => $CONF_TYPE_STRING,
  });

=item report ...some text for a report...

Set the report template which is attached to spam mail messages.  See the
C<10_default_prefs.cf> configuration file in C</usr/share/spamassassin> for an
example.

If you change this, try to keep it under 78 columns. Each C<report>
line appends to the existing template, so use C<clear_report_template>
to restart.

Tags can be included as explained above.

=cut

lib/Mail/SpamAssassin/Conf.pm  view on Meta::CPAN


  push (@cmds, {
    setting => 'report_hostname',
    default => '',
    type => $CONF_TYPE_STRING,
  });

=item unsafe_report ...some text for a report...

Set the report template which is attached to spam mail messages which contain a
non-text/plain part.  See the C<10_default_prefs.cf> configuration file in
C</usr/share/spamassassin> for an example.

Each C<unsafe-report> line appends to the existing template, so use
C<clear_unsafe_report_template> to restart.

Tags can be used in this template (see above for details).

=cut

  push (@cmds, {

lib/Mail/SpamAssassin/Conf.pm  view on Meta::CPAN

    type => $CONF_TYPE_BOOL,
  });

=back

=head1 RULE DEFINITIONS AND PRIVILEGED SETTINGS

These settings differ from the ones above, in that they are considered
'privileged'.  Only users running C<spamassassin> from their procmailrc's or
forward files, or sysadmins editing a file in C</etc/mail/spamassassin>, can
use them.   C<spamd> users cannot use them in their C<user_prefs> files, for
security and efficiency reasons, unless C<allow_user_rules> is enabled (and
then, they may only add rules from below).

=over 4

=item allow_user_rules ( 0 | 1 )		(default: 0)

This setting allows users to create rules (and only rules) in their
C<user_prefs> files for use with C<spamd>. It defaults to off, because
this could be a severe security hole. It may be possible for users to
gain root level access if C<spamd> is run as root. It is NOT a good
idea, unless you have some other way of ensuring that users' tests are
safe. Don't use this unless you are certain you know what you are
doing. Furthermore, this option causes spamassassin to recompile all
the tests each time it processes a message for a user with a rule in
his/her C<user_prefs> file, which could have a significant effect on
server load. It is not recommended.

Note that it is not currently possible to use C<allow_user_rules> to modify an
existing system rule from a C<user_prefs> file with C<spamd>.

=cut

  push (@cmds, {
    setting => 'allow_user_rules',
    is_priv => 1,
    default => 0,
    type => $CONF_TYPE_BOOL,
    code => sub {
      my ($self, $key, $value, $line) = @_;

lib/Mail/SpamAssassin/Conf.pm  view on Meta::CPAN

set to priority -10000, so that the tags should always be ready for any
normal rules to use.  When rule depends on a tag that might be set at later
stage by a plugin for example, it's priority should be set manually to a
higher value.

=head1 ADMINISTRATOR SETTINGS

These settings differ from the ones above, in that they are considered 'more
privileged' -- even more than the ones in the B<PRIVILEGED SETTINGS> section.
No matter what C<allow_user_rules> is set to, these can never be set from a
user's C<user_prefs> file when spamc/spamd is being used.  However, all
settings can be used by local programs run directly by the user.

=over 4

=item version_tag string

This tag is appended to the SA version in the X-Spam-Status header. You should
include it when you modify your ruleset, especially if you plan to distribute it.
A good choice for I<string> is your last name or your initials followed by a
number which you increase with each change.

lib/Mail/SpamAssassin/Conf.pm  view on Meta::CPAN

=over 4

=item Current default query:

C<SELECT preference, value FROM _TABLE_ WHERE username = _USERNAME_ OR username = '@GLOBAL' ORDER BY username ASC>

=item Use global and then domain level defaults:

C<SELECT preference, value FROM _TABLE_ WHERE username = _USERNAME_ OR username = '@GLOBAL' OR username = '@~'||_DOMAIN_ ORDER BY username ASC>

=item Maybe global prefs should override user prefs:

C<SELECT preference, value FROM _TABLE_ WHERE username = _USERNAME_ OR username = '@GLOBAL' ORDER BY username DESC>

=back

=cut

  push (@cmds, {
    setting => 'user_scores_sql_custom_query',
    is_admin => 1,

lib/Mail/SpamAssassin/Conf.pm  view on Meta::CPAN


  push (@cmds, {
    setting => 'user_scores_ldap_password',
    is_admin => 1,
    default => '',
    type => $CONF_TYPE_STRING,
  });

=item user_scores_fallback_to_global        (default: 1)

Fall back to global scores and settings if userprefs can't be loaded
from SQL or LDAP, instead of passing the message through unprocessed.

=cut

  push (@cmds, {
    setting => 'user_scores_fallback_to_global',
    is_admin => 1,
    default => 1,
    type => $CONF_TYPE_BOOL,
  });

lib/Mail/SpamAssassin/Conf.pm  view on Meta::CPAN

  # NOTE: Deprecated usage of TieOneStringHash as of 10/2018, it's an
  # absolute pig, doubling config parsing time, while benchmarks indicate
  # no difference in resident memory size!
  $self->{descriptions} = { };
  #tie %{$self->{descriptions}}, 'Mail::SpamAssassin::Util::TieOneStringHash'
  #  or warn "tie failed";
  $self->{subjprefix} = { };

  # after parsing, tests are refiled into these hashes for each test type.
  # this allows e.g. a full-text test to be rewritten as a body test in
  # the user's user_prefs file.
  $self->{body_tests} = { };
  $self->{uri_tests}  = { };
  $self->{uri_evals}  = { }; # not used/implemented yet
  $self->{head_tests} = { };
  $self->{head_evals} = { };
  $self->{body_evals} = { };
  $self->{full_tests} = { };
  $self->{full_evals} = { };
  $self->{rawbody_tests} = { };
  $self->{rawbody_evals} = { };

lib/Mail/SpamAssassin/Conf/LDAP.pm  view on Meta::CPAN

  my $result = $ldap->search( base => $base,
			      filter => $filter,
			      scope => $scope,
			      attrs => \@attr
                            );

  my $config_text = '';
  foreach my $entry ($result->all_entries) {
    my @v = $entry->get_value($f_attribute);
    foreach my $v (@v) {
      dbg("ldap: retrieving prefs for $username: $v");
      $config_text .= $v."\n";
    }
  }
  if ($config_text ne '') {
    $conf->{main} = $main;
    $config_text = "file start (ldap config)\n".
                   $config_text.
                   "file end (ldap config)\n";
    $conf->parse_scores_only($config_text);
    delete $conf->{main};

lib/Mail/SpamAssassin/Conf/Parser.pm  view on Meta::CPAN

}

# functions supported in the "if" eval:
sub cond_clause_plugin_loaded {
  return 1 if $_[1] eq 'Mail::SpamAssassin::Plugin::RaciallyCharged'; # removed in 4.1
  return $_[0]->{conf}->{plugins_loaded}->{$_[1]};
}

sub cond_clause_can {
  my ($self, $method) = @_;
  if ($self->{currentfile} =~ q!\buser_prefs$! ) {
    warn "config: 'if can $method' not available in user_prefs";
    return 0
  }
  $self->cond_clause_can_or_has('can', $method);
}

sub cond_clause_has {
  my ($self, $method) = @_;
  $self->cond_clause_can_or_has('has', $method);
}

lib/Mail/SpamAssassin/Conf/Parser.pm  view on Meta::CPAN

    # keep_config_parsing_metadata is set (ruleqa stuff)
    $conf->{source_file}->{$name} = $self->{currentfile};

    $conf->{if_stack}->{$name} = $self->get_if_stack_as_string();

    if ($self->{file_scoped_attrs}->{testrules}) {
      $conf->{testrules}->{$name} = 1;   # used in build/mkupdates/listpromotable
    }
  }

  # if we found this rule in a user_prefs file, it's a user rule -- note that
  # we may need to recompile the rule code for this type (if they've already
  # been compiled, e.g. in spamd).
  #
  # Note: the want_rebuild_for_type 'flag' is actually a counter; it is decremented
  # after each scan.  This ensures that we always recompile at least once more;
  # once to *define* the rule, and once afterwards to *undefine* the rule in the
  # compiled ruleset again.
  #
  # If two consecutive scans use user rules, that's ok -- the second one will
  # reset the counter, and we'll still recompile just once afterwards to undefine

lib/Mail/SpamAssassin/Conf/SQL.pm  view on Meta::CPAN

     else {
       $sql = "select $f_preference, $f_value  from $f_table where ". 
        "$f_username = ".$dbh->quote($username).
        " or $f_username = '\@GLOBAL' order by $f_username asc";
     }
     dbg("config: Conf::SQL: executing SQL: $sql");
     my $sth = $dbh->prepare($sql);
     if ($sth) {
       my $rv  = $sth->execute();
       if ($rv) {
	 dbg("config: retrieving prefs for $username from SQL server");
	 my @row;
	 my $config_text = '';
	 while (@row = $sth->fetchrow_array()) {
	   $config_text .= (defined($row[0]) ? $row[0] : '') . "\t" .
	       (defined($row[1]) ? $row[1] : '')  . "\n";
	 }
	 if ($config_text ne '') {
	   $conf->{main} = $main;
	   $config_text = "file start (sql config)\n".
	                  $config_text.

lib/Mail/SpamAssassin/PerMsgLearner.pm  view on Meta::CPAN

# </@LICENSE>

=head1 NAME

Mail::SpamAssassin::PerMsgLearner - per-message status (spam or not-spam)

=head1 SYNOPSIS

  my $spamtest = Mail::SpamAssassin->new({
    'rules_filename'      => '/etc/spamassassin.rules',
    'userprefs_filename'  => $ENV{HOME}.'/.spamassassin/user_prefs'
  });
  my $mail = $spamtest->parse();

  my $status = $spamtest->learn($mail,$id,$isspam,$forget);
  my $didlearn = $status->did_learn();
  $status->finish();


=head1 DESCRIPTION

lib/Mail/SpamAssassin/PerMsgStatus.pm  view on Meta::CPAN

# </@LICENSE>

=head1 NAME

Mail::SpamAssassin::PerMsgStatus - per-message status (spam or not-spam)

=head1 SYNOPSIS

  my $spamtest = Mail::SpamAssassin->new({
    'rules_filename'      => '/etc/spamassassin.rules',
    'userprefs_filename'  => $ENV{HOME}.'/.spamassassin/user_prefs'
  });
  my $mail = $spamtest->parse();

  my $status = $spamtest->check ($mail);

  my $rewritten_mail;
  if ($status->is_spam()) {
    $rewritten_mail = $status->rewrite_mail ();
  }
  ...

lib/Mail/SpamAssassin/Plugin.pm  view on Meta::CPAN

=back

=item $plugin-E<gt>compile_now_start ( { options ... } )

This is called at the beginning of Mail::SpamAssassin::compile_now() so
plugins can do any necessary initialization for multi-process
SpamAssassin (such as spamd or mass-check -j).

=over 4

=item use_user_prefs

The value of $use_user_prefs option in compile_now().

=item keep_userstate

The value of $keep_userstate option in compile_now().

=back

=item $plugin-E<gt>compile_now_finish ( { options ... } )

This is called at the end of Mail::SpamAssassin::compile_now() so
plugins can do any necessary initialization for multi-process
SpamAssassin (such as spamd or mass-check -j).

=over 4

=item use_user_prefs

The value of $use_user_prefs option in compile_now().

=item keep_userstate

The value of $keep_userstate option in compile_now().

=back

=item $plugin-E<gt>check_start ( { options ... } )

Signals that a message check operation is starting.

lib/Mail/SpamAssassin/Plugin/AWL.pm  view on Meta::CPAN

  return $self;
}

sub set_config {
  my($self, $conf) = @_;
  my @cmds;

=head1 USER PREFERENCES

The following options can be used in both site-wide (C<local.cf>) and
user-specific (C<user_prefs>) configuration files to customize how
SpamAssassin handles incoming email messages.

=over 4

=item use_auto_welcomelist ( 0 | 1 )		(default: 1)

Previously use_auto_whitelist which will work interchangeably until 4.1.

Whether to use auto-welcomelists.  Auto-welcomelists track the long-term
average score for each sender and then shift the score of new messages

lib/Mail/SpamAssassin/Plugin/AWL.pm  view on Meta::CPAN

		type => $Mail::SpamAssassin::Conf::CONF_TYPE_BOOL
	       });

=back

=head1 ADMINISTRATOR SETTINGS

These settings differ from the ones above, in that they are considered 'more
privileged' -- even more than the ones in the B<PRIVILEGED SETTINGS> section.
No matter what C<allow_user_rules> is set to, these can never be set from a
user's C<user_prefs> file.

=over 4

=item auto_welcomelist_factory module (default: Mail::SpamAssassin::DBBasedAddrList)

Previously auto_whitelist_factory which will work interchangeably until 4.1.

Select alternative welcomelist factory module.

=cut

lib/Mail/SpamAssassin/Plugin/DKIM.pm  view on Meta::CPAN

Removes an email address with its corresponding signing-domain field
from def_welcomelist_from_dkim and welcomelist_from_dkim tables, if it exists.
Parameters to unwelcomelist_from_dkim must exactly match the parameters of
a corresponding welcomelist_from_dkim or def_welcomelist_from_dkim config
option which created the entry, for it to be removed (a domain name is
matched case-insensitively);  i.e. if a signing-domain parameter was
specified in a welcomelisting command, it must also be specified in the
unwelcomelisting command.

Useful for removing undesired default entries from a distributed configuration
by a local or site-specific configuration or by C<user_prefs>.

=item adsp_override domain [signing-practices]

Currently few domains publish their signing practices (RFC 5617 - ADSP),
partly because the ADSP rfc is rather new, partly because they think
hardly any recipient bothers to check it, and partly for fear that some
recipients might lose mail due to problems in their signature validation
procedures or mail mangling by mailers beyond their control.

Nevertheless, recipients could benefit by knowing signing practices of a

lib/Mail/SpamAssassin/Plugin/DNSEval.pm  view on Meta::CPAN

  foreach(@{$self->{'evalrules'}}) {
    $self->register_eval_rule($_, $Mail::SpamAssassin::Conf::TYPE_RBL_EVALS);
  }

  return $self;
}

=head1 USER PREFERENCES

The following options can be used in both site-wide (C<local.cf>) and
user-specific (C<user_prefs>) configuration files to customize how
SpamAssassin handles incoming email messages.

=over

=item rbl_headers

 This option tells SpamAssassin in which headers to check for content
 used to query the specified rbl.
 If on the headers content there is an email address, an ip address
 or a domain name, it will be checked on the specified rbl.

lib/Mail/SpamAssassin/Plugin/ExtractText.pm  view on Meta::CPAN


This module uses external tools to extract text from message parts,
and then sets the text as the rendered part. External tool must output
plain text, not HTML or other non-textual result.

How to extract text is completely configurable, and based on
MIME part type and file name.

=head1 CONFIGURATION

All configuration lines in user_prefs files will be ignored.

=over 4

=item extracttext_maxparts (default: 10)

Configure the maximum mime parts number to analyze, a value of 0 means all mime parts
will be analyzed

=item extracttext_timeout (default: 5 10)

lib/Mail/SpamAssassin/Plugin/OLEVBMacro.pm  view on Meta::CPAN

attached to emails.  It can detect documents inside zip files as well as
encrypted documents.

=head1 REQUIREMENT

This plugin requires Archive::Zip and IO::String perl modules.

=head1 USER PREFERENCES

The following options can be used in both site-wide (C<local.cf>) and
user-specific (C<user_prefs>) configuration files to customize how
the module handles attached documents

=cut

package Mail::SpamAssassin::Plugin::OLEVBMacro;
use strict;
use warnings;

use Mail::SpamAssassin::Plugin;
use Mail::SpamAssassin::Util qw(compile_regexp get_part_details);

lib/Mail/SpamAssassin/Plugin/SPF.pm  view on Meta::CPAN

these are often targets for spammer spoofing.

=item unwelcomelist_from_spf user@example.com

Previously unwhitelist_from_spf which will work interchangeably until 4.1.

Used to remove a C<welcomelist_from_spf> or C<def_welcomelist_from_spf> entry. 
The specified email address has to match exactly the address previously used.

Useful for removing undesired default entries from a distributed configuration
by a local or site-specific configuration or by C<user_prefs>.

=cut

  push (@cmds, {
    setting => 'welcomelist_from_spf',
    aliases => ['whitelist_from_spf'], # removed in 4.1
    type => $Mail::SpamAssassin::Conf::CONF_TYPE_ADDRLIST
  });

  push (@cmds, {

lib/Mail/SpamAssassin/Plugin/TxRep.pm  view on Meta::CPAN

###########################################################################
sub set_config {
###########################################################################
  my($self, $conf) = @_;
  my @cmds;

# -------------------------------------------------------------------------
=head1 USER PREFERENCES

The following options can be used in both site-wide (C<local.cf>) and
user-specific (C<user_prefs>) configuration files to customize how
SpamAssassin handles incoming email messages.

=over 4

=item B<use_txrep>

  0 | 1                 (default: 0)

Whether to use TxRep reputation system.  TxRep tracks the long-term average
score for each sender and then shifts the score of new messages toward that

lib/Mail/SpamAssassin/Plugin/TxRep.pm  view on Meta::CPAN

    }
  });

=back

=head1 ADMINISTRATOR SETTINGS

These settings differ from the ones above, in that they are considered 'more
privileged' -- even more than the ones in the B<PRIVILEGED SETTINGS> section.
No matter what C<allow_user_rules> is set to, these can never be set from a
user's C<user_prefs> file.

=over 4

=item B<txrep_factory module>

 (default: Mail::SpamAssassin::DBBasedAddrList)

Select alternative database factory module for the TxRep database.

=cut

lib/Mail/SpamAssassin/Plugin/TxRep.pm  view on Meta::CPAN

sub has_txrep_min_score { 1 }
sub has_txrep_max_score { 1 }

=head1 OPTIMIZING TXREP

TxRep can be optimized for speed and simplicity, or for the precision in
assigning the reputation scores.

First of all TxRep can be quickly disabled and re-enabled through the option
L</C<use_txrep>>. It can be done globally, or individually in each respective
C<user_prefs>. Disabling TxRep will not destroy the database, so it can be
re-enabled any time later again.

On many systems, SQL-based storage may perform faster than the default
Berkeley DB storage, so you should consider setting it up.

Then there are multiple settings that can reduce the number of records stored
in the database, hence reducing the size of the storage, and also the processing
time:

1. Setting L</C<txrep_user2global_ratio>> to zero will disable the dual storage,

lib/Mail/SpamAssassin/Plugin/VBounce.pm  view on Meta::CPAN

  return $self;
}

sub set_config {
  my($self, $conf) = @_;
  my @cmds;

=head1 USER PREFERENCES

The following options can be used in both site-wide (C<local.cf>) and
user-specific (C<user_prefs>) configuration files to customize how
SpamAssassin handles incoming email messages.

=over 4

=item welcomelist_bounce_relays hostname [hostname2 ...]

Previously whitelist_bounce_relays which will work interchangeably until 4.1.

This is used to 'rescue' legitimate bounce messages that were generated in
response to mail you really *did* send. List the MTA relay hostnames that

lib/spamassassin-run.pod  view on Meta::CPAN

B<spamassassin> B<-W>|B<-R> [ < I<mailmessage> | I<path> ... ]

Options:

 -L, --local                       Local tests only (no online tests)
 -r, --report                      Report message as spam
 -k, --revoke                      Revoke message as spam
 -d, --remove-markup               Remove spam reports from a message
 -C path, --configpath=path, --config-file=path
                                   Path to standard configuration dir
 -p prefs, --prefspath=file, --prefs-file=file
                                   Set user preferences file
 --siteconfigpath=path             Path for site configs
                                   (def: /etc/mail/spamassassin)
 --cf='config line'                Additional line of configuration
 --pre='config line'               Additional line of ".pre" (prepended to configuration)
 -x, --nocreate-prefs              Don't create user preferences file
 -e, --exit-code                   Exit with a non-zero exit code if the
                                   tested message was spam
 --mbox                            read in messages in mbox format
 --mbx                             read in messages in UW mbx format
 -t, --test-mode                   Pipe message through and add extra
                                   report to the bottom
 --lint                            Lint the rule set: report syntax errors
 -W, --add-to-welcomelist          Add addresses in mail to persistent address welcomelist
 --add-to-blocklist                Add addresses in mail to persistent address blocklist
 -R, --remove-from-welcomelist     Remove all addresses found in mail from

lib/spamassassin-run.pod  view on Meta::CPAN


=item B<--pre='config line'>

Add additional lines of .pre configuration directly from the command-line,
parsed before the configuration files are read.  Multiple B<--pre> arguments
can be used, and each will be considered a separate line of configuration. 
For example:

        spamassassin -t --pre="loadplugin Mail::SpamAssassin::Plugin::Foobar"

=item B<-p> I<prefs>, B<--prefspath>=I<prefs>, B<--prefs-file>=I<prefs>

Read user score preferences from I<prefs> (usually C<$HOME/.spamassassin/user_prefs>).

=item B<--progress>

Prints a progress bar (to STDERR) showing the current progress.  This option
will only be useful if you are redirecting STDOUT (and not STDERR).  In the
case where no valid terminal is found this option will behave very much like
the --showdots option in other SpamAssassin programs.

=item B<-D> [I<area,...>], B<--debug> [I<area,...>]

lib/spamassassin-run.pod  view on Meta::CPAN

command line is a path, to prevent the path from being parsed as an area.

Higher priority informational messages that are suitable for logging in normal
circumstances are available with an area of "info".

For more information about which areas (also known as channels) are available,
please see the documentation at:

	L<https://wiki.apache.org/spamassassin/DebugChannels>

=item B<-x>, B<--nocreate-prefs>

Disable creation of user preferences file.

=item B<--mbox>

Specify that the input message(s) are in mbox format.  mbox is a standard
Unix message folder format.

=item B<--mbx>

sa-compile.raw  view on Meta::CPAN

    permute no_auto_abbrev no_ignore_case)
);

GetOptions(
  'list'		=> \$opt{'list'},
  'sudo'		=> \$opt{'sudo'},
  'quiet'               => \$opt{'quiet'},
  'keep-tmps'		=> \$opt{'keep-tmps'},

  'configpath|config-file|config-dir|c|C=s' => \$opt{'configpath'},
  'prefspath|prefs-file|p=s'                => \$opt{'prefspath'},
  'siteconfigpath=s'                        => \$opt{'siteconfigpath'},
  'updatedir=s'                             => \$opt{'updatedir'},
  'cf=s'                                    => \@{$opt{'cf'}},
  'debug|D:s'       => \$opt{'debug'},
  'help|h|?'        => \$opt{'help'},
  'version|V'       => \$opt{'version'},
  )
  or usage( 0, "Unknown option!" );

if ( defined $opt{'help'} ) {

sa-compile.raw  view on Meta::CPAN

# ensure the body-rule base extractor plugin is loaded, we use that
my $post_config = q(
  loadplugin Mail::SpamAssassin::Plugin::BodyRuleBaseExtractor

).join("\n", @{$opt{'cf'}})."\n";

my $spamtest = Mail::SpamAssassin->new(
  {
    rules_filename      => $opt{'configpath'},
    site_rules_filename => $opt{'siteconfigpath'},
    userprefs_filename  => $opt{'prefspath'},
    debug               => $opt{'debug'},
    local_tests_only    => 1,
    dont_copy_prefs     => 1,
    PREFIX              => $PREFIX,
    DEF_RULES_DIR       => $DEF_RULES_DIR,
    LOCAL_RULES_DIR     => $LOCAL_RULES_DIR,
    LOCAL_STATE_DIR     => $LOCAL_STATE_DIR,
    post_config_text    => $post_config,
  }
);

# appropriate BodyRuleBaseExtractor settings for rule2xs usage
$spamtest->{base_extract} = 1;

sa-compile.raw  view on Meta::CPAN


B<sa-compile> [options]

Options:

  --list                        Output base string list to STDOUT
  --sudo                        Use 'sudo' for privilege escalation
  --keep-tmps                   Keep temporary files instead of deleting
  -C path, --configpath=path, --config-file=path
                                Path to standard configuration dir
  -p prefs, --prefspath=file, --prefs-file=file
                                Set user preferences file
  --siteconfigpath=path         Path for site configs
                                (default: @@PREFIX@@/etc/mail/spamassassin)
  --updatedir=path              Directory to place updates
          (default: @@LOCAL_STATE_DIR@@/compiled/<perlversion>/@@VERSION@@)
  --cf='config line'            Additional line of configuration
  -D, --debug [area=n,...]	Print debugging messages
  -V, --version			Print version
  -h, --help			Print usage message

=head1 DESCRIPTION

sa-compile uses C<re2c> to compile the site-wide parts of the SpamAssassin
ruleset. No part of user_prefs or any files included from user_prefs can be
built into the compiled set.

This compiled set is then used by the 
C<Mail::SpamAssassin::Plugin::Rule2XSBody> plugin to speed up
SpamAssassin's operation, where possible, and when that plugin is loaded.

C<re2c> can match strings much faster than perl code, by constructing a DFA to
match many simple strings in parallel, and compiling that to native object
code.  Not all SpamAssassin rules are amenable to this conversion, however.

sa-compile.raw  view on Meta::CPAN

compiled rules the wrong directory, you probably need to rebuild SpamAssassin
with different C<Makefile.PL> arguments, instead of overriding sa-compile's
runtime behaviour.

=item B<--cf='config line'>

Add additional lines of configuration directly from the command-line, parsed
after the configuration files are read.   Multiple B<--cf> arguments can be
used, and each will be considered a separate line of configuration.

=item B<-p> I<prefs>, B<--prefspath>=I<prefs>, B<--prefs-file>=I<prefs>

Read user score preferences from I<prefs> (usually
C<$HOME/.spamassassin/user_prefs>) .

=item B<-D> [I<area,...>], B<--debug> [I<area,...>]

Produce debugging output.  If no areas are listed, all debugging information is
printed.  Diagnostic output can also be enabled for each area individually;
I<area> is the area of the code to instrument.

For more information about which areas (also known as channels) are
available, please see the documentation at
L<https://wiki.apache.org/spamassassin/DebugChannels>.

sa-learn.raw  view on Meta::CPAN

GetOptions(
  'forget'      => \$forget,
  'ham|nonspam' => sub { $isspam = 0; },
  'spam'        => sub { $isspam = 1; },
  'sync'        => \$synconly,
  'rebuild'     => sub { $synconly = 1; warn "The --rebuild option has been deprecated.  Please use --sync instead.\n" },

  'q|quiet'     => \$opt{'quiet'},
  'username|u=s'    => \$opt{'username'},
  'configpath|config-file|config-dir|c|C=s' => \$opt{'configpath'},
  'prefspath|prefs-file|p=s'                => \$opt{'prefspath'},
  'siteconfigpath=s'                        => \$opt{'siteconfigpath'},
  'cf=s'                                    => \@{$opt{'cf'}},

  'folders|f=s'          => \$opt{'folders'},
  'force-expire|expire'  => \$opt{'force-expire'},
  'local|L'              => \$opt{'local'},
  'no-sync|nosync'       => \$opt{'nosync'},
  'showdots'             => \$opt{'showdots'},
  'progress'             => \$opt{'progress'},
  'use-ignores'          => \$opt{'use-ignores'},

sa-learn.raw  view on Meta::CPAN

  $post_config .= "use_bayes 1\n";
}

$post_config .= join("\n", @{$opt{'cf'}})."\n";

# create the tester factory
$spamtest = Mail::SpamAssassin->new(
  {
    rules_filename      => $opt{'configpath'},
    site_rules_filename => $opt{'siteconfigpath'},
    userprefs_filename  => $opt{'prefspath'},
    username            => $opt{'username'},
    debug               => $opt{'debug'},
    local_tests_only    => $opt{'local'},
    dont_copy_prefs     => 1,
    PREFIX              => $PREFIX,
    DEF_RULES_DIR       => $DEF_RULES_DIR,
    LOCAL_RULES_DIR     => $LOCAL_RULES_DIR,
    post_config_text	=> $post_config,
  }
);

$spamtest->init(1);
dbg("sa-learn: spamtest initialized");

sa-learn.raw  view on Meta::CPAN

 --import              Migrate data from older version/non DB_File
                       based databases
 --clear               Wipe out existing database
 --backup              Backup, to STDOUT, existing database
 --restore <filename>  Restore a database from filename
 -u username, --username=username
                       Override username taken from the runtime
                       environment, used with SQL
 -C path, --configpath=path, --config-file=path
                       Path to standard configuration dir
 -p prefs, --prefspath=file, --prefs-file=file
                       Set user preferences file
 --siteconfigpath=path Path for site configs
                       (default:  @@PREFIX@@/etc/mail/spamassassin)
 --cf='config line'    Additional line of configuration
 -D, --debug [area,...]  Print debugging messages
 -V, --version         Print version
 -h, --help            Print usage message

=head1 DESCRIPTION

sa-learn.raw  view on Meta::CPAN


Use the specified path for locating site-specific configuration files.  Ignore
the default directories (usually C</etc/mail/spamassassin> or similar).

=item B<--cf='config line'>

Add additional lines of configuration directly from the command-line, parsed
after the configuration files are read.   Multiple B<--cf> arguments can be
used, and each will be considered a separate line of configuration.

=item B<-p> I<prefs>, B<--prefspath>=I<prefs>, B<--prefs-file>=I<prefs>

Read user score preferences from I<prefs> (usually C<$HOME/.spamassassin/user_prefs>).

=item B<--progress>

Prints a progress bar (to STDERR) showing the current progress.  In the case
where no valid terminal is found this option will behave very much like the
--showdots option.

=item B<-D> [I<area,...>], B<--debug> [I<area,...>]

Produce debugging output. If no areas are listed, all debugging information is

sa-update.raw  view on Meta::CPAN

}
my $RevSAVersion = join(".", reverse split(/\./, $SAVersion));

# set debug areas, if any specified (only useful for command-line tools)
$opt{'debug'} ||= 'all' if (defined $opt{'debug'});

# Find the default site rule directory, also setup debugging and other M::SA bits
my $SA = Mail::SpamAssassin->new({
  debug => $opt{'debug'},
  local_tests_only => 1,
  dont_copy_prefs => 1,

  PREFIX          => $PREFIX,
  DEF_RULES_DIR   => $DEF_RULES_DIR,
  LOCAL_RULES_DIR => $LOCAL_RULES_DIR,
  LOCAL_STATE_DIR => $LOCAL_STATE_DIR,
});

if (defined $opt{'updatedir'}) {
  $opt{'updatedir'} = untaint_file_path($opt{'updatedir'});
}

sa-update.raw  view on Meta::CPAN

sub lint_check_dir {
  my $dir = shift;

  # due to the Logger module's globalness (all M::SA objects share the same
  # Logger setup), we can't change the debug level here to only include
  # "config" or otherwise be more terse. :(
  my $spamtest = Mail::SpamAssassin->new( {
    rules_filename       => $dir,
    site_rules_filename  => $LOCAL_RULES_DIR,
    ignore_site_cf_files => 1,
    userprefs_filename   => File::Spec->catfile($dir, "doesnotexist"),

    local_tests_only     => 1,
    dont_copy_prefs      => 1,

    PREFIX               => $PREFIX,
    DEF_RULES_DIR        => $DEF_RULES_DIR,
    LOCAL_RULES_DIR      => $LOCAL_RULES_DIR,
    LOCAL_STATE_DIR      => $LOCAL_STATE_DIR,
  });

  # need to kluge disabling bayes since it may try to expire the DB, and
  # without the proper config it's not going to be good.
  $spamtest->{conf}->{use_bayes} = 0;

spamassassin.raw  view on Meta::CPAN

# Check to make sure the script version and the module version matches.
# If not, die here!  Also, deal with unchanged VERSION macro.
if ($Mail::SpamAssassin::VERSION ne '@@VERSION@@' && '@@VERSION@@' ne "\@\@VERSION\@\@") {
  die 'spamassassin: spamassassin script is v@@VERSION@@, but using modules v'.$Mail::SpamAssassin::VERSION."\n";
}

# by default:
# - create user preference files
# - have ArchiveIterator detect the input message format (file vs dir)
#
my %opt = ( 'create-prefs' => 1, 'format' => 'detect', pre => [], cf => [] );

my $doing_welcomelist_operation = 0;
my $count                     = 0;
my @targets                   = ();
my $exitvalue;

my $init_results              = 0;
my $progress;
my $total_messages            = 0;

spamassassin.raw  view on Meta::CPAN

  'add-addr-to-blocklist=s'                 => \$opt{'add-addr-to-blocklist'},
  'add-addr-to-welcomelist=s'               => \$opt{'add-addr-to-welcomelist'},
  'add-addr-to-blacklist=s'                 => \$opt{'add-addr-to-blocklist'}, # removed in 4.1
  'add-addr-to-whitelist=s'                 => \$opt{'add-addr-to-welcomelist'}, # removed in 4.1
  'add-to-blocklist'                        => \$opt{'add-to-blocklist'},
  'add-to-welcomelist|W'                    => \$opt{'add-to-welcomelist'},
  'add-to-blacklist'                        => \$opt{'add-to-blocklist'}, # removed in 4.1
  'add-to-whitelist'                        => \$opt{'add-to-welcomelist'}, # removed in 4.1
  'username|u=s'                            => \$opt{'username'},
  'configpath|config-file|config-dir|c|C=s' => \$opt{'configpath'},
  'create-prefs!'                           => \$opt{'create-prefs'},
  'pre=s'                                   => \@{$opt{'pre'}},
  'cf=s'                                    => \@{$opt{'cf'}},
  'debug|D:s'                               => \$opt{'debug'},
  'error-code|exit-code|e:i'                => \$opt{'error-code'},
  'help|h|?'                                => \$opt{'help'},
  '4|ipv4only|ipv4-only|ipv4'               => sub { $opt{'force_ipv4'} = 1;
                                                     $opt{'force_ipv6'} = 0; },
  '6'                                       => sub { $opt{'force_ipv6'} = 1;
                                                     $opt{'force_ipv4'} = 0; },
  'lint'                                    => \$opt{'lint'},
  'net'                                     => \$opt{'net'},
  'local-only|local|L'                      => \$opt{'local'},
  'mbox'                                    => sub { $opt{'format'} = 'mbox'; },
  'mbx'                                     => sub { $opt{'format'} = 'mbx'; },
  'prefspath|prefs-file|p=s'                => \$opt{'prefspath'},
  'remove-addr-from-welcomelist=s'          => \$opt{'remove-addr-from-welcomelist'},
  'remove-addr-from-blocklist=s'            => \$opt{'remove-addr-from-blocklist'},
  'remove-from-welcomelist|R'               => \$opt{'remove-from-welcomelist'},
  'remove-addr-from-whitelist=s'            => \$opt{'remove-addr-from-welcomelist'}, # removed in 4.1
  'remove-from-whitelist'                   => \$opt{'remove-from-welcomelist'}, # removed in 4.1
  'remove-markup|despamassassinify|d'       => \$opt{'remove-markup'},
  'report|r'                                => \$opt{'report'},
  'revoke|k'                                => \$opt{'revoke'},
  'siteconfigpath=s'                        => \$opt{'siteconfigpath'},
  'test-mode|test|t'                        => \$opt{'test-mode'},
  'progress'                                => \$opt{'progress'},
  'version|V'                               => \$opt{'version'},
  'x'                                       => sub { $opt{'create-prefs'} = 0 },

  #
  # NOTE: These are old options.  We should ignore (but warn about)
  # the ones that are now defaults.  Everything else gets a die (see note2)
  # so the user doesn't get us doing something they didn't expect.
  #
  # NOTE2: 'die' doesn't actually stop the process, GetOptions() catches
  # it, then passes the error on, so we'll end up doing a Usage statement.
  # You can avoid that by doing an explicit exit in the sub.
  #

spamassassin.raw  view on Meta::CPAN


# bug 5048: --lint should not cause network accesses
# allow --net to override for testing
if ($opt{'lint'} && !$opt{'net'}) { $opt{'local'} = 1; }

# create the tester factory
my $spamtest = Mail::SpamAssassin->new(
  {
    rules_filename      => $opt{'configpath'},
    site_rules_filename => $opt{'siteconfigpath'},
    userprefs_filename  => $opt{'prefspath'},
    username            => $opt{'username'},
    force_ipv4          => $opt{'force_ipv4'},
    force_ipv6          => $opt{'force_ipv6'},
    local_tests_only    => $opt{'local'},
    debug               => $opt{'debug'},
    dont_copy_prefs     => ( $opt{'create-prefs'} ? 0 : 1 ),
    pre_config_text     => join("\n", @{$opt{'pre'}})."\n",
    post_config_text    => join("\n", @{$opt{'cf'}})."\n",
    require_rules       => 1,
    PREFIX              => $PREFIX,
    DEF_RULES_DIR       => $DEF_RULES_DIR,
    LOCAL_RULES_DIR     => $LOCAL_RULES_DIR,
    LOCAL_STATE_DIR     => $LOCAL_STATE_DIR,
  }
);

spamassassin.raw  view on Meta::CPAN


=item /etc/spamassassin

=back

From those directories, SpamAssassin will first read files ending in
".pre" in lexical order and then it will read files ending in ".cf" in
lexical order (most files begin with two numbers to make the sorting
order obvious).

In other words, it will read F<init.pre> first, then F<10_default_prefs.cf> before
F<50_scores.cf> and F<20_body_tests.cf> before F<20_head_tests.cf>.
Options in later files will override earlier files.

Individual user preferences are loaded from the location specified on
the C<spamassassin>, C<sa-learn>, or C<spamd> command line (see respective
manual page for details).  If the location is not specified,
F<~/.spamassassin/user_prefs> is used if it exists.  SpamAssassin will
create that file if it does not already exist, using
F<user_prefs.template> as a template.  That file will be looked for in:

=over 4

=item @@LOCAL_RULES_DIR@@

=item @@PREFIX@@/etc/mail/spamassassin

=item @@PREFIX@@/share/spamassassin

=item /etc/spamassassin

spamd-apache2/bin/apache-spamd.pl  view on Meta::CPAN

command line options, compatible to spamd where possible and makes sense.

If this script doesn't work for you, complain.

=head1 TODO

 * misc MPMs
 * testing on different platforms and configurations
 * fix FIXME's
 * review XXX's
 * --create-prefs (?), --help, --virtual-config-dir
 * current directory (home_dir_for_helpers?)

=cut

# NOTE: the amount of code here and list of loaded modules doesn't matter;
# we exec() anyway.

# NOTE: no point in using -T, it'd only mess up code with workarounds;
# we don't process any user input but command line options.

spamd-apache2/lib/Mail/SpamAssassin/Spamd/Apache2.pm  view on Meta::CPAN

    else {
      # if we are given a username, but can't look it up, maybe name
      # services are down?  let's break out here to allow them to get
      # 'defaults' when we are not running paranoid
      info($errmsg);
    }
    return 0;
  }

  my $cf_dir  = File::Spec->catdir($dir,     '.spamassassin');
  my $cf_file = File::Spec->catfile($cf_dir, 'user_prefs');
  if (!-l $cf_dir && -d _ && !-d $cf_file && -f _ && -s _) {
    $self->spamtest->read_scoreonly_config($cf_file);

    # if the $cf_dir group matches ours, assume we can write there
    my $user_dir = $) == (stat $cf_dir)[5] ? $dir : undef;

    $self->spamtest->signal_user_changed(
      { username => $username, user_dir => $user_dir, });
  }
  return 1;



( run in 2.221 seconds using v1.01-cache-2.11-cpan-8f98c5d2c55 )