/amavisd-new-2.8.0/amavisd
Perl | 11249 lines | 9407 code | 279 blank | 1563 comment | 824 complexity | 4fc193aa494cbf85ec5fb01922acc8f3 MD5 | raw file
Possible License(s): GPL-2.0
Large files files are truncated, but you can click here to view the full file
- #!/usr/bin/perl -T
- #!/usr/bin/perl -d:NYTProf
- #------------------------------------------------------------------------------
- # This is amavisd-new.
- # It is an interface between a message transfer agent (MTA) and virus
- # scanners and/or spam scanners, functioning as a mail content filter.
- #
- # It is a performance-enhanced and feature-enriched version of amavisd
- # (which in turn is a daemonized version of AMaViS), initially based
- # on amavisd-snapshot-20020300).
- #
- # All work since amavisd-snapshot-20020300:
- # Copyright (C) 2002-2012 Mark Martinec,
- # All Rights Reserved.
- # with contributions from the amavis-user mailing list and individuals,
- # as acknowledged in the release notes.
- #
- # This program is free software; you can redistribute it and/or modify
- # it under the terms of the GNU General Public License as published by
- # the Free Software Foundation; either version 2 of the License, or
- # (at your option) any later version.
- #
- # This program is distributed in the hope that it will be useful,
- # but WITHOUT ANY WARRANTY; without even the implied warranty of
- # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- # GNU General Public License for details.
- #
- # You should have received a copy of the GNU General Public License
- # along with this program; if not, write to the Free Software
- # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- # Author: Mark Martinec <Mark.Martinec@ijs.si>
- # Patches and problem reports are welcome.
- #
- # The latest version of this program is available at:
- # http://www.ijs.si/software/amavisd/
- #------------------------------------------------------------------------------
- # Here is a boilerplate from the amavisd(-snapshot) version,
- # which is the version that served as a base code for the initial
- # version of amavisd-new. License terms were the same:
- #
- # Author: Chris Mason <cmason@unixzone.com>
- # Current maintainer: Lars Hecking <lhecking@users.sourceforge.net>
- # Based on work by:
- # Mogens Kjaer, Carlsberg Laboratory, <mk@crc.dk>
- # Juergen Quade, Softing GmbH, <quade@softing.com>
- # Christian Bricart <shiva@aachalon.de>
- # Rainer Link <link@foo.fh-furtwangen.de>
- # This script is part of the AMaViS package. For more information see:
- # http://amavis.org/
- # Copyright (C) 2000 - 2002 the people mentioned above
- # This software is licensed under the GNU General Public License (GPL)
- # See: http://www.gnu.org/copyleft/gpl.html
- #------------------------------------------------------------------------------
- #------------------------------------------------------------------------------
- #Index of packages in this file
- # Amavis::Boot
- # Amavis::Conf
- # Amavis::Log
- # Amavis::DbgLog
- # Amavis::Timing
- # Amavis::Util
- # Amavis::ProcControl
- # Amavis::rfc2821_2822_Tools
- # Amavis::Lookup::RE
- # Amavis::Lookup::IP
- # Amavis::Lookup::Opaque
- # Amavis::Lookup::OpaqueRef
- # Amavis::Lookup::Label
- # Amavis::Lookup::SQLfield (just the new() method)
- # Amavis::Lookup::LDAPattr (just the new() method)
- # Amavis::Lookup
- # Amavis::Expand
- # Amavis::TempDir
- # Amavis::IO::FileHandle
- # Amavis::IO::Zlib
- # Amavis::IO::RW
- # Amavis::In::Connection
- # Amavis::In::Message::PerRecip
- # Amavis::In::Message
- # Amavis::Out::EditHeader
- # Amavis::Out
- # Amavis::UnmangleSender
- # Amavis::Unpackers::NewFilename
- # Amavis::Unpackers::Part
- # Amavis::Unpackers::OurFiler
- # Amavis::Unpackers::Validity
- # Amavis::Unpackers::MIME
- # Amavis::Notify
- # Amavis::Custom
- # Amavis
- #optionally compiled-in packages: ---------------------------------------------
- # Amavis::ZMQ
- # Amavis::DB::SNMP
- # Amavis::DB
- # Amavis::Lookup::SQLfield (the rest)
- # Amavis::Lookup::SQL
- # Amavis::LDAP::Connection
- # Amavis::Lookup::LDAP
- # Amavis::Lookup::LDAPattr (the rest)
- # Amavis::In::AMPDP
- # Amavis::In::SMTP
- #( Amavis::In::Courier )
- # Amavis::Out::SMTP::Protocol
- # Amavis::Out::SMTP::Session
- # Amavis::Out::SMTP
- # Amavis::Out::Pipe
- # Amavis::Out::BSMTP
- # Amavis::Out::Local
- # Amavis::OS_Fingerprint
- # Amavis::Out::SQL::Connection
- # Amavis::Out::SQL::Log
- # Amavis::IO::SQL
- # Amavis::Out::SQL::Quarantine
- # Amavis::AV
- # Amavis::SpamControl
- # Amavis::SpamControl::ExtProg
- # Amavis::SpamControl::SpamdClient
- # Mail::SpamAssassin::Logger::Amavislog
- # Amavis::SpamControl::SpamAssassin
- # Amavis::Unpackers
- # Amavis::DKIM::CustomSigner
- # Amavis::DKIM
- # Amavis::Tools
- #------------------------------------------------------------------------------
- use strict;
- use re 'taint';
- use warnings;
- use warnings FATAL => qw(utf8 void);
- no warnings 'uninitialized';
- #
- package Amavis::Boot;
- use strict;
- use re 'taint';
- use Errno qw(ENOENT EACCES);
- # replacement for a 'require' with a more informative error handling
- #sub my_require($) {
- # my($filename) = @_;
- # my $result;
- # if (exists $INC{$filename} && !$INC{$filename}) {
- # die "Compilation failed in require\n";
- # } elsif (exists $INC{$filename}) {
- # $result = 1; # already loaded
- # } else {
- # my $found = 0;
- # for my $prefix (@INC) {
- # my $full_fname = "$prefix/$filename";
- # my(@stat_list) = stat($full_fname); # symlinks-friendly
- # my $errn = @stat_list ? 0 : 0+$!;
- # if ($errn != ENOENT) {
- # $found = 1;
- # $INC{$filename} = $full_fname;
- # my $owner_uid = $stat_list[4];
- # my $msg;
- # if ($errn) { $msg = "is inaccessible: $!" }
- # elsif (-d _) { $msg = "is a directory" }
- # elsif (!-f _) { $msg = "is not a regular file" }
- # elsif ($> && -o _) { $msg = "should not be owned by EUID $>" }
- # elsif ($> && -w _) { $msg = "is writable by EUID $>, EGID $)" }
- # elsif ($owner_uid) { $msg = "should be owned by root (uid 0) "}
- # !defined($msg) or die "Requiring $full_fname, file $msg,\n";
- # $! = 0;
- # $result = do $full_fname;
- # if (!defined($result) && $@ ne '') {
- # undef $INC{$filename}; chomp($@);
- # die "Error in file $full_fname: $@\n";
- # } elsif (!defined($result) && $! != 0) {
- # undef $INC{$filename};
- # die "Error reading file $full_fname: $!\n";
- # } elsif (!$result) {
- # undef $INC{$filename};
- # die "Module $full_fname did not return a true value\n";
- # }
- # last;
- # }
- # }
- # die sprintf("my_require: Can't locate %s in \@INC (\@INC contains: %s)\n",
- # $filename, join(' ',@INC)) if !$found;
- # }
- # $result;
- #}
- # Fetch all required modules (or nicely report missing ones), and compile them
- # once-and-for-all at the parent process, so that forked children can inherit
- # and share already compiled code in memory. Children will still need to 'use'
- # modules if they want to inherit from their name space.
- #
- sub fetch_modules($$@) {
- my($reason, $required, @modules) = @_;
- my $have_sawampersand = Devel::SawAmpersand->UNIVERSAL::can('sawampersand');
- my $amp = $have_sawampersand && Devel::SawAmpersand::sawampersand() ? 1 : 0;
- warn 'fetch_modules: PL_sawampersand flag was already turned on' if $amp;
- my(@missing);
- for my $m (@modules) {
- local $_ = $m;
- $_ .= /^auto::/ ? '.al' : '.pm' if !m{^/} && !m{\.(?:pm|pl|al|ix)\z};
- s{::}{/}g;
- # eval { my_require $_ } #more informative on err, but some problems reported
- eval { require $_ }
- or do {
- my $eval_stat = $@ ne '' ? $@ : "errno=$!"; chomp $eval_stat;
- push(@missing,$m);
- $eval_stat =~ s/^/ /mgs; # indent
- printf STDERR ("fetch_modules: error loading %s module %s:\n%s\n",
- $required ? 'required' : 'optional', $_, $eval_stat)
- if $eval_stat !~ /\bCan't locate \Q$_\E in \@INC\b/;
- };
- if ($have_sawampersand && !$amp && Devel::SawAmpersand::sawampersand())
- { $amp = 1; warn "Loading of module $m turned on PL_sawampersand flag" }
- }
- die "ERROR: MISSING $reason:\n" . join('', map(" $_\n", @missing))
- if $required && @missing;
- \@missing;
- }
- BEGIN {
- if ($] <= 5.008) { # deal with a glob() taint bug (perl 5.6.1, 5.8.0)
- fetch_modules('REQUIRED BASIC MODULES', 1, qw(File::Glob));
- File::Glob->import(':globally'); # use the same module as Perl 5.8 uses
- }
- fetch_modules('REQUIRED BASIC MODULES', 1, qw(
- Exporter POSIX Fcntl Socket Errno Carp Time::HiRes
- IO::Handle IO::File IO::Socket IO::Socket::UNIX
- IO::Stringy Digest::MD5 Unix::Syslog File::Basename
- Compress::Zlib MIME::Base64 MIME::QuotedPrint MIME::Words
- MIME::Head MIME::Body MIME::Entity MIME::Parser MIME::Decoder
- MIME::Decoder::Base64 MIME::Decoder::Binary MIME::Decoder::QuotedPrint
- MIME::Decoder::NBit MIME::Decoder::UU MIME::Decoder::Gzip64
- Net::Server Net::Server::PreFork
- ));
- # with earlier versions of Perl one may need to add additional modules
- # to the list, such as: auto::POSIX::setgid auto::POSIX::setuid ...
- fetch_modules('OPTIONAL BASIC MODULES', 0, qw(
- PerlIO PerlIO::scalar Unix::Getrusage
- Carp::Heavy auto::POSIX::setgid auto::POSIX::setuid
- auto::POSIX::SigAction::new auto::POSIX::SigAction::safe
- MIME::Decoder::BinHex
- ));
- 1;
- }
- 1;
- #
- package Amavis::Conf;
- use strict;
- use re 'taint';
- # constants; intentionally leave value -1 unassigned for compatibility
- use constant D_TEMPFAIL => -4;
- use constant D_REJECT => -3;
- use constant D_BOUNCE => -2;
- use constant D_DISCARD => 0;
- use constant D_PASS => 1;
- # major contents_category constants, in increasing order of importance
- use constant CC_CATCHALL => 0;
- use constant CC_CLEAN => 1; # tag_level = "CC_CLEAN,1"
- use constant CC_MTA => 2; # trouble passing mail back to MTA
- use constant CC_OVERSIZED => 3;
- use constant CC_BADH => 4;
- use constant CC_SPAMMY => 5; # tag2_level (and: tag3_level = CC_SPAMMY,1)
- use constant CC_SPAM => 6; # kill_level
- use constant CC_UNCHECKED => 7;
- use constant CC_BANNED => 8;
- use constant CC_VIRUS => 9;
- #
- # in other words: major_ccat minor_ccat %subject_tag_maps_by_ccat
- ## if score >= kill level => CC_SPAM 0
- ## elsif score >= tag3 level => CC_SPAMMY 1 @spam_subject_tag3_maps
- ## elsif score >= tag2 level => CC_SPAMMY 0 @spam_subject_tag2_maps
- ## elsif score >= tag level => CC_CLEAN 1 @spam_subject_tag_maps
- ## else => CC_CLEAN 0
- BEGIN {
- require Exporter;
- use vars qw(@ISA @EXPORT @EXPORT_OK %EXPORT_TAGS $VERSION);
- $VERSION = '2.316';
- @ISA = qw(Exporter);
- %EXPORT_TAGS = (
- 'dynamic_confvars' => # per- policy bank settings
- [qw(
- $child_timeout $smtpd_timeout
- $policy_bank_name $protocol @inet_acl
- $myhostname $myauthservid $snmp_contact $snmp_location
- $myprogram_name $syslog_ident $syslog_facility
- $log_level $log_templ $log_recip_templ $enable_log_capture_dump
- $forward_method $notify_method $resend_method $report_format
- $release_method $requeue_method $release_format
- $attachment_password $attachment_email_name $attachment_outer_name
- $os_fingerprint_method $os_fingerprint_dst_ip_and_port
- $originating @smtpd_discard_ehlo_keywords $soft_bounce
- $propagate_dsn_if_possible $terminate_dsn_on_notify_success
- $amavis_auth_user $amavis_auth_pass $auth_reauthenticate_forwarded
- $auth_required_out $auth_required_inp $auth_required_release
- @auth_mech_avail $tls_security_level_in $tls_security_level_out
- $local_client_bind_address $smtpd_message_size_limit
- $localhost_name $smtpd_greeting_banner $smtpd_quit_banner
- $mailfrom_to_quarantine $warn_offsite $bypass_decode_parts @decoders
- @av_scanners @av_scanners_backup @spam_scanners
- $first_infected_stops_scan $virus_scanners_failure_is_fatal
- $sa_spam_level_char $sa_mail_body_size_limit
- $penpals_bonus_score $penpals_halflife $bounce_killer_score
- $reputation_factor
- $undecipherable_subject_tag $localpart_is_case_sensitive
- $recipient_delimiter $replace_existing_extension
- $hdr_encoding $bdy_encoding $hdr_encoding_qb
- $allow_disclaimers
- $prepend_header_fields_hdridx
- $allow_fixing_improper_header
- $allow_fixing_improper_header_folding $allow_fixing_long_header_lines
- %allowed_added_header_fields %prefer_our_added_header_fields
- %allowed_header_tests
- $X_HEADER_TAG $X_HEADER_LINE
- $remove_existing_x_scanned_headers $remove_existing_spam_headers
- %sql_clause $partition_tag
- %local_delivery_aliases $banned_namepath_re
- $per_recip_whitelist_sender_lookup_tables
- $per_recip_blacklist_sender_lookup_tables
- @anomy_sanitizer_args @altermime_args_defang
- @altermime_args_disclaimer @disclaimer_options_bysender_maps
- %signed_header_fields @dkim_signature_options_bysender_maps
- $enable_dkim_verification $enable_dkim_signing $dkim_signing_service
- $enable_ldap
- @local_domains_maps @mynetworks_maps @client_ipaddr_policy
- @forward_method_maps @newvirus_admin_maps @banned_filename_maps
- @spam_quarantine_bysender_to_maps
- @spam_tag_level_maps @spam_tag2_level_maps @spam_tag3_level_maps
- @spam_kill_level_maps
- @spam_subject_tag_maps @spam_subject_tag2_maps @spam_subject_tag3_maps
- @spam_dsn_cutoff_level_maps @spam_dsn_cutoff_level_bysender_maps
- @spam_crediblefrom_dsn_cutoff_level_maps
- @spam_crediblefrom_dsn_cutoff_level_bysender_maps
- @spam_quarantine_cutoff_level_maps @spam_notifyadmin_cutoff_level_maps
- @whitelist_sender_maps @blacklist_sender_maps @score_sender_maps
- @author_to_policy_bank_maps @signer_reputation_maps
- @message_size_limit_maps @debug_sender_maps @debug_recipient_maps
- @bypass_virus_checks_maps @bypass_spam_checks_maps
- @bypass_banned_checks_maps @bypass_header_checks_maps
- @viruses_that_fake_sender_maps
- @virus_name_to_spam_score_maps @virus_name_to_policy_bank_maps
- @remove_existing_spam_headers_maps
- @sa_userconf_maps @sa_username_maps
- %final_destiny_by_ccat %forward_method_maps_by_ccat
- %lovers_maps_by_ccat %defang_maps_by_ccat %subject_tag_maps_by_ccat
- %quarantine_method_by_ccat %quarantine_to_maps_by_ccat
- %notify_admin_templ_by_ccat %notify_recips_templ_by_ccat
- %notify_sender_templ_by_ccat %notify_autoresp_templ_by_ccat
- %notify_release_templ_by_ccat %notify_report_templ_by_ccat
- %warnsender_by_ccat
- %hdrfrom_notify_admin_by_ccat %mailfrom_notify_admin_by_ccat
- %hdrfrom_notify_recip_by_ccat %mailfrom_notify_recip_by_ccat
- %hdrfrom_notify_sender_by_ccat
- %hdrfrom_notify_release_by_ccat %hdrfrom_notify_report_by_ccat
- %admin_maps_by_ccat %warnrecip_maps_by_ccat
- %always_bcc_by_ccat %dsn_bcc_by_ccat
- %addr_extension_maps_by_ccat %addr_rewrite_maps_by_ccat
- %smtp_reason_by_ccat
- )],
- 'confvars' => # global settings (not per-policy, not per-recipient)
- [qw(
- $myproduct_name $myversion_id $myversion_id_numeric $myversion_date
- $myversion $instance_name @additional_perl_modules
- $MYHOME $TEMPBASE $QUARANTINEDIR $quarantine_subdir_levels
- $daemonize $courierfilter_shutdown $pid_file $lock_file $db_home
- $enable_db $enable_zmq @zmq_sockets $mail_id_size_bits
- $daemon_user $daemon_group $daemon_chroot_dir $path
- $DEBUG $do_syslog $logfile $allow_preserving_evidence $enable_log_capture
- $log_short_templ $log_verbose_templ $logline_maxlen
- $nanny_details_level $max_servers $max_requests
- $min_servers $min_spare_servers $max_spare_servers
- %current_policy_bank %policy_bank %interface_policy
- @listen_sockets $inet_socket_port $inet_socket_bind $listen_queue_size
- $unix_socketname $unix_socket_mode
- $smtp_connection_cache_on_demand $smtp_connection_cache_enable
- $smtpd_recipient_limit
- $smtpd_tls_cert_file $smtpd_tls_key_file
- $enforce_smtpd_message_size_limit_64kb_min
- $MAXLEVELS $MAXFILES
- $MIN_EXPANSION_QUOTA $MIN_EXPANSION_FACTOR
- $MAX_EXPANSION_QUOTA $MAX_EXPANSION_FACTOR
- $database_sessions_persistent $lookup_maps_imply_sql_and_ldap
- @lookup_sql_dsn @storage_sql_dsn
- $sql_schema_version $timestamp_fmt_mysql
- $sql_quarantine_chunksize_max $sql_allow_8bit_address
- $sql_lookups_no_at_means_domain $ldap_lookups_no_at_means_domain
- $sql_store_info_for_all_msgs
- $trim_trailing_space_in_lookup_result_fields
- $default_ldap $mail_digest_algorithm
- @keep_decoded_original_maps @map_full_type_to_short_type_maps
- %banned_rules $penpals_threshold_low $penpals_threshold_high
- %dkim_signing_keys_by_domain
- @dkim_signing_keys_list @dkim_signing_keys_storage
- $file $altermime $enable_anomy_sanitizer
- )],
- 'sa' => # global SpamAssassin settings
- [qw(
- $spamcontrol_obj $sa_num_instances
- $helpers_home $sa_configpath $sa_siteconfigpath $sa_userprefs_file
- $sa_local_tests_only $sa_timeout $sa_debug
- $dspam $sa_spawned
- )],
- 'platform' => [qw(
- $can_truncate $unicode_aware $my_pid
- $AF_INET6 $have_inet4 $have_inet6 $have_socket_ip
- &D_TEMPFAIL &D_REJECT &D_BOUNCE &D_DISCARD &D_PASS
- &CC_CATCHALL &CC_CLEAN &CC_MTA &CC_OVERSIZED &CC_BADH
- &CC_SPAMMY &CC_SPAM &CC_UNCHECKED &CC_BANNED &CC_VIRUS
- %ccat_display_names %ccat_display_names_major
- )],
- # other variables settable by user in amavisd.conf,
- # but not directly accessible to the program
- 'hidden_confvars' => [qw(
- $mydomain
- )],
- 'legacy_dynamic_confvars' =>
- # the rest of the program does not use these settings directly and they
- # should not be visible in, or imported to other modules, but may be
- # referenced indirectly through *_by_ccat variables for compatibility
- [qw(
- $final_virus_destiny $final_banned_destiny $final_unchecked_destiny
- $final_spam_destiny $final_bad_header_destiny
- @virus_lovers_maps @spam_lovers_maps @unchecked_lovers_maps
- @banned_files_lovers_maps @bad_header_lovers_maps
- $always_bcc $dsn_bcc
- $mailfrom_notify_sender $mailfrom_notify_recip
- $mailfrom_notify_admin $mailfrom_notify_spamadmin
- $hdrfrom_notify_sender $hdrfrom_notify_recip
- $hdrfrom_notify_admin $hdrfrom_notify_spamadmin
- $hdrfrom_notify_release $hdrfrom_notify_report
- $notify_virus_admin_templ $notify_spam_admin_templ
- $notify_virus_recips_templ $notify_spam_recips_templ
- $notify_virus_sender_templ $notify_spam_sender_templ
- $notify_sender_templ $notify_release_templ
- $notify_report_templ $notify_autoresp_templ
- $warnbannedsender $warnbadhsender
- $defang_virus $defang_banned $defang_spam
- $defang_bad_header $defang_undecipherable $defang_all
- $virus_quarantine_method $banned_files_quarantine_method
- $unchecked_quarantine_method $spam_quarantine_method
- $bad_header_quarantine_method $clean_quarantine_method
- $archive_quarantine_method
- @virus_quarantine_to_maps @banned_quarantine_to_maps
- @unchecked_quarantine_to_maps @spam_quarantine_to_maps
- @bad_header_quarantine_to_maps @clean_quarantine_to_maps
- @archive_quarantine_to_maps
- @virus_admin_maps @banned_admin_maps
- @spam_admin_maps @bad_header_admin_maps @spam_modifies_subj_maps
- @warnvirusrecip_maps @warnbannedrecip_maps @warnbadhrecip_maps
- @addr_extension_virus_maps @addr_extension_spam_maps
- @addr_extension_banned_maps @addr_extension_bad_header_maps
- )],
- 'legacy_confvars' =>
- # legacy variables, predeclared for compatibility of amavisd.conf
- # The rest of the program does not use them directly and they should
- # not be visible in other modules, but may be referenced through
- # @*_maps variables for backwards compatibility
- [qw(
- %local_domains @local_domains_acl $local_domains_re @mynetworks
- %bypass_virus_checks @bypass_virus_checks_acl $bypass_virus_checks_re
- %bypass_spam_checks @bypass_spam_checks_acl $bypass_spam_checks_re
- %bypass_banned_checks @bypass_banned_checks_acl $bypass_banned_checks_re
- %bypass_header_checks @bypass_header_checks_acl $bypass_header_checks_re
- %virus_lovers @virus_lovers_acl $virus_lovers_re
- %spam_lovers @spam_lovers_acl $spam_lovers_re
- %banned_files_lovers @banned_files_lovers_acl $banned_files_lovers_re
- %bad_header_lovers @bad_header_lovers_acl $bad_header_lovers_re
- %virus_admin %spam_admin
- $newvirus_admin $virus_admin $banned_admin $bad_header_admin $spam_admin
- $warnvirusrecip $warnbannedrecip $warnbadhrecip
- $virus_quarantine_to $banned_quarantine_to $unchecked_quarantine_to
- $spam_quarantine_to $spam_quarantine_bysender_to
- $bad_header_quarantine_to $clean_quarantine_to $archive_quarantine_to
- $keep_decoded_original_re $map_full_type_to_short_type_re
- $banned_filename_re $viruses_that_fake_sender_re
- $sa_tag_level_deflt $sa_tag2_level_deflt $sa_tag3_level_deflt
- $sa_kill_level_deflt
- $sa_quarantine_cutoff_level @spam_notifyadmin_cutoff_level_maps
- $sa_dsn_cutoff_level $sa_crediblefrom_dsn_cutoff_level
- $sa_spam_modifies_subj $sa_spam_subject_tag1 $sa_spam_subject_tag
- %whitelist_sender @whitelist_sender_acl $whitelist_sender_re
- %blacklist_sender @blacklist_sender_acl $blacklist_sender_re
- $addr_extension_virus $addr_extension_spam
- $addr_extension_banned $addr_extension_bad_header
- $sql_select_policy $sql_select_white_black_list
- $gets_addr_in_quoted_form @debug_sender_acl
- $arc $bzip2 $lzop $lha $unarj $gzip $uncompress $unfreeze
- $unrar $zoo $pax $cpio $ar $rpm2cpio $cabextract $ripole $tnef
- $gunzip $bunzip2 $unlzop $unstuff
- $SYSLOG_LEVEL $syslog_priority $append_header_fields_to_bottom
- $insert_received_line $notify_xmailer_header $relayhost_is_client
- $sa_spam_report_header $sa_auto_whitelist
- $warnvirussender $warnspamsender
- $enable_global_cache
- $virus_check_negative_ttl $virus_check_positive_ttl
- $spam_check_negative_ttl $spam_check_positive_ttl
- )],
- );
- Exporter::export_tags qw(dynamic_confvars confvars sa platform
- hidden_confvars legacy_dynamic_confvars legacy_confvars);
- 1;
- } # BEGIN
- use POSIX ();
- use Carp ();
- use Errno qw(ENOENT EACCES EBADF);
- use vars @EXPORT;
- sub c($); sub cr($); sub ca($); sub dkim_key($$$;@); # prototypes
- use subs qw(c cr ca dkim_key); # access subroutines to config vars and keys
- BEGIN { push(@EXPORT,qw(c cr ca dkim_key)) }
- # access to dynamic config variables, returns a scalar config variable value;
- # one level of indirection is allowed
- #
- sub c($) {
- my $var = $current_policy_bank{$_[0]};
- if (!defined $var) {
- my $name = $_[0];
- if (!exists $current_policy_bank{$name}) {
- Carp::croak(sprintf('No entry "%s" in policy bank "%s"',
- $name, $current_policy_bank{'policy_bank_name'}));
- }
- }
- my $r = ref $var;
- !$r ? $var : $r eq 'SCALAR' || $r eq 'REF' ? $$var : $var;
- }
- # return a ref to a config variable value, or undef if var is undefined
- #
- sub cr($) {
- my $var = $current_policy_bank{$_[0]};
- if (!defined $var) {
- my $name = $_[0];
- if (!exists $current_policy_bank{$name}) {
- Carp::croak(sprintf('No entry "%s" in policy bank "%s"',
- $name, $current_policy_bank{'policy_bank_name'}));
- }
- }
- !defined $var ? undef : !ref $var ? \$var : $var;
- }
- # return a ref to a config variable value (which is supposed to be an array),
- # converting undef to an empty array, and a scalar to a one-element array
- # if necessary
- #
- sub ca($) {
- my $var = $current_policy_bank{$_[0]};
- if (!defined $var) {
- my $name = $_[0];
- if (!exists $current_policy_bank{$name}) {
- Carp::croak(sprintf('No entry "%s" in policy bank "%s"',
- $name, $current_policy_bank{'policy_bank_name'}));
- }
- }
- !defined $var ? [] : !ref $var ? [$var] : $var;
- }
- sub deprecate_var($$$) {
- my($data_type, $var_name, $init_value) = @_;
- my $code = <<'EOD';
- tie(%n, '%p', %v) or die 'Tieing a variable %n failed';
- package %p;
- use strict; use Carp ();
- sub TIESCALAR { my($class,$val) = @_; bless \$val, $class }
- sub FETCH { my $self = shift; $$self }
- sub STORE { my($self,$newv) = @_; my $oldv = $$self;
- if ((defined $oldv || defined $newv) && (%t)) {
- Carp::carp('Variable %n was retired, changing its value has no effect.'
- . " See release notes.\n");
- }
- $$self = $newv;
- }
- 1;
- EOD
- if ($data_type eq 'bool') {
- $code =~ s{%t}'($oldv ? 1 : 0) != ($newv ? 1 : 0)'g;
- } elsif ($data_type eq 'num') {
- $code =~ s{%t}'!defined $oldv || !defined $newv || $oldv != $newv'g;
- } elsif ($data_type eq 'str') {
- $code =~ s{%t}'!defined $oldv || !defined $newv || $oldv ne $newv'g;
- } else {
- die "Error deprecating a variable $var_name: bad type $data_type";
- }
- $code =~ s/%n/$var_name/g;
- $code =~ s/%v/\$init_value/g;
- my $barename = $var_name;
- $barename =~ s/^[\$\@%&]//; $code =~ s/%p/Amavis::Deprecate::$barename/g;
- eval $code
- or do { chomp $@; die "Error deprecating a variable $var_name: $@" };
- }
- # Store a private DKIM signing key for a given domain and selector.
- # The argument $key can be a Mail::DKIM::PrivateKey object or a file
- # name containing a key in a PEM format (e.g. as generated by openssl).
- # For compatibility with dkim_milter the signing domain can include a '*'
- # as a wildcard - this is not recommended as this way amavisd could produce
- # signatures which have no corresponding public key published in DNS.
- # The proper way is to have one dkim_key entry for each published DNS RR.
- # Optional arguments can provide additional information about the resource
- # record (RR) of a public key, i.e. its options according to RFC 4871.
- # The subroutine is typically called from a configuration file, once for
- # each signing key available.
- #
- sub dkim_key($$$;@) {
- my($domain,$selector,$key) = @_; shift; shift; shift;
- @_%2 == 0 or die "dkim_key: a list of key/value pairs expected as options\n";
- my(%key_options) = @_; # remaining args are options from a public key RR
- defined $domain && $domain ne ''
- or die "dkim_key: domain must not be empty: ($domain,$selector,$key)";
- defined $selector && $selector ne ''
- or die "dkim_key: selector must not be empty: ($domain,$selector,$key)";
- my $key_storage_ind;
- if (ref $key) { # key already preprocessed and provided as an object
- push(@dkim_signing_keys_storage, [$key]);
- $key_storage_ind = $#dkim_signing_keys_storage;
- } else { # assume a name of a file containing a private key in PEM format
- my $fname = $key;
- my $pem_fh = IO::File->new; # open a file with a private key
- $pem_fh->open($fname,'<') or die "Can't open PEM file $fname: $!";
- my(@stat_list) = stat($pem_fh); # soft-link friendly
- @stat_list or warn "Error accessing $fname: $!";
- my($dev,$inode) = @stat_list;
- if ($dev && $inode) {
- for my $j (0..$#dkim_signing_keys_storage) { # same file reused?
- my($k,$dv,$in,$fn) = @{$dkim_signing_keys_storage[$j]};
- if ($dv == $dev && $in == $inode) { $key_storage_ind = $j; last }
- }
- }
- if (!defined($key_storage_ind)) {
- # read file and store its contents as a new entry
- $key = ''; Amavis::Util::read_file($pem_fh,\$key);
- my $key_fit = $key; # shrink allocated storage size to actual size
- undef $key; # release storage
- push(@dkim_signing_keys_storage, [$key_fit, $dev, $inode, $fname]);
- $key_storage_ind = $#dkim_signing_keys_storage;
- }
- $pem_fh->close or die "Error closing file $fname: $!";
- $key_options{k} = 'rsa' if defined $key_options{k}; # force RSA
- }
- $domain = lc($domain) if !ref($domain); # possibly a regexp
- $selector = lc($selector);
- $key_options{domain} = $domain; $key_options{selector} = $selector;
- $key_options{key_storage_ind} = $key_storage_ind;
- if (@dkim_signing_keys_list > 100) {
- # sorry, skip the test to avoid slow O(n^2) searches
- } else {
- !grep($_->{domain} eq $domain && $_->{selector} eq $selector,
- @dkim_signing_keys_list)
- or die "dkim_key: selector $selector for domain $domain already in use\n";
- }
- $key_options{key_ind} = $#dkim_signing_keys_list + 1;
- push(@dkim_signing_keys_list, \%key_options); # using a list preserves order
- }
- # essential initializations, right at the program start time, may run as root!
- #
- use vars qw($read_config_files_depth @actual_config_files);
- BEGIN { # init_primary: version, $unicode_aware, base policy bank
- $myprogram_name = $0; # typically 'amavisd'
- local $1; $myprogram_name =~ s{([^/]*)\z}{$1}s;
- $myproduct_name = 'amavisd-new';
- $myversion_id = '2.8.0'; $myversion_date = '20120630';
- $myversion = "$myproduct_name-$myversion_id ($myversion_date)";
- $myversion_id_numeric = # x.yyyzzz, allows numerical compare, like Perl $]
- sprintf('%8.6f', $1 + ($2 + $3/1000)/1000)
- if $myversion_id =~ /^(\d+)(?:\.(\d*)(?:\.(\d*))?)?(.*)$/;
- $sql_schema_version = $myversion_id_numeric;
- $unicode_aware =
- $] >= 5.008 && length("\x{263a}")==1 && eval { require Encode };
- $read_config_files_depth = 0;
- eval { require Devel::SawAmpersand } or 1; # load if avail, ignore failure
- # initialize policy bank hash to contain dynamic config settings
- for my $tag (@EXPORT_TAGS{'dynamic_confvars', 'legacy_dynamic_confvars'}) {
- for my $v (@$tag) {
- local($1,$2);
- if ($v !~ /^([%\$\@])(.*)\z/) { die "Unsupported variable type: $v" }
- else {
- no strict 'refs'; my($type,$name) = ($1,$2);
- $current_policy_bank{$name} = $type eq '$' ? \${"Amavis::Conf::$name"}
- : $type eq '@' ? \@{"Amavis::Conf::$name"}
- : $type eq '%' ? \%{"Amavis::Conf::$name"}
- : undef;
- }
- }
- }
- $current_policy_bank{'policy_bank_name'} = ''; # builtin policy
- $current_policy_bank{'policy_bank_path'} = '';
- $policy_bank{''} = { %current_policy_bank }; # copy
- 1;
- } # end BEGIN - init_primary
- # boot-time initializations of simple global settings, may run as root!
- #
- BEGIN {
- # serves only as a quick default for other configuration settings
- $MYHOME = '/var/amavis';
- $mydomain = '!change-mydomain-variable!.example.com';#intentionally bad deflt
- # Create debugging output - true: log to stderr; false: log to syslog/file
- $DEBUG = 0;
- # In case of trouble, allow preserving temporary files for forensics
- $allow_preserving_evidence = 1;
- # Cause Net::Server parameters 'background' and 'setsid' to be set,
- # resulting in the program to detach itself from the terminal
- $daemonize = 1;
- # Net::Server pre-forking settings - defaults, overruled by amavisd.conf
- $max_servers = 2; # number of pre-forked children
- $max_requests = 20; # retire a child after that many accepts, 0=unlimited
- # timeout for our processing:
- $child_timeout = 8*60; # abort child if it does not complete a task in n sec
- # timeout for waiting on client input:
- $smtpd_timeout = 8*60; # disconnect session if client is idle for too long;
- # $smtpd_timeout should be higher than Postfix's max_idle (default 100s)
- # Assume STDIN is a courierfilter pipe and shutdown when it becomes readable
- $courierfilter_shutdown = 0;
- # Can file be truncated?
- # Set to 1 if 'truncate' works (it is XPG4-UNIX standard feature,
- # not required by Posix).
- # Things will go faster with SMTP-in, otherwise (e.g. with milter)
- # it makes no difference as file truncation will not be used.
- $can_truncate = 1;
- # Customizable notification messages, logging
- $syslog_ident = 'amavis';
- $syslog_facility = 'mail';
- $log_level = 0;
- # should be less than (1023 - prefix), i.e. 980,
- # to avoid syslog truncating lines; see sub write_log
- $logline_maxlen = 980;
- $nanny_details_level = 1; # register_proc verbosity: 0, 1, 2
- # $inner_sock_specs in amavis-services should match one of the sockets
- # in the @zmq_sockets list
- # @zmq_sockets = ( "ipc://$MYHOME/amavisd-zmq.sock" ); # after-default
- # $enable_zmq = undef; # load optional module Amavis::ZMQ
- # # (interface to 0MQ or Crossroads I/O)
- # $enable_db = undef; # load optional modules Amavis::DB & Amavis::DB::SNMP
- # $enable_dkim_signing = undef;
- # $enable_dkim_verification = undef;
- $reputation_factor = 0.2; # a value between 0 and 1, controlling the amount
- # of 'bending' of a calculated spam score towards a fixed score assigned
- # to a signing domain (its 'reputation') through @signer_reputation_maps;
- # the formula is: adjusted_spam_score = f*reputation + (1-f)*spam_score;
- # which has the same semantics as auto_whitelist_factor in SpamAssassin AWL
- $database_sessions_persistent = 1; # keep SQL & LDAP sessions open when idle
- $lookup_maps_imply_sql_and_ldap = 1; # set to 0 to disable
- # Algorithm name for generating a mail header digest and a mail body digest:
- # either 'MD5' (will use Digest::MD5, fastest and smallest digest), or
- # anything else accepted by Digest::SHA->new(), e.g. 'SHA-1' or 'SHA-256'.
- # The generated digest may end up as part of a quarantine file name
- # or via macro %b in log or notification templates.
- #
- $mail_digest_algorithm = 'MD5'; # or 'SHA-1' or 'SHA-256', ...
- # Where to find SQL server(s) and database to support SQL lookups?
- # A list of triples: (dsn,user,passw). Specify more than one
- # for multiple (backup) SQL servers.
- #
- #@storage_sql_dsn =
- #@lookup_sql_dsn =
- # ( ['DBI:mysql:mail:host1', 'some-username1', 'some-password1'],
- # ['DBI:mysql:mail:host2', 'some-username2', 'some-password2'] );
- # Does a database mail address field with no '@' character represent a
- # local username or a domain name? By default it implies a username in
- # SQL and LDAP lookups (but represents a domain in hash and acl lookups),
- # so domain names in SQL and LDAP should be specified as '@domain'.
- # Setting these to true will cause 'xxx' to be interpreted as a domain
- # name, just like in hash or acl lookups.
- #
- $sql_lookups_no_at_means_domain = 0;
- $ldap_lookups_no_at_means_domain = 0;
- # Maximum size (in bytes) for data written to a field 'quarantine.mail_text'
- # when quarantining to SQL. Must not exceed size allowed for a data type
- # on a given SQL server. It also determines a buffer size in amavisd.
- # Too large a value may exceed process virtual memory limits or just waste
- # memory, too small a value splits large mail into too many chunks, which
- # may be less efficient to process.
- #
- $sql_quarantine_chunksize_max = 16384;
- $sql_allow_8bit_address = 0;
- # the length of mail_id in bits, must be an integral multiple of 24
- # (i.e. divisible by 6 and 8); the mail_id is represented externally
- # as a base64url-encoded string of size $mail_id_size_bits / 6
- #
- $mail_id_size_bits = 72; # 24, 48, 72, 96
- $sql_store_info_for_all_msgs = 1;
- $penpals_bonus_score = undef; # maximal (positive) score value by which spam
- # score is lowered when sender is known to have previously received mail
- # from our local user from this mail system. Zero or undef disables
- # pen pals lookups in SQL tables msgs and msgrcpt, and is a default.
- $penpals_halflife = 7*24*60*60; # exponential decay time constant in seconds;
- # pen pal bonus is halved for each halflife period since the last mail
- # sent by a local user to a current message's sender
- $penpals_threshold_low = 1.0; # SA score below which pen pals lookups are
- # not performed to save time; undef lets the threshold be ignored;
- $penpals_threshold_high = undef;
- # when (SA_score - $penpals_bonus_score > $penpals_threshold_high)
- # pen pals lookup will not be performed to save time, as it could not
- # influence blocking of spam even at maximal penpals bonus (age=0);
- # usual choice for value would be kill level or other reasonably high
- # value; undef lets the threshold be ignored and is a default (useful
- # for testing and statistics gathering);
- $bounce_killer_score = 0;
- #
- # Receiving mail related
- # $unix_socketname = '/var/amavis/amavisd.sock'; # e.g. milter or release
- # $inet_socket_port = 10024; # accept SMTP on this TCP port
- # $inet_socket_port = [10024,10026,10027]; # ...possibly on more than one
- $AF_INET6 = eval { require Socket; Socket::AF_INET6() } ||
- eval { require Socket6; Socket6::AF_INET6() };
- # prefer using IO::Socket::IP if it exists, otherwise
- # fall back to IO::Socket::INET6 or IO::Socket::INET as appropriate
- #
- $have_socket_ip = eval {
- require IO::Socket::IP;
- };
- $have_inet4 = # can we make a PF_INET socket?
- $have_socket_ip ? eval {
- my $sock = IO::Socket::IP->new(LocalAddr => '0.0.0.0', Proto => 'udp');
- $sock->close or die "error closing inet6 socket: $!" if $sock;
- $sock ? 1 : undef;
- } : eval {
- require IO::Socket::INET;
- my $sock = IO::Socket::INET->new(LocalAddr => '0.0.0.0', Proto => 'udp');
- $sock->close or die "error closing inet socket: $!" if $sock;
- $sock ? 1 : undef;
- };
- $have_inet6 = # can we make a PF_INET6 socket?
- $have_socket_ip ? eval {
- my $sock = IO::Socket::IP->new(LocalAddr => '::', Proto => 'udp');
- $sock->close or die "error closing inet6 socket: $!" if $sock;
- $sock ? 1 : undef;
- } : eval {
- require IO::Socket::INET6;
- my $sock = IO::Socket::INET6->new(LocalAddr => '::', Proto => 'udp');
- $sock->close or die "error closing inet6 socket: $!" if $sock;
- $sock ? 1 : undef;
- };
- # bind socket to a loopback interface
- if (Net::Server->VERSION < 2) {
- $inet_socket_bind = '127.0.0.1';
- } else { # requires Net::Server 2 or a patched 0.99 with IPv6 support)
- $inet_socket_bind = $have_inet4 && $have_inet6 ? ['127.0.0.1', '[::1]']
- : $have_inet6 ? '[::1]' : '127.0.0.1';
- }
- @inet_acl = qw( 127.0.0.1 [::1] ); # allow SMTP access only from localhost
- @mynetworks = qw( 127.0.0.0/8 [::1] [FE80::]/10 [FEC0::]/10
- 10.0.0.0/8 172.16.0.0/12 192.168.0.0/16 169.254.0.0/16 );
- $originating = 0; # a boolean, initially reflects @mynetworks,
- # but may be modified later through a policy bank
- $forward_method = $have_inet6 && !$have_inet4 ? 'smtp:[::1]:10025'
- : 'smtp:[127.0.0.1]:10025';
- $notify_method = $forward_method;
- $resend_method = undef; # overrides $forward_method on defanging if nonempty
- $release_method = undef; # overrides $notify_method on releasing
- # from quarantine if nonempty
- $requeue_method = # requeuing release from a quarantine
- $have_inet6 && !$have_inet4 ? 'smtp:[::1]:25' : 'smtp:[127.0.0.1]:25';
- $release_format = 'resend'; # (dsn), (arf), attach, plain, resend
- $report_format = 'arf'; # (dsn), arf, attach, plain, resend
- # when $release_format is 'attach', the following control the attachment:
- $attachment_password = ''; # '': no pwd; undef: PIN; code ref; or static str
- $attachment_email_name = 'msg-%m.eml';
- $attachment_outer_name = 'msg-%m.zip';
- $virus_quarantine_method = 'local:virus-%m';
- $banned_files_quarantine_method = 'local:banned-%m';
- $spam_quarantine_method = 'local:spam-%m.gz';
- $bad_header_quarantine_method = 'local:badh-%m';
- $unchecked_quarantine_method = undef; # 'local:unchecked-%m';
- $clean_quarantine_method = undef; # 'local:clean-%m';
- $archive_quarantine_method = undef; # 'local:archive-%m.gz';
- $prepend_header_fields_hdridx = 0; # normally 0, use 1 for co-existence
- # with signing DK and DKIM milters
- $remove_existing_x_scanned_headers = 0;
- $remove_existing_spam_headers = 1;
- # fix improper header fields in passed or released mail - this setting
- # is a pre-condition for $allow_fixing_improper_header_folding and similar
- # (future) fixups; (desirable, but may break DKIM validation of messages
- # with illegal header section)
- $allow_fixing_improper_header = 1;
- # fix improper folded header fields made up entirely of whitespace, by
- # removing all-whitespace lines ($allow_fixing_improper_header must be true)
- $allow_fixing_improper_header_folding = 1;
- # truncate header section lines longer than 998 characters as limited
- # by the RFC 5322 ($allow_fixing_improper_header must be true)
- $allow_fixing_long_header_lines = 1;
- # encoding (charset in MIME terminology)
- # to be used in RFC 2047-encoded ...
- # $hdr_encoding = 'iso-8859-1'; # ... header field bodies
- # $bdy_encoding = 'iso-8859-1'; # ... notification body text
- $hdr_encoding = 'UTF-8'; # ... header field bodies
- $bdy_encoding = 'UTF-8'; # ... notification body text
- # encoding (encoding in MIME terminology)
- $hdr_encoding_qb = 'Q'; # quoted-printable (default)
- #$hdr_encoding_qb = 'B'; # base64 (usual for far east charsets)
- $smtpd_recipient_limit = 1100; # max recipients (RCPT TO) - sanity limit
- # $myhostname is used by SMTP server module in the initial SMTP welcome line,
- # in inserted Received: lines, Message-ID in notifications, log entries, ...
- $myhostname = (POSIX::uname)[1]; # should be a FQDN !
- $snmp_contact = ''; # a value of sysContact OID
- $snmp_location = ''; # a value of sysLocation OID
- $smtpd_greeting_banner = '${helo-name} ${protocol} ${product} service ready';
- $smtpd_quit_banner = '${helo-name} ${product} closing transmission channel';
- $enforce_smtpd_message_size_limit_64kb_min = 1;
- # $localhost_name is the name of THIS host running amavisd
- # (typically 'localhost'). It is used in HELO SMTP command
- # when reinjecting mail back to MTA via SMTP for final delivery,
- # and in inserted Received header field
- $localhost_name = 'localhost';
- $propagate_dsn_if_possible = 1; # pass on DSN if MTA announces this
- # capability; useful to be turned off globally but enabled in
- # MYNETS policy bank to hide internal mail routing from outsiders
- $terminate_dsn_on_notify_success = 0; # when true=>handle DSN NOTIFY=SUCCESS
- # locally, do not let NOTIFY=SUCCESS propagate to MTA (but allow
- # other DSN options like NOTIFY=NEVER/FAILURE/DELAY, ORCPT, RET,
- # and ENVID to propagate if possible)
- #@auth_mech_avail = ('PLAIN','LOGIN'); # empty list disables incoming AUTH
- #$auth_required_inp = 1; # incoming SMTP authentication required by amavisd?
- #$auth_required_out = 1; # SMTP authentication required by MTA
- $auth_required_release = 1; # secret_id is required for a quarantine release
- $tls_security_level_in = undef; # undef, 'may', 'encrypt', ...
- $tls_security_level_out = undef; # undef, 'may', 'encrypt', ...
- $smtpd_tls_cert_file = undef; # e.g. "$MYHOME/cert/amavisd-cert.pem"
- $smtpd_tls_key_file = undef; # e.g. "$MYHOME/cert/amavisd-key.pem"
- # SMTP AUTH username and password for notification submissions
- # (and reauthentication of forwarded mail if requested)
- #$amavis_auth_user = undef; # perhaps: 'amavisd'
- #$amavis_auth_pass = undef;
- #$auth_reauthenticate_forwarded = undef; # supply our own credentials also
- # for forwarded (passed) mail
- $smtp_connection_cache_on_demand = 1;
- $smtp_connection_cache_enable = 1;
- # whom quarantined messages appear to be sent from (envelope sender)
- # $mailfrom_to_quarantine = undef; # orig. sender if undef, or set explicitly
- # where to send quarantined malware - specify undef to disable, or an
- # e-mail address containing '@', or just a local part, which will be
- # mapped by %local_delivery_aliases into local mailbox name or directory.
- # The lookup key is a recipient address
- $virus_quarantine_to = 'virus-quarantine';
- $banned_quarantine_to = 'banned-quarantine';
- $unchecked_quarantine_to = 'unchecked-quarantine';
- $spam_quarantine_to = 'spam-quarantine';
- $bad_header_quarantine_to = 'bad-header-quarantine';
- $clean_quarantine_to = 'clean-quarantine';
- $archive_quarantine_to = 'archive-quarantine';
- # similar to $spam_quarantine_to, but the lookup key is the sender address:
- $spam_quarantine_bysender_to = undef; # dflt: no by-sender spam quarantine
- # quarantine directory or mailbox file or empty
- # (only used if $*_quarantine_to specifies direct local delivery)
- $QUARANTINEDIR = undef; # no quarantine unless overridden by config
- $undecipherable_subject_tag = '***UNCHECKED*** ';
- # NOTE: all entries can accept mail_body_size_limit and score_factor options
- @spam_scanners = (
- ['SpamAssassin', 'Amavis::SpamControl::SpamAssassin' ],
- # ['SpamdClient', 'Amavis::SpamControl::SpamdClient',
- # mail_body_size_limit => 65000, score_factor => 1.0,
- # ],
- # ['DSPAM', 'Amavis::SpamControl::ExtProg', $dspam,
- # [ qw(--stdout --classify --deliver=innocent,spam
- # --mode=toe --feature noise
- # --user), $daemon_user ],
- # mail_body_size_limit => 65000, score_factor => 1.0,
- # ],
- # ['CRM114', 'Amavis::SpamControl::ExtProg', 'crm',
- # [ qw(-u /var/amavis/home/.crm114 mailreaver.crm
- # --dontstore --report_only --stats_only
- # --good_threshold=10 --spam_threshold=-10) ],
- # mail_body_size_limit => 65000, score_factor => -0.20,
- # lock_file => '/var/amavis/crm114.lock',
- # lock_type => 'shared', learner_lock_type => 'exclusive',
- # ],
- # ['Bogofilter', 'Amavis::SpamControl::ExtProg', 'bogofilter',
- # [ qw(-e -v)], # -u
- # mail_body_size_limit => 65000, score_factor => 1.0,
- # ],
- );
- $sa_spawned = 0; # true: run SA in a subprocess; false: call SA directly
- # string to prepend to Subject header field when message qualifies as spam
- # $sa_spam_subject_tag1 = undef; # example: '***Possible Spam*** '
- # $sa_spam_subject_tag = undef; # example: '***Spam*** '
- $sa_spam_level_char = '*'; # character to be used in X-Spam-Level bar;
- # empty or undef disables adding this header field
- $sa_num_instances = 1; # number of SA instances,
- # usually 1, memory-expensive, keep small
- $sa_local_tests_only = 0;
- $sa_debug = undef;
- $sa_timeout = 30; # no longer used since 2.6.5
- $file = 'file'; # path to the file(1) utility for classifying contents
- $altermime = 'altermime'; # path to the altermime utility (optional)
- @altermime_args_defang = qw(--verbose --removeall);
- @altermime_args_disclaimer = qw(--disclaimer=/etc/altermime-disclaimer.txt);
- # @altermime_args_disclaimer =
- # qw(--disclaimer=/etc/_OPTION_.txt --disclaimer-html=/etc/_OPTION_.html);
- # @disclaimer_options_bysender_maps = ( 'altermime-disclaimer' );
- $MIN_EXPANSION_FACTOR = 5; # times original mail size
- $MAX_EXPANSION_FACTOR = 500; # times original mail size
- # See amavisd.conf and README.lookups for details.
- # What to do with the message (this is independent of quarantining):
- # Reject: tell MTA to generate a non-delivery notification, MTA gets 5xx
- # Bounce: generate a non-delivery notification by ourselves, MTA gets 250
- # Discard: drop the message and pretend it was delivered, MTA gets 250
- # Pass: accept/forward a message, MTA gets 250
- # TempFail: temporary failure, client should retry, MTA gets 4xx
- #
- # COMPATIBILITY NOTE: the separation of *_destiny values into
- # D_BOUNCE, D_REJECT, D_DISCARD and D_PASS made settings $warn*sender only
- # still useful with D_PASS. The combination of D_DISCARD + $warn*sender=1
- # is mapped into D_BOUNCE for compatibility.
- # The following symbolic constants can be used in *destiny settings:
- #
- # D_PASS mail will pass to recipients, regardless of contents;
- #
- # D_DISCARD mail will not be delivered to its recipients, sender will NOT be
- # notified. Effectively we lose mail (but it will be quarantined
- # unless disabled).
- #
- # D_BOUNCE mail will not be delivered to its recipients, a non-delivery
- # notification (bounce) will be sent to the sender by amavisd-new
- # (unless suppressed). Bounce (DSN) will not be sent if a virus
- # name matches $viruses_that_fake_sender_maps, or to messages
- # from mailing lists (Precedence: bulk|list|junk), or for spam
- # exceeding spam_dsn_cutoff_level
- #
- # D_REJECT mail will not be delivered to its recipients, amavisd will
- # return a 5xx status response. Depending on an MTA/amavisd setup
- # this will result either in a reject status passed back to a
- # connecting SMTP client (in a pre-queue setup: proxy or milter),
- # or an MTA will generate a bounce in a post-queue setup.
- # If not all recipients agree on rejecting a message (like when
- # different recipients have different thresholds on bad mail
- # contents and LMTP is not used) amavisd sends a bounce by itself
- # (same as D_BOUNCE).
- #
- # D_TEMPFAIL indicates a temporary failure, mail will not be delivered to
- # its recipients, sender should retry the operation later.
- #
- # Notes:
- # D_REJECT and D_BOUNCE are similar,the difference is in who is responsible
- # for informing the sender about non-delivery, and how informative
- # the notification can be (amavisd-new knows more than MTA);
- # With D_REJECT, MTA may reject original SMTP, or send DSN (delivery status
- # notification, colloquially called 'bounce') - depending on MTA
- # and its interface to a content checker; best suited for sendmail
- # milter or other pre-queue filtering …
Large files files are truncated, but you can click here to view the full file