initial commit of a *whole bunch* of old Egressive shell scripts, used to make many people redundant.

This commit is contained in:
Dave Lane 2016-03-16 13:43:31 +13:00
commit 43e0f5b59e
329 changed files with 31937 additions and 0 deletions

View file

@ -0,0 +1,20 @@
$TTL 86400
DOMAIN.CO.NZ. IN SOA ns1.DOMAIN.CO.NZ. support@egressive.com. (
2007052001 ; Serial
604800 ; Refresh
86400 ; Retry
2419200 ; Expire
86400 ) ; Negative Cache TTL
;
NS ns1.DOMAIN.CO.NZ.
;
MX 5 mail.DOMAIN.CO.NZ.
;
DOMAIN.CO.NZ. IN A 192.168.1.1
ns1 IN A 192.168.1.1
mail IN A 192.168.1.1
;
server CNAME DOMAIN.CO.NZ.
www CNAME DOMAIN.CO.NZ.
webmail CNAME DOMAIN.CO.NZ.

View file

@ -0,0 +1,367 @@
# Syntax:
# loadplugin <Plugin_Name> <Location>
# <Location> path where Plugin resides.
loadplugin FuzzyOcr FuzzyOcr.pm
body FUZZY_OCR eval:fuzzyocr_check()
body FUZZY_OCR_WRONG_CTYPE eval:dummy_check()
body FUZZY_OCR_CORRUPT_IMG eval:dummy_check()
body FUZZY_OCR_WRONG_EXTENSION eval:dummy_check()
body FUZZY_OCR_KNOWN_HASH eval:dummy_check()
describe FUZZY_OCR Mail contains an image with common spam text inside
describe FUZZY_OCR_WRONG_CTYPE Mail contains an image with wrong content-type set
describe FUZZY_OCR_WRONG_EXTENSION Mail contains an image with wrong file extension
describe FUZZY_OCR_CORRUPT_IMG Mail contains a corrupted image
describe FUZZY_OCR_KNOWN_HASH Mail contains an image with known hash
priority FUZZY_OCR 900
###
### Plugin Configuration
###
###
### Logging options
###
# Verbosity level (see manual)
# Level 0 - Errors only
# Level 1 - Errors and Warnings
# Level 2 - Errors, Warnings and Info Messages
# Level 3 - Full debug output
# Default value: 1
focr_verbose 3
# Log Message-Id, From, To
# Default: 1
#focr_log_pmsinfo 0
# Send logging output to stderr.
# Default value: 1
#focr_log_stderr 0
# Logfile (make sure it is writable by the plugin)
# Default value: none
#focr_logfile /tmp/FuzzyOcr.log
focr_logfile /var/spool/MailScanner/spamassassin/FuzzyOcr.log
###
### Wordlists
###
# Here we defined the words to scan for
# Default value: /etc/mail/spamassassin/FuzzyOcr.words
#focr_global_wordlist /etc/mail/spamassassin/FuzzyOcr.words
#
# This is the path RELATIVE to the respective home directory
# for the personalized list. This list is merged with the global
# word list on execution.
# Default value: ~/.spamassassin/fuzzyocr.words
# If value begins with '/', it is treated as fixed path.
#focr_personal_wordlist fuzzyocr.words
#
# This option allows you to disable the whole personalization stuff,
# i.e. FuzzyOcr will not call functions in SA that require home
# directories for your users. This is only required if you are running
# an environment where the users don't have home directories at all.
# Default value: 0
#
#focr_no_homedirs 1
#
## Optionally, disable this option if you want to scan for numbers
## Setting this to 0 will cause FuzzyOcr not to strip numbers from
## both the wordlist and the OCR results
#
#focr_strip_numbers 1
###
### Helper Applications
###
# These parameters can be used to change other detection settings
# If you leave these commented out, the defaults will be used.
# Do not use " " around any parameters!
###
### Step 1:
### Inform the plugin which helper apps are required.
###
# The following are already included by default:
#
#focr_bin_helper gifsicle, giffix, giftext, gifinter, giftopnm
#focr_bin_helper jpegtopnm, pngtopnm, bmptopnm, tifftopnm, ppmhist
#focr_bin_helper gocr, ocrad
# Include additional scanner/preprocessor commands here:
#
#focr_bin_helper pnmnorm, pnminvert, pamthreshold, ppmtopgm, pamtopnm
#focr_bin_helper tesseract
focr_bin_helper pnmnorm, pnminvert, ppmtopgm
###
### Step 2:
### Inform the plugin of the search path to find all helper apps.
### Only the first match will be considered, so the order is important.
###
# Search path for locating helper applications
#focr_path_bin /usr/local/netpbm/bin:/usr/local/bin:/usr/bin
focr_path_bin /usr/local/netpbm/bin:/usr/local/bin:/usr/bin
###
### Step 3:
### You can optionally define a helper application location, bypassing
### the search path algorithm. Please note that if the helper app is not
### previously defined, it will generate an error:
#focr_bin_gifsicle /usr/bin/gifsicle
#focr_bin_giffix /usr/bin/giffix
#focr_bin_giftext /usr/bin/giftext
#focr_bin_gifinter /usr/bin/gifinter
#focr_bin_giftopnm /usr/bin/giftopnm
#focr_bin_jpegtopnm /usr/bin/jpegtopnm
#focr_bin_pngtopnm /usr/bin/pngtopnm
#focr_bin_bmptopnm /usr/bin/bmptopnm
#focr_bin_tifftopnm /usr/bin/tifftopnm
#focr_bin_ppmhist /usr/bin/ppmhist
#focr_bin_gocr /usr/bin/gocr
#focr_bin_ocrad /usr/bin/ocrad
#focr_bin_pnmnorm /usr/bin/pnmnorm
#focr_bin_pnminvert /usr/bin/pnminvert
#focr_bin_convert /usr/bin/convert
###
### Scansets
###
# Paths to the files containing Scansets and Preprocessors definitions
#
#focr_preprocessor_file /etc/mail/spamassassin/FuzzyOcr.preps
#focr_scanset_file /etc/mail/spamassassin/FuzzyOcr.scansets
# Setting this to 1 will cause FuzzyOcr to skip all other scansets,
# if a scanset has reached the amount of hits specified in
# focr_counts_required. (i.e. if the image is detected as spam).
# This saves resources, but lowers the scores because not the best,
# but the first best scanset is taken as result.
# Default value: 1
#focr_minimal_scanset 0
# This option is only used when focr_minimal_scanset is enabled.
# Basically, this counts the effectiveness of a scanset on the current
# mail traffic and resorts the scansets with the most effective first.
# This saves unnecessary scanner passes and saves resources.
# Default value: 1.
#focr_autosort_scanset 0
# This is a parameter for the focr_autosort_scanset function, and specifies
# the maximum value of the effectiveness counter used in each scanset. If you
# increase this, it will take longer until the autosort function adapts to new
# types of spam, setting it too low will lower the effectiveness of the
# function.
# Default value: 10
#focr_autosort_buffer 10
###
### Scan Settings
###
# Timeout for the plugin, in seconds. (Maximum runtime of the plugin)
# Default value: 10
#focr_timeout 15
# Use a global timeout value instead of per helper application.
# Default value: 0
#focr_global_timeout 1
# Minimum image size to scan. Images with dimensions smaller than the
# ones specified here will be skipped:
# Default: Height:4 Width:4
#
#focr_min_height 4
#focr_min_width 4
# Maximum image size to scan. Images with dimensions bigger than the
# ones specified here will be skipped:
# Default: Height:800 Width:800
#
#focr_max_height 800
#focr_max_width 800
# Maximum file size for different formats in byte, bigger pictures
# will not be scanned
# Default values: Unlimited)
#focr_max_size_gif 80000
#focr_max_size_jpeg 100000
#focr_max_size_png 80000
#focr_max_size_bmp 500000
#focr_max_size_tiff 500000
# Skip checking the following image types
# Default value: 0 (check image type)
#focr_skip_gif 1
#focr_skip_jpeg 1
#focr_skip_png 1
#focr_skip_bmp 1
#focr_skip_tiff 1
# Default detection treshold (see manual)
# Default value: 0.25 (Can be changed on a per word basis in the wordlist).
#focr_threshold 0.20
# Number of minimum matches before the rule scores (Default value: 2)
#focr_counts_required 3
# Setting this will cause every word to be matched only once per image (Default value: 0)
#focr_unique_matches 1
# This is the score for a hit after focr_counts_required matches
# Default value: 5
#focr_base_score 5
# This is the additional score for every additional match after
# focr_counts_required matches
# Default value: 1
#focr_add_score 0.375
# This option defines the factor, which is multiplied with the number
# of matches, that were made without stripping spaces. FuzzyOcr does two
# matching attempts on OCR results, one without space strippings and one with.
# To weight the first match type more, this factor is applied.
# Default value: 1.5
#focr_twopass_scoring_factor 1.5
# This is the score to give for a wrong content-type.
# e.g. JPEG image but content type says GIF
# Default value: 1.5
#focr_wrongctype_score 1.5
# This is the score to give for a wrong file extension.
# e.g. JPEG image but file extension says GIF
# Default value: 1.5
#focr_wrongext_score 1.5
# This is the score to give for a corrupted image.
# This currently affects only GIF images
# Default value: 2.5
#focr_corrupt_score 2.5
# This is the score to give for a corrupted unfixable image.
# This currently affects only GIF images.
# Default value: 5
#focr_corrupt_unfixable_score 5
# This is used to disable the OCR engine if the message has
# already more points than this value
# Default value: 10
#focr_autodisable_score 30
# This is used to disable the OCR engine if the message has
# already less points than this value
# Default value: -5
#focr_autodisable_negative_score -5
###
### Hashing Options (Optional)
###
# Select which type of image hashing to use:
# Default value: 0 (disabled)
# Allowed values:
# 1 ... use digest_hash only (deprecated)
# 2 ... use digest_db w/digest_hash import (see requirements, recommended)
# 3 ... use mysql database (see requirements, experimental)
#--
# The score is saved with the hash in the database, allowing the plugin to
# skip the scans when the image is found in the database, using the score
# from the previous scans.
#--
#focr_enable_image_hashing 3
focr_enable_image_hashing 2
# Set this to skip updating the hashing database at startup
# Default value: 0 (update at startup)
#focr_skip_updates 1
# Automatically add hashes of spam images recognized by OCR to the Image
# Hash database, to disable, set to 0
# Default value: 1 (learn)
#focr_hashing_learn_scanned 1
# Score images who's global word count is below focr_counts_required using
# the following formulae: (focr_add_score * word count) as score.
# Default value: 0 (ignore images)
#focr_score_ham 1
# If the image hash database feature is enabled (Type 1 Hashing),
# specify the file to use as database
# Default value: /etc/mail/spamassassin/FuzzyOcr.hashdb
#focr_digest_db /etc/mail/spamassassin/FuzzyOcr.hashdb
# If the image hash db feature is enabled (Type 2 Hashing),
# specify the file to use as the SPAM database
# Default value: /etc/mail/spamassassin/FuzzyOcr.db
#focr_db_hash /etc/mail/spamassassin/FuzzyOcr.db
focr_db_hash /var/spool/MailScanner/spamassassin/FuzzyOcr.db
# If the image hash db feature is enabled (Type 2 Hashing),
# specify the file to use as the HAM database
# Default value: /etc/mail/spamassassin/FuzzyOcr.safe.db
#focr_db_safe /etc/mail/spamassassin/FuzzyOcr.safe.db
focr_db_safe /var/spool/MailScanner/spamassassin/FuzzyOcr.safe.db
# Auto-prune: Expire records from hasing databases after these many days
# Default value: 35
#focr_db_max_days 15
###
### MySQL options (Type 3 Hashing)
###
#focr_mysql_db FuzzyOcr
#focr_mysql_hash Hash
#focr_mysql_safe Safe
#focr_mysql_user fuzzyocr
#focr_mysql_pass fuzzyocr
#focr_mysql_host localhost
#focr_mysql_port 3306
#focr_mysql_socket /tmp/mysql.sock
# If set, the database table is updated with different data from one of
# the following:
# + filename,
# + image-params,
# + content-type,
# + file-type,
# + score,
# + word-info
# Default value: 0
#focr_mysql_update_hash 1
###
### Miscellaneous Options
###
# The pluging uses a temporary directory to store intermediate information.
# In order to Keep these files for debugging purposes use any of these
# values:
# 0 = always cleanup (default value)
# 1 = keep only if error
# 2 = always keep
#--
# Keeping these intermediate files could fill your HDD _very_ fast!
# Make shure you periodically empty your temp dir (usually: /tmp) or
# suffer the conscecuences. You've been warned!!
#--
#focr_keep_bad_images 1
#################################################################
# DO NOT REMOVE THIS LINE, IT IS REQUIRED UNDER ALL CIRCUMSTANCES
focr_end_config

View file

@ -0,0 +1,952 @@
# FuzzyOcr plugin, version 3.4
#
# written by Christian Holler (decoder_at_own-hero_dot_net)
# and Jorge Valdes (jorge_at_joval_dot_info)
package FuzzyOcr;
use strict;
use warnings;
use Mail::SpamAssassin;
use Mail::SpamAssassin::Logger;
use Mail::SpamAssassin::Util;
use Mail::SpamAssassin::Timeout;
use Mail::SpamAssassin::Plugin;
use Time::HiRes qw( gettimeofday tv_interval );
use String::Approx 'adistr';
use FileHandle;
# added rob@egressive.com 20070603
use File::Temp qw/ tempfile tempdir /;
use Fcntl ':flock';
use POSIX;
use lib qw(/etc/mail/spamassassin); # Allow placing of FuzzyOcr in siteconfigdir
use FuzzyOcr::Logging qw(debuglog errorlog warnlog infolog);
use FuzzyOcr::Config qw(kill_pid
get_tmpdir
set_tmpdir
get_all_tmpdirs
get_pms
save_pms
get_timeout
get_mysql_ddb
get_scansets
get_wordlist
set_config
get_config
parse_config
finish_parsing_end
read_words);
use FuzzyOcr::Hashing qw(check_image_hash_db add_image_hash_db calc_image_hash);
use FuzzyOcr::Deanimate qw(deanimate);
use FuzzyOcr::Scoring qw(wrong_ctype wrong_extension corrupt_img known_img_hash);
use FuzzyOcr::Misc qw(max removedir removedirs save_execute);
our @ISA = qw(Mail::SpamAssassin::Plugin);
# constructor: register the eval rule
sub new {
my ( $class, $mailsa ) = @_;
$class = ref($class) || $class;
my $self = $class->SUPER::new($mailsa);
bless( $self, $class );
$self->register_eval_rule("fuzzyocr_check");
$self->register_eval_rule("dummy_check");
$self->set_config($mailsa->{conf});
return $self;
}
sub dummy_check {
return 0;
}
sub fuzzyocr_check {
my ( $self, $pms ) = @_;
my $conf = get_config();
save_pms($pms);
my $end;
my $begin = [gettimeofday];
if ($conf->{focr_global_timeout}) {
my $t = get_timeout();
debuglog("Global Timeout set at ".$conf->{focr_timeout}." sec.");
$t->run(sub {
$end = fuzzyocr_do( $self, $conf, $pms );
});
if ($t->timed_out()) {
infolog("Scan timed out after $conf->{focr_timeout} seconds.");
infolog("Killing possibly running pid...");
my ($ret, $pid) = kill_pid();
if ($ret > 0) {
infolog("Successfully killed PID $pid");
} elsif ($ret < 0) {
infolog("No processes left... exiting");
} else {
infolog("Failed to kill PID $pid, stale process!");
}
infolog("Removing possibly leftover tempdirs...");
removedirs(get_all_tmpdirs());
return 0;
}
} else {
$end = fuzzyocr_do( $self, $conf, $pms );
}
debuglog("Processed in ".
sprintf("%.6f",tv_interval($begin, [gettimeofday]))
." sec.");
return $end;
}
sub fuzzyocr_do {
my ( $self, $conf, $pms ) = @_;
my $internal_score = 0;
my $current_score = $pms->get_score();
my $score = $conf->{focr_autodisable_score} || 100;
if ( $current_score > $score ) {
infolog("Scan canceled, message has already more than $score points ($current_score).");
return 0;
}
my $nscore = $conf->{focr_autodisable_negative_score} || -100;
if ( $current_score < $nscore ) {
infolog("Scan canceled, message has less than $nscore points ($current_score).");
return 0;
}
my $imgdir;
my %imgfiles = ();
my @found = ();
my @hashes = ();
my $cnt = 0;
my $imgerr = 0;
my $main = $self->{main};
debuglog("Starting FuzzyOcr...");
#Show PMS info if asked to
if ($conf->{focr_log_pmsinfo}) {
my $msgid = $pms->get('Message-Id') ? $pms->get('Message-Id') : "<no messageid>";
my $from = $pms->get('From') ? $pms->get('From') : "<no sender>";
my $to = $pms->get('To') ? $pms->get('To') : "<no receipients>";
chomp($from, $to, $msgid);
infolog("Processing Message with ID \"$msgid\" ($from -> $to)");
}
foreach my $p (
$pms->{msg}->find_parts(qr(^image\b)i),
$pms->{msg}->find_parts(qr(Application/Octet-Stream)i)
) {
my $ctype = $p->{'type'};
my $fname = $p->{'name'} || 'unknown';
if (($fname eq 'unknown') and
(defined $p->{'headers'}->{'content-id'})
){
$fname = join('',@{$p->{'headers'}->{'content-id'}});
$fname =~ s/[<>]//g;
$fname =~ tr/\@\$\%\&/_/s;
}
my $filename = $fname; $filename =~ tr{a-zA-Z0-9\-.}{_}cs;
debuglog("fname: \"$fname\" => \"$filename\"");
my $pdata = $p->decode();
my $pdatalen = length($pdata);
my $w = 0; my $h = 0;
if ( substr($pdata,0,3) eq "\x47\x49\x46" ) {
## GIF File
$imgfiles{$filename}{ftype} = 1;
($w,$h) = unpack("vv",substr($pdata,6,4));
infolog("GIF: [${h}x${w}] $filename ($pdatalen)");
$imgfiles{$filename}{width} = $w;
$imgfiles{$filename}{height} = $h;
} elsif ( substr($pdata,0,2) eq "\xff\xd8" ) {
## JPEG File
my @Markers = (0xC0,0xC1,0xC2,0xC3,0xC5,0xC6,0xC7,0xC9,0xCA,0xCB,0xCD,0xCE,0xCF);
my $pos = 2;
while ($pos < $pdatalen) {
my ($b,$m) = unpack("CC",substr($pdata,$pos,2)); $pos += 2;
if ($b != 0xff) {
infolog("Invalid JPEG image");
$pos = $pdatalen + 1;
last;
}
my $skip = 0;
foreach my $mm (@Markers) {
if ($mm == $m) {
$skip++; last;
}
}
last if ($skip);
$pos += unpack("n",substr($pdata,$pos,2));
}
if ($pos > $pdatalen) {
errorlog("Cannot find image dimensions");
} else {
($h,$w) = unpack("nn",substr($pdata,$pos+3,4));
infolog("JPEG: [${h}x${w}] $filename ($pdatalen)");
$imgfiles{$filename}{ftype} = 2;
$imgfiles{$filename}{height} = $h;
$imgfiles{$filename}{width} = $w;
}
} elsif ( substr($pdata,0,4) eq "\x89\x50\x4e\x47" ) {
# PNG File
($w,$h) = unpack("NN",substr($pdata,16,8));
$imgfiles{$filename}{ftype} = 3;
$imgfiles{$filename}{width} = $w;
$imgfiles{$filename}{height} = $h;
infolog("PNG: [${h}x${w}] $filename ($pdatalen)");
} elsif ( substr($pdata,0,2) eq "BM" ) {
## BMP File
($w,$h) = unpack("VV",substr($pdata,18,8));
$imgfiles{$filename}{ftype} = 4;
$imgfiles{$filename}{width} = $w;
$imgfiles{$filename}{height} = $h;
infolog("BMP: [${h}x${w}] $filename ($pdatalen)");
} elsif (
## TIFF File
(substr($pdata,0,4) eq "\x4d\x4d\x00\x2a") or
(substr($pdata,0,4) eq "\x49\x49\x2a\x00")
) {
my $worder = (substr($pdata,0,2) eq "\x4d\x4d") ? 0 : 1;
my $offset = unpack($worder?"V":"N",substr($pdata,4,4));
my $number = unpack($worder?"v":"n",substr($pdata,$offset,2)) - 1;
foreach my $n (0 .. $number) {
my $add = 2 + ($n * 12);
my ($id,$tag,$cnt,$val) = unpack($worder?"vvVV":"nnNN",substr($pdata,$offset+$add,12));
$h = $val if ($id == 256);
$w = $val if ($id == 257);
last if ($h != 0 and $w != 0);
}
infolog("TIFF: [${h}x${w}] $filename ($pdatalen) ($worder)");
infolog("Cannot determine size of TIFF image, setting to '1x1'") if ($h == 0 and $w == 0);
$imgfiles{$filename}{ftype} = 5;
$imgfiles{$filename}{width} = $w ? $w : 1;
$imgfiles{$filename}{height} = $h ? $h : 1;
}
#Skip unless we found the right header
unless (defined $imgfiles{$filename}{ftype}) {
infolog("Skipping file with content-type=\"$ctype\" name=\"$fname\"");
delete $imgfiles{$filename};
next;
}
#Skip images that cannot contain text
if ($imgfiles{$filename}{height} < $conf->{focr_min_height}) {
infolog("Skipping image: height < $conf->{focr_min_height}");
delete $imgfiles{$filename};
next;
}
#Skip images that cannot contain text
if ($imgfiles{$filename}{width} < $conf->{focr_min_width}) {
infolog("Skipping image: width < $conf->{focr_min_width}");
delete $imgfiles{$filename};
next;
}
#Skip too big images, screenshots etc
if ($imgfiles{$filename}{height} > $conf->{focr_max_height}) {
infolog("Skipping image: height > $conf->{focr_max_height}");
delete $imgfiles{$filename};
next;
}
#Skip too big images, screenshots etc
if ($imgfiles{$filename}{width} > $conf->{focr_max_width}) {
infolog("Skipping image: width > $conf->{focr_max_width}");
delete $imgfiles{$filename};
next;
}
#Found Image!! Get a temporary dir to save image
# changed rob@egressive.com 20070218
#$imgdir = Mail::SpamAssassin::Util::secure_tmpdir();
$imgdir = File::Temp::mkdtemp('/tmp/focr.XXXX');
unless ($imgdir) {
errorlog("Scan canceled, cannot create Image TMPDIR.");
return 0;
}
set_tmpdir($imgdir);
#Generete unique filename to store image
my $imgfilename = Mail::SpamAssassin::Util::untaint_file_path(
$imgdir . "/" . $filename
);
my $unique = 0;
while (-e $imgfilename) {
$imgfilename = Mail::SpamAssassin::Util::untaint_file_path(
$imgdir . "/" . chr(65+$unique) . "." . $filename
);
$unique++;
}
#Save important constants
$imgfiles{$filename}{fname} = $fname;
$imgfiles{$filename}{ctype} = $ctype;
$imgfiles{$filename}{fsize} = $pdatalen;
$imgfiles{$filename}{fpath} = $imgfilename;
#Save Image to disk.
unless (open PICT, ">$imgfilename") {
errorlog("Cannot write \"$imgfilename\", skipping...");
delete $imgfiles{$filename};
removedir($imgdir);
next;
}
binmode PICT;
print PICT $pdata;
close PICT;
debuglog("Saved: $imgfilename");
#Increment valid image file counter
$cnt++;
#keep raw email for debugging later
my $rawfilename = $imgdir . "/raw.eml";
if (open RAW, ">$rawfilename") {
print RAW $pms->{msg}->get_pristine();
close RAW;
debuglog("Saved: $rawfilename");
}
}
if ($cnt == 0) {
debuglog("Skipping OCR, no image files found...");
return 0;
}
infolog("Found: $cnt images"); $cnt = 0;
if ($conf->{focr_enable_image_hashing} == 3) {
$conf->{focr_mysql_ddb} = get_mysql_ddb();
}
# Try to load personal wordlist
unless ($conf->{focr_no_homedirs}) {
if ($conf->{focr_personal_wordlist} =~ m/^\//) {
read_words( $conf->{focr_personal_wordlist} );
} else {
my $peruserlist = $main->sed_path($conf->{focr_personal_wordlist});
if ( -r $peruserlist ) {
read_words( $peruserlist );
} else {
# Only complain if the file exists
if ( -e $peruserlist ) {
errorlog("Cannot read personal_wordlist: $peruserlist, skipping...");
}
}
}
}
my $haserr;
foreach my $filename (keys %imgfiles) {
my $pic = $imgfiles{$filename};
#infolog("Analyzing file with content-type=\"$$pic{ctype}\"");
my @used_scansets = ();
my $corrupt = 0;
my $suffix = 0;
my $generic_ctype = 0;
my $digest;
my $file = $$pic{fpath};
my $tfile = $file;
my $pfile = $file . ".pnm";
my $efile = $file . ".err";
debuglog("pfile => $pfile");
debuglog("efile => $efile");
#Open ERRORLOG
$haserr = $Mail::SpamAssassin::Logger::LOG_SA{level} == 3;
if ($haserr) {
$haserr = open RAWERR, ">$imgdir/raw.err";
debuglog("Errors to: $imgdir/raw.err") if ($haserr>0);
}
my $mimetype = $$pic{ctype};
if($mimetype =~ m'application/octet-stream'i) {
$generic_ctype = 1;
}
if($$pic{fname} =~ /\.([\w-]+)$/) {
$suffix = $1;
}
if ($suffix) {
debuglog("File has Content-Type \"$mimetype\" and File Extension \"$suffix\"");
} else {
debuglog("File has Content-Type \"$mimetype\" and no File Extension");
}
if ( $$pic{ftype} == 1 ) {
infolog("Found GIF header name=\"$$pic{fname}\"");
if ($conf->{focr_skip_gif}) {
infolog("Skipping image check");
next;
}
if (defined($conf->{focr_max_size_gif}) and ($$pic{fsize} > $conf->{focr_max_size_gif})) {
infolog("GIF file size ($$pic{fsize}) exceeds maximum file size for this format, skipping...");
next;
}
if ( ($$pic{ctype} !~ /gif/i) and not $generic_ctype) {
wrong_ctype( "GIF", $$pic{ctype} );
$internal_score += $conf->{'focr_wrongctype_score'};
}
if ( $suffix and $suffix !~ /gif/i) {
wrong_extension( "GIF", $suffix);
$internal_score += $conf->{'focr_wrongext_score'};
}
my $interlaced_gif = 0;
my $image_count = 0;
foreach my $a (qw/gifsicle giftext giffix gifinter giftopnm/) {
unless (defined $conf->{"focr_bin_$a"}) {
errorlog("Cannot exec $a, skipping image");
next;
}
}
my @stderr_data;
my ($retcode, @stdout_data) = save_execute(
"$conf->{focr_bin_giftext} $file",
undef,
">$imgdir/giftext.info",
">>$imgdir/giftext.err", 1);
if ($retcode<0) { # only care if we timed out
chomp $retcode;
errorlog("$conf->{focr_bin_giftext} Timed out [$retcode], skipping...");
++$imgerr if $conf->{focr_keep_bad_images}>0; next;
}
foreach (@stdout_data) {
unless ($interlaced_gif) {
if ( $_ =~ /Image is Interlaced/i ) {
$interlaced_gif = 1;
}
}
if ( $_ =~ /^Image #/ ) {
$image_count++;
}
}
if ($interlaced_gif or ($image_count > 1)) {
infolog("Image is interlaced or animated...");
}
else {
infolog("Image is single non-interlaced...");
$tfile .= "-fixed.gif";
printf RAWERR "## $conf->{focr_bin_giffix} $file >$tfile 2>>$efile\n" if ($haserr>0);
$retcode = save_execute("$conf->{focr_bin_giffix} $file", undef, ">$tfile", ">>$efile");
if ($retcode<0) { # only care if we timed out
chomp $retcode;
errorlog("$conf->{focr_bin_giffix}: Timed out [$retcode], skipping...");
printf RAWERR "?? Timed out > $retcode\n" if ($haserr>0);
++$imgerr if $conf->{focr_keep_bad_images}>0; next;
}
if (open ERR, $efile) {
@stderr_data = <ERR>;
close ERR;
foreach (@stderr_data) {
if ( $_ =~ /GIF-LIB error/i ) {
$corrupt = $_;
last;
}
}
}
}
my $fixedsize = (stat($tfile))[7];
if (defined($conf->{focr_max_size_gif}) and ($fixedsize > $conf->{focr_max_size_gif})) {
infolog("Fixed GIF file size ($fixedsize) exceeds maximum file size for this format, skipping...");
next;
}
if ($corrupt) {
if ($interlaced_gif or ($image_count > 1)) {
infolog("Skipping corrupted interlaced image...");
corrupt_img($conf->{focr_corrupt_unfixable_score}, $corrupt);
$internal_score += $conf->{focr_corrupt_unfixable_score};
next;
}
if (-z $tfile) {
infolog("Uncorrectable corruption detected, skipping non-interlaced image...");
corrupt_img($conf->{focr_corrupt_unfixable_score}, $corrupt);
$internal_score += $conf->{focr_corrupt_unfixable_score};
next;
}
infolog("Image is corrupt, but seems fixable, continuing...");
corrupt_img($conf->{focr_corrupt_score}, $corrupt);
$internal_score += $conf->{focr_corrupt_score};
}
if ($image_count > 1) {
infolog("File contains <$image_count> images, deanimating...");
$tfile = deanimate($tfile);
}
if ($interlaced_gif) {
infolog("Processing interlaced_gif $tfile...");
my $cfile = $tfile;
if ($tfile =~ m/\.gif$/i) {
$tfile =~ s/\.gif$/-fixed.gif/i;
} else {
$tfile .= ".gif";
}
printf RAWERR qq(## $conf->{focr_bin_gifinter} $cfile >$tfile 2>>$efile\n) if ($haserr>0);
$retcode = save_execute("$conf->{focr_bin_gifinter} $cfile", undef, ">$tfile", ">>$efile");
if ($retcode<0) {
chomp $retcode;
printf RAWERR "?? Timed out > $retcode\n" if ($haserr>0);
errorlog("$conf->{focr_bin_gifinter}: Timed out [$retcode], skipping...");
++$imgerr if $conf->{focr_keep_bad_images}>0; next;
} elsif ($retcode>0) {
chomp $retcode;
printf RAWERR "?? [$retcode] returned from $conf->{focr_bin_gifinter}\n" if ($haserr>0);
errorlog("$conf->{focr_bin_gifinter}: Returned [$retcode], skipping...");
++$imgerr if $conf->{focr_keep_bad_images}>0; next;
}
}
printf RAWERR qq(## $conf->{focr_bin_giftopnm} $tfile >$pfile 2>>$efile\n) if ($haserr>0);
$retcode = save_execute("$conf->{focr_bin_giftopnm} $tfile", undef, ">$pfile", ">>$efile");
if ($retcode<0) {
chomp $retcode;
printf RAWERR "?? Timed out > $retcode\n" if ($haserr>0);
errorlog("$conf->{focr_bin_giftopnm}: Timed out [$retcode], skipping...");
++$imgerr if $conf->{focr_keep_bad_images}>0; next;
} elsif ($retcode>0) {
chomp $retcode;
printf RAWERR "?? [$retcode] returned from $conf->{focr_bin_giftopnm}\n" if ($haserr>0);
errorlog("$conf->{focr_bin_giftopnm}: Returned [$retcode], skipping...");
++$imgerr if $conf->{focr_keep_bad_images}>0; next;
}
}
elsif ( $$pic{ftype} == 2 ) {
infolog("Found JPEG header name=\"$$pic{fname}\"");
if ($conf->{focr_skip_jpeg}) {
infolog("Skipping image check");
next;
}
if (defined($conf->{focr_max_size_jpeg}) and ($$pic{fsize} > $conf->{focr_max_size_jpeg})) {
infolog("JPEG file size ($$pic{fsize}) exceeds maximum file size for this format, skipping...");
next;
}
if ( ($$pic{ctype} !~ /(jpeg|jpg)/i) and not $generic_ctype) {
wrong_ctype( "JPEG", $$pic{ctype} );
$internal_score += $conf->{'focr_wrongctype_score'};
}
if ( $suffix and $suffix !~ /(jpeg|jpg|jfif)/i) {
wrong_extension( "JPEG", $suffix);
$internal_score += $conf->{'focr_wrongext_score'};
}
foreach my $a (qw/jpegtopnm/) {
unless (defined $conf->{"focr_bin_$a"}) {
errorlog("Cannot exec $a, skipping image");
next;
}
}
printf RAWERR qq(## $conf->{focr_bin_jpegtopnm} $file >$pfile 2>>$efile\n) if ($haserr>0);
my $retcode = save_execute("$conf->{focr_bin_jpegtopnm} $file", undef, ">$pfile", ">>$efile");
if ($retcode<0) {
chomp $retcode;
printf RAWERR "?? Timed out > $retcode\n" if ($haserr>0);
errorlog("$conf->{focr_bin_jpegtopnm}: Timed out [$retcode], skipping...");
++$imgerr if $conf->{focr_keep_bad_images}>0; next;
} elsif ($retcode>0) {
chomp $retcode;
printf RAWERR "?? [$retcode] returned from $conf->{focr_bin_jpegtopnm}\n" if ($haserr>0);
errorlog("$conf->{focr_bin_jpegtopnm}: Returned [$retcode], skipping...");
++$imgerr if $conf->{focr_keep_bad_images}>0; next;
}
}
elsif ( $$pic{ftype} == 3 ) {
infolog("Found PNG header name=\"$$pic{fname}\"");
if ($conf->{focr_skip_png}) {
infolog("Skipping image check");
next;
}
if (defined($conf->{focr_max_size_png}) and ($$pic{fsize} > $conf->{focr__max_size_png})) {
infolog("PNG file size ($$pic{fsize}) exceeds maximum file size for this format, skipping...");
next;
}
if ( ($$pic{ctype} !~ /png/i) and not $generic_ctype) {
wrong_ctype( "PNG", $$pic{ctype} );
$internal_score += $conf->{'focr_wrongctype_score'};
}
if ( $suffix and $suffix !~ /(png)/i) {
wrong_extension( "PNG", $suffix);
$internal_score += $conf->{'focr_wrongext_score'};
}
foreach my $a (qw/pngtopnm/) {
unless (defined $conf->{"focr_bin_$a"}) {
errorlog("Cannot exec $a, skipping image");
next;
}
}
printf RAWERR qq(## $conf->{focr_bin_pngtopnm} $file >$pfile 2>>$efile\n) if ($haserr>0);
my $retcode = save_execute("$conf->{focr_bin_pngtopnm} $file", undef, ">$pfile", ">>$efile");
if ($retcode<0) {
chomp $retcode;
printf RAWERR "?? Timed out > $retcode\n" if ($haserr>0);
errorlog("$conf->{focr_bin_pngtopnm}: Timed out [$retcode], skipping...");
++$imgerr if $conf->{focr_keep_bad_images}>0; next;
} elsif ($retcode>0) {
chomp $retcode;
printf RAWERR "?? [$retcode] returned from $conf->{focr_bin_pngtopnm}\n" if ($haserr>0);
errorlog("$conf->{focr_bin_pngtopnm}: Returned [$retcode], skipping...");
++$imgerr if $conf->{focr_keep_bad_images}>0; next;
}
}
elsif ( $$pic{ftype} == 4 ) {
infolog("Found BMP header name=\"$$pic{fname}\"");
if ($conf->{focr_skip_bmp}) {
infolog("Skipping image check");
next;
}
if (defined($conf->{focr_max_size_bmp}) and ($$pic{fsize} > $conf->{focr_max_size_bmp})) {
infolog("BMP file size ($$pic{fsize}) exceeds maximum file size for this format, skipping...");
next;
}
if ( ($$pic{ctype} !~ /bmp/i) and not $generic_ctype) {
wrong_ctype( "BMP", $$pic{ctype} );
$internal_score += $conf->{'focr_wrongctype_score'};
}
if ( $suffix and $suffix !~ /(bmp)/i) {
wrong_extension( "BMP", $suffix);
$internal_score += $conf->{'focr_wrongext_score'};
}
foreach my $a (qw/bmptopnm/) {
unless (defined $conf->{"focr_bin_$a"}) {
errorlog("Cannot exec $a, skipping image");
next;
}
}
printf RAWERR qq(## $conf->{focr_bin_bmptopnm} $file >$pfile 2>>$efile\n) if ($haserr>0);
my $retcode = save_execute("$conf->{focr_bin_bmptopnm} $file", undef, ">$pfile", ">>$efile");
if ($retcode<0) {
chomp $retcode;
printf RAWERR "?? Timed out > $retcode\n" if ($haserr>0);
errorlog("$conf->{focr_bin_bmptopnm}: Timed out [$retcode], skipping...");
++$imgerr if $conf->{focr_keep_bad_images}>0; next;
} elsif ($retcode>0) {
chomp $retcode;
printf RAWERR "?? [$retcode] returned from $conf->{focr_bin_bmptopnm}\n" if ($haserr>0);
errorlog("$conf->{focr_bin_bmptopnm}: Returned [$retcode], skipping...");
++$imgerr if $conf->{focr_keep_bad_images}>0; next;
}
}
elsif ( $$pic{ftype} == 5 ) {
infolog("Found TIFF header name=\"$$pic{fname}\"");
if ($conf->{focr_skip_tiff}) {
infolog("Skipping image check");
next;
}
if (defined($conf->{focr_max_size_tiff}) and ($$pic{fsize} > $conf->{focr_max_size_tiff})) {
infolog("TIFF file size ($$pic{fsize}) exceeds maximum file size for this format, skipping...");
next;
}
if ( ($$pic{ctype} !~ /tif/i) and not $generic_ctype) {
wrong_ctype( "TIFF", $$pic{ctype} );
$internal_score += $conf->{'focr_wrongctype_score'};
}
if ( $suffix and $suffix !~ /tif/i) {
wrong_extension( "TIFF", $suffix);
$internal_score += $conf->{'focr_wrongext_score'};
}
foreach my $a (qw/tifftopnm/) {
unless (defined $conf->{"focr_bin_$a"}) {
errorlog("Cannot exec $a, skipping image");
next;
}
}
printf RAWERR qq(## $conf->{focr_bin_tifftopnm} $file >$pfile 2>>$efile\n) if ($haserr>0);
my $retcode = save_execute("$conf->{focr_bin_tifftopnm} $file", undef, ">$pfile", ">>$efile");
if ($retcode<0) {
chomp $retcode;
printf RAWERR "?? Timed out > $retcode\n" if ($haserr>0);
errorlog("$conf->{focr_bin_tifftopnm}: Timed out [$retcode], skipping...");
++$imgerr if $conf->{focr_keep_bad_images}>0; next;
} elsif ($retcode>0) {
chomp $retcode;
printf RAWERR "?? [$retcode] returned from $conf->{focr_bin_tifftopnm}\n" if ($haserr>0);
errorlog("$conf->{focr_bin_tifftopnm}: Returned [$retcode], skipping...");
++$imgerr if $conf->{focr_keep_bad_images}>0; next;
}
}
else {
errorlog("Image type not recognized, unknown format. Skipping this image...");
next;
}
if($conf->{focr_enable_image_hashing}) {
infolog("Calculating image hash for: $pfile");
($corrupt, $digest) = calc_image_hash($pfile,$pic);
if ($corrupt) {
infolog("Error calculating the image hash, skipping hash check...");
} else {
my ($score, $dinfo, $whash);
$whash = $conf->{focr_enable_image_hashing} == 3
? $conf->{focr_mysql_hash}
: $conf->{focr_db_hash};
($score,$dinfo) = check_image_hash_db($digest, $whash, $$pic{fname}, $$pic{ctype}, $$pic{ftype});
if ($score > 0) {
known_img_hash($score,$dinfo);
infolog("Message is SPAM. $dinfo") if ($conf->{focr_enable_image_hashing} < 3);
removedirs(get_all_tmpdirs());
return 0;
}
$whash = $conf->{focr_enable_image_hashing} == 3
? $conf->{focr_mysql_safe}
: $conf->{focr_db_safe};
($score,$dinfo) = check_image_hash_db($digest, $whash, $$pic{fname}, $$pic{ctype}, $$pic{ftype});
if ($score > 0) {
infolog("Image in KNOWN_GOOD. Skipping OCR checks...");
next;
}
}
if ($digest eq '') {
infolog("Empty Hash, skipping...");
next;
}
} else {
infolog("Image hashing disabled in configuration, skipping...");
}
# Note: $current_score is here the score that the message had at the beginning
# and $score is the autodisable_score defined in the config
# $internal_score describes the score that the message got by FuzzyOcr so far.
if ($internal_score + $current_score > $score) {
my $total = $internal_score + $current_score;
warnlog("FuzzyOcr stopped, message got $internal_score points by other FuzzyOcr tests ($total>$score).");
#infolog("OCR canceled, message got already more than $score points ($total) by other FuzzyOcr tests.");
return 0;
}
my @ocr_results = ();
my $scansets = get_scansets();
my $newlist = '';
foreach my $s (@$scansets) {
$newlist .= ' ' . $s->{label} . '(' . $s->{hit_counter} . ')';
}
infolog("Scanset Order:$newlist");
my $mcnt = 0;
my $modus = 0;
my $modus_match = 0;
my $wref = get_wordlist();
my %words = %$wref;
foreach my $scanset (@$scansets) {
my $scanlabel = $scanset->{label};
my $scancmd = $scanset->{command};
if ($scancmd =~ m/^\$/) {
warnlog("Skipping $scanlabel, invalid command '$scancmd'");
next;
}
if (($scancmd =~ m/ocrad/) and
($$pic{width} < 16 or $$pic{height} < 16)) {
warnlog("Skipping $scanlabel, image too small");
next;
}
my $cmcnt = 0;
my @cfound;
if (defined $scanset->{args}) {
$scancmd .= ' ' . $scanset->{args};
}
printf RAWERR qq(## $scancmd\n) if ($haserr>0);
my ($retcode, @result) = $scanset->run($pfile);
if ($retcode<0) {
if ($retcode == -1) {
printf RAWERR qq(Timeout[$conf->{focr_timeout}]: $scancmd\n) if ($haserr>0);
errorlog("Timeout[$scanlabel]: \"$scancmd\" took more than $conf->{focr_timeout} sec.");
} elsif ($retcode == -2) {
printf RAWERR qq(Cannot exec[$scanlabel]: $scancmd\n) if ($haserr>0);
errorlog("Cannot execute($scanlabel): \"$scancmd\"");
} else {
printf RAWERR qq(Unknown error <$retcode>: $scancmd\n) if ($haserr>0);
errorlog("Unknown error: [$retcode]...");
}
infolog("Skipping scanset, trying next...");
next;
} elsif ($retcode>0) {
chomp $retcode;
my $errstr = "Return code: $retcode, Error: ";
$errstr .= join( '', @result );
warnlog("Errors in Scanset \"$scanlabel\"");
warnlog($errstr);
warnlog("Skipping scanset because of errors, trying next...");
printf RAWERR qq($errstr\n) if ($haserr>0);
next;
}
debuglog("ocrdata=>>".join("",@result)."<<=end");
foreach $modus (0 .. 1) {
foreach my $ww (keys %words) {
my $w = lc $ww;
$w =~ s/[^a-z0-9 ]//g;
if ($modus) {
$w =~ s/ //g;
}
if ($conf->{focr_strip_numbers}) {
$w =~ s/[0-9]//g;
}
my $wcnt = 0;
foreach (@result) {
$_ = lc;
if ($modus) {
s/ //g;
}
if ($conf->{focr_strip_numbers}) {
tr/!;|(0815/iiicoals/;
s/[0-9]//g;
} else {
tr/!;|(/iiic/;
}
s/[^a-z0-9 ]//g;
my $matched = abs(adistr( $w, $_ ));
if ( $matched < $words{$ww} ) {
$wcnt++;
infolog(
"Scanset \"$scanlabel\" found word \"$w\" with fuzz of "
. sprintf("%0.4f",$matched)
. "\nline: \"$_\""
);
if ($conf->{focr_unique_matches}) {
last;
}
}
}
$cmcnt += $wcnt;
if ( ( $conf->{focr_verbose} > 0 ) and ($wcnt) ) {
push( @cfound, "\"$w\" in $wcnt lines" );
}
}
$mcnt = max($mcnt, $cmcnt);
if ($mcnt == $cmcnt) {
@found = @cfound;
}
if ((not $modus) and ($cmcnt >= $conf->{focr_counts_required})) {
if ($mcnt == $cmcnt) {
$modus_match = 0;
}
debuglog("Enough OCR Hits without space stripping, skipping second matching pass...");
last;
} elsif (not $modus) {
debuglog("Not enough OCR Hits without space stripping, doing second matching pass...");
if ($mcnt == $cmcnt) {
$modus_match = 1;
}
}
}
if ($mcnt >= $conf->{focr_counts_required} and $conf->{focr_minimal_scanset}) {
infolog("Scanset \"$scanlabel\" generates enough hits ($mcnt), skipping further scansets...");
if ($conf->{focr_autosort_scanset}) {
foreach my $s (@$scansets) {
if ($s->{label} eq $scanlabel) {
if ($s->{hit_counter} < $conf->{focr_autosort_buffer}) {
$s->{hit_counter} = $s->{hit_counter} + 1;
}
} else {
if ($s->{hit_counter} > 0) {
$s->{hit_counter} = $s->{hit_counter} - 1;
}
}
}
}
last;
}
}
if ($conf->{focr_enable_image_hashing}) {
my $info = join('::',$mcnt,$$pic{fname},$$pic{ctype},$$pic{ftype},$digest);
push(@hashes, $info);
}
# Normal match or match without spaces?
if ($modus_match) {
$cnt += $mcnt;
} else {
$cnt += $conf->{focr_twopass_scoring_factor} * $mcnt;
}
}
close RAWERR if ($haserr>0);
if ($cnt == 0) {
if ($conf->{focr_enable_image_hashing} > 1 and @hashes) {
infolog("Message is ham, saving...");
foreach my $h (@hashes) {
my ($mcnt,$fname,$ctype,$ftype,$digest) = split('::',$h,5);
next if $mcnt;
my $whash = $conf->{focr_enable_image_hashing} == 3
? $conf->{focr_mysql_safe}
: $conf->{focr_db_safe};
add_image_hash_db($digest,0,$whash,$fname,$ctype,$ftype);
}
}
} else {
my $score = '0.000';
my $debuginfo = (
"Words found:\n"
. join( "\n", @found )
. "\n($cnt word occurrences found)" );
if ($cnt >= $conf->{focr_counts_required}) {
$score = sprintf "%0.3f", $conf->{focr_base_score} +
(( $cnt - $conf->{focr_counts_required} ) * $conf->{focr_add_score} );
infolog("Message is spam, score = $score");
} else {
$score = sprintf("%0.3f", $conf->{focr_add_score} * $cnt) if $conf->{focr_score_ham};
infolog("Message is ham, score = $score");
}
if ($conf->{focr_enable_image_hashing} and
$conf->{focr_hashing_learn_scanned} and
$score > 0) {
foreach my $h (@hashes) {
my ($mcnt,$fname,$ctype,$ftype,$digest) = split('::',$h,5);
next unless $mcnt;
my $whash = $conf->{focr_enable_image_hashing} == 3
? $conf->{focr_mysql_hash}
: $conf->{focr_db_hash};
add_image_hash_db($digest,$score,$whash,$fname,$ctype,$ftype,$debuginfo);
}
}
if ( $conf->{focr_verbose} > 0 and $conf->{focr_verbose} < 3 ) {
infolog($debuginfo) unless ($conf->{focr_enable_image_hashing} == 3);
}
for my $set ( 0 .. 3 ) {
$pms->{conf}->{scoreset}->[$set]->{"FUZZY_OCR"} = $score;
}
$pms->_handle_hit( "FUZZY_OCR", $score, "BODY: ",
$pms->{conf}->{descriptions}->{FUZZY_OCR} . "\n$debuginfo" );
}
if ($imgerr == 0 and $conf->{focr_keep_bad_images}<2) {
removedirs(get_all_tmpdirs());
}
if ($conf->{focr_enable_image_hashing} == 3) {
if (defined $conf->{focr_mysql_ddb}) {
$conf->{focr_mysql_ddb}->disconnect;
}
}
debuglog("FuzzyOcr ending successfully...");
return 0;
}
1;
#vim: et ts=4 sw=4

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,332 @@
#
# MailWatch for MailScanner
# Copyright (C) 2003 Steve Freegard (smf@f2s.com)
#
# 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 more 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
#
package MailScanner::CustomConfig;
use strict;
use DBI;
use Sys::Hostname;
use Storable(qw[freeze thaw]);
use POSIX;
use Socket;
# Trace settings - uncomment this to debug
# DBI->trace(2,'/root/dbitrace.log');
my($dbh);
my($sth);
my($hostname) = hostname;
my $loop = inet_aton("127.0.0.1");
my $server_port = 11553;
my $timeout = 3600;
# Modify this as necessary for your configuration
my($db_name) = 'mailscanner';
my($db_host) = 'localhost';
my($db_user) = 'mailwatch';
my($db_pass) = 'eepGur&';
sub InitMailWatchLogging {
my $pid = fork();
if ($pid) {
# MailScanner child process
waitpid $pid, 0;
MailScanner::Log::InfoLog("Started SQL Logging child");
} else {
# New process
# Detach from parent, make connections, and listen for requests
POSIX::setsid();
if (!fork()) {
$SIG{HUP} = $SIG{INT} = $SIG{PIPE} = $SIG{TERM} = $SIG{ALRM} = \&ExitLogging;
alarm $timeout;
$0 = "MailWatch SQL";
InitConnection();
ListenForMessages();
}
exit;
}
}
sub InitConnection {
# Set up TCP/IP socket. We will start one server per MailScanner
# child, but only one child will actually be able to get the socket.
# The rest will die silently. When one of the MailScanner children
# tries to log a message and fails to connect, it will start a new
# server.
socket(SERVER, PF_INET, SOCK_STREAM, getprotobyname("tcp"));
setsockopt(SERVER, SOL_SOCKET, SO_REUSEADDR, 1);
my $addr = sockaddr_in($server_port, $loop);
bind(SERVER, $addr) or exit;
listen(SERVER, SOMAXCONN) or exit;
# Our reason for existence - the persistent connection to the database
$dbh = DBI->connect("DBI:mysql:database=$db_name;host=$db_host", $db_user, $db_pass, {PrintError => 0});
if (!$dbh) {
MailScanner::Log::WarnLog("Unable to initialise database connection: %s", $DBI::errstr);
}
$sth = $dbh->prepare("INSERT INTO maillog (timestamp, id, size, from_address, from_domain, to_address, to_domain, subject, clientip, archive, isspam, ishighspam, issaspam, isrblspam, spamwhitelisted, spamblacklisted, sascore, spamreport, virusinfected, nameinfected, otherinfected, report, ismcp, ishighmcp, issamcp, mcpwhitelisted, mcpblacklisted, mcpsascore, mcpreport, hostname, date, time, headers, quarantined) VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)") or
MailScanner::Log::WarnLog($DBI::errstr);
}
sub ExitLogging {
# Server exit - commit changes, close socket, and exit gracefully.
close(SERVER);
$dbh->commit;
$dbh->disconnect;
exit;
}
sub ListenForMessages {
my $message;
# Wait for messages
while (my $cli = accept(CLIENT, SERVER)) {
my($port, $packed_ip) = sockaddr_in($cli);
my $dotted_quad = inet_ntoa($packed_ip);
# reset emergency timeout - if we haven"t heard anything in $timeout
# seconds, there is probably something wrong, so we should clean up
# and let another process try.
alarm $timeout;
# Make sure we"re only receiving local connections
if ($dotted_quad ne "127.0.0.1") {
close CLIENT;
next;
}
my @in;
while (<CLIENT>) {
# End of normal logging message
last if /^END$/;
# MailScanner child telling us to shut down
ExitLogging if /^EXIT$/;
chop;
push @in, $_;
}
my $data = join "", @in;
my $tmp = unpack("u", $data);
$message = thaw $tmp;
next unless defined $$message{id};
# Check to make sure DB connection is still valid
InitConnection unless $dbh->ping;
# Log message
$sth->execute(
$$message{timestamp},
$$message{id},
$$message{size},
$$message{from},
$$message{from_domain},
$$message{to},
$$message{to_domain},
$$message{subject},
$$message{clientip},
$$message{archiveplaces},
$$message{isspam},
$$message{ishigh},
$$message{issaspam},
$$message{isrblspam},
$$message{spamwhitelisted},
$$message{spamblacklisted},
$$message{sascore},
$$message{spamreport},
$$message{virusinfected},
$$message{nameinfected},
$$message{otherinfected},
$$message{reports},
$$message{ismcp},
$$message{ishighmcp},
$$message{issamcp},
$$message{mcpwhitelisted},
$$message{mcpblacklisted},
$$message{mcpsascore},
$$message{mcpreport},
$$message{hostname},
$$message{date},
$$message{"time"},
$$message{headers},
$$message{quarantined});
# this doesn't work in the event we have no connection by now ?
if (!$sth) {
MailScanner::Log::WarnLog("$$message{id}: MailWatch SQL Cannot insert row: %s", $sth->errstr);
} else {
MailScanner::Log::InfoLog("$$message{id}: Logged to MailWatch SQL");
}
# Unset
$message = undef;
}
}
sub EndMailWatchLogging {
# Tell server to shut down. Another child will start a new server
# if we are here due to old age instead of administrative intervention
socket(TO_SERVER, PF_INET, SOCK_STREAM, getprotobyname("tcp"));
my $addr = sockaddr_in($server_port, $loop);
connect(TO_SERVER, $addr) or return;
print TO_SERVER "EXIT\n";
close TO_SERVER;
}
sub MailWatchLogging {
my($message) = @_;
# Don't bother trying to do an insert if no message is passed-in
return unless $message;
# Fix duplicate 'to' addresses for Postfix users
my(%rcpts);
map { $rcpts{$_}=1; } @{$message->{to}};
@{$message->{to}} = keys %rcpts;
# Get rid of control chars and tidy-up SpamAssassin report
my $spamreport = $message->{spamreport};
$spamreport =~ s/\n/ /g;
$spamreport =~ s/\t//g;
# Same with MCP report
my $mcpreport = $message->{mcpreport};
$mcpreport =~ s/\n/ /g;
$mcpreport =~ s/\t//g;
# Workaround tiny bug in original MCP code
my($mcpsascore);
if (defined $message->{mcpsascore}) {
$mcpsascore = $message->{mcpsascore};
} else {
$mcpsascore = $message->{mcpscore};
}
# Set quarantine flag - this only works on 4.43.7 or later
my($quarantined);
$quarantined = 0;
if ( (scalar(@{$message->{quarantineplaces}}))
+ (scalar(@{$message->{spamarchive}})) > 0 )
{
$quarantined = 1;
}
# Get timestamp, and format it so it is suitable to use with MySQL
my($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime();
my($timestamp) = sprintf("%d-%02d-%02d %02d:%02d:%02d",
$year+1900,$mon+1,$mday,$hour,$min,$sec);
my($date) = sprintf("%d-%02d-%02d",$year+1900,$mon+1,$mday);
my($time) = sprintf("%02d:%02d:%02d",$hour,$min,$sec);
# Also print 1 line for each report about this message. These lines
# contain all the info above, + the attachment filename and text of
# each report.
my($file, $text, @report_array);
while(($file, $text) = each %{$message->{allreports}}) {
$file = "the entire message" if $file eq "";
# Use the sanitised filename to avoid problems caused by people forcing
# logging of attachment filenames which contain nasty SQL instructions.
$file = $message->{file2safefile}{$file} or $file;
$text =~ s/\n/ /; # Make sure text report only contains 1 line
$text =~ s/\t/ /; # and no tab characters
push (@report_array, $text);
}
# Sanitize reports
my $reports = join(",",@report_array);
# Fix the $message->{clientip} for later versions of Exim
# where $message->{clientip} contains ip.ip.ip.ip.port
my $clientip = $message->{clientip};
$clientip =~ s/^(\d+\.\d+\.\d+\.\d+)(\.\d+)$/$1/;
# Integrate SpamAssassin Whitelist/Blacklist reporting
if($spamreport =~ /USER_IN_WHITELIST/) {
$message->{spamwhitelisted} = 1;
}
if($spamreport =~ /USER_IN_BLACKLIST/) {
$message->{spamblacklisted} = 1;
}
# Get the first domain from the list of recipients
my($todomain,@todomain);
@todomain = @{$message->{todomain}};
$todomain = $todomain[0];
# Place all data into %msg
my %msg;
$msg{timestamp} = $timestamp;
$msg{id} = $message->{id};
$msg{size} = $message->{size};
$msg{from} = $message->{from};
$msg{from_domain} = $message->{fromdomain};
$msg{to} = join(",", @{$message->{to}});
$msg{to_domain} = $todomain;
$msg{subject} = $message->{subject};
$msg{clientip} = $clientip;
$msg{archiveplaces} = join(",", @{$message->{archiveplaces}});
$msg{isspam} = $message->{isspam};
$msg{ishigh} = $message->{ishigh};
$msg{issaspam} = $message->{issaspam};
$msg{isrblspam} = $message->{isrblspam};
$msg{spamwhitelisted} = $message->{spamwhitelisted};
$msg{spamblacklisted} = $message->{spamblacklisted};
$msg{sascore} = $message->{sascore};
$msg{spamreport} = $spamreport;
$msg{ismcp} = $message->{ismcp};
$msg{ishighmcp} = $message->{ishighmcp};
$msg{issamcp} = $message->{issamcp};
$msg{mcpwhitelisted} = $message->{mcpwhitelisted};
$msg{mcpblacklisted} = $message->{mcpblacklisted};
$msg{mcpsascore} = $mcpsascore;
$msg{mcpreport} = $mcpreport;
$msg{virusinfected} = $message->{virusinfected};
$msg{nameinfected} = $message->{nameinfected};
$msg{otherinfected} = $message->{otherinfected};
$msg{reports} = $reports;
$msg{hostname} = $hostname;
$msg{date} = $date;
$msg{"time"} = $time;
$msg{headers} = join("\n",@{$message->{headers}});
$msg{quarantined} = $quarantined;
# Prepare data for transmission
my $f = freeze \%msg;
my $p = pack("u", $f);
# Connect to server
while (1) {
socket(TO_SERVER, PF_INET, SOCK_STREAM, getprotobyname("tcp"));
my $addr = sockaddr_in($server_port, $loop);
connect(TO_SERVER, $addr) and last;
# Failed to connect - kick off new child, wait, and try again
InitMailWatchLogging();
sleep 5;
}
# Pass data to server process
MailScanner::Log::InfoLog("Logging message $msg{id} to SQL");
print TO_SERVER $p;
print TO_SERVER "END\n";
close TO_SERVER;
}
1;

View file

@ -0,0 +1,174 @@
#
# MailScanner - SMTP E-Mail Virus Scanner
# Copyright (C) 2002 Julian Field
#
# $Id: SQLBlackWhiteList.pm,v 1.2 2005/08/19 08:45:34 smfreegard Exp $
#
# 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 more 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
#
# The author, Julian Field, can be contacted by email at
# Jules@JulianField.net
# or by paper mail at
# Julian Field
# Dept of Electronics & Computer Science
# University of Southampton
# Southampton
# SO17 1BJ
# United Kingdom
#
package MailScanner::CustomConfig;
use strict 'vars';
use strict 'refs';
no strict 'subs'; # Allow bare words for parameter %'s
use vars qw($VERSION);
### The package version, both in 1.23 style *and* usable by MakeMaker:
$VERSION = substr q$Revision: 1.2 $, 10;
use DBI;
my(%Whitelist, %Blacklist);
my($wtime, $btime);
my($refresh_time) = 15; # Time in minutes before lists are refreshed
#
# Initialise SQL spam whitelist and blacklist
#
sub InitSQLWhitelist {
MailScanner::Log::InfoLog("Starting up SQL Whitelist");
my $entries = CreateList('whitelist', \%Whitelist);
MailScanner::Log::InfoLog("Read %d whitelist entries", $entries);
$wtime = time();
}
sub InitSQLBlacklist {
MailScanner::Log::InfoLog("Starting up SQL Blacklist");
my $entries = CreateList('blacklist', \%Blacklist);
MailScanner::Log::InfoLog("Read %d blacklist entries", $entries);
$btime = time();
}
#
# Lookup a message in the by-domain whitelist and blacklist
#
sub SQLWhitelist {
# Do we need to refresh the data?
if ( (time() - $wtime) >= ($refresh_time * 60) ) {
MailScanner::Log::InfoLog("Whitelist refresh time reached");
InitSQLWhitelist();
}
my($message) = @_;
return LookupList($message, \%Whitelist);
}
sub SQLBlacklist {
# Do we need to refresh the data?
if ( (time() - $btime) >= ($refresh_time * 60) ) {
MailScanner::Log::InfoLog("Blacklist refresh time reached");
InitSQLBlacklist();
}
my($message) = @_;
return LookupList($message, \%Blacklist);
}
#
# Close down the by-domain whitelist and blacklist
#
sub EndSQLWhitelist {
MailScanner::Log::InfoLog("Closing down by-domain spam whitelist");
}
sub EndSQLBlacklist {
MailScanner::Log::InfoLog("Closing down by-domain spam blacklist");
}
sub CreateList {
my($type, $BlackWhite) = @_;
my($dbh, $sth, $sql, $to_address, $from_address, $count);
my($db_name) = 'mailscanner';
my($db_host) = 'localhost';
my($db_user) = 'mailwatch';
my($db_pass) = 'eepGur&';
# Connect to the database
$dbh = DBI->connect("DBI:mysql:database=$db_name;host=$db_host",
$db_user, $db_pass,
{PrintError => 0});
# Check if connection was successfull - if it isn't
# then generate a warning and continue processing.
if (!$dbh) {
MailScanner::Log::WarnLog("Unable to initialise database connection: %s", $DBI::errstr);
return;
}
$sql = "SELECT to_address, from_address FROM $type";
$sth = $dbh->prepare($sql);
$sth->execute;
$sth->bind_columns(undef,\$to_address,\$from_address);
$count = 0;
while($sth->fetch()) {
$BlackWhite->{lc($to_address)}{lc($from_address)} = 1; # Store entry
$count++;
}
# Close connections
$sth->finish();
$dbh->disconnect();
return $count;
}
#
# Based on the address it is going to, choose the right spam white/blacklist.
# Return 1 if the "from" address is white/blacklisted, 0 if not.
#
sub LookupList {
my($message, $BlackWhite) = @_;
return 0 unless $message; # Sanity check the input
# Find the "from" address and the first "to" address
my($from, $fromdomain, @todomain, $todomain, @to, $to, $ip);
$from = $message->{from};
$fromdomain = $message->{fromdomain};
@todomain = @{$message->{todomain}};
$todomain = $todomain[0];
@to = @{$message->{to}};
$to = $to[0];
$ip = $message->{clientip};
# It is in the list if either the exact address is listed,
# or the domain is listed
return 1 if $BlackWhite->{$to}{$from};
return 1 if $BlackWhite->{$to}{$fromdomain};
return 1 if $BlackWhite->{$to}{$ip};
return 1 if $BlackWhite->{$to}{'default'};
return 1 if $BlackWhite->{$todomain}{$from};
return 1 if $BlackWhite->{$todomain}{$fromdomain};
return 1 if $BlackWhite->{$todomain}{$ip};
return 1 if $BlackWhite->{$todomain}{'default'};
return 1 if $BlackWhite->{'default'}{$from};
return 1 if $BlackWhite->{'default'}{$fromdomain};
return 1 if $BlackWhite->{'default'}{$ip};
# It is not in the list
return 0;
}
1;

View file

@ -0,0 +1,52 @@
NameVirtualHost *:80
NameVirtualHost *:443
<VirtualHost *:80>
ServerAdmin webmaster@DOMAINNAME
DocumentRoot /var/www
RewriteEngine on
RewriteCond %{SERVER_PORT} =80
RewriteRule ^(.*) https://mail.DOMAINNAME%{REQUEST_URI}
<Directory />
Options FollowSymLinks
AllowOverride None
</Directory>
<Directory /var/www/>
Options Indexes FollowSymLinks MultiViews
AllowOverride None
Order allow,deny
allow from all
# Uncomment this directive is you want to see apache2's
# default start page (in /apache2-default) when you go to /
#RedirectMatch ^/$ /apache2-default/
</Directory>
ScriptAlias /cgi-bin/ /usr/lib/cgi-bin/
<Directory "/usr/lib/cgi-bin">
AllowOverride None
Options +ExecCGI -MultiViews +SymLinksIfOwnerMatch
Order allow,deny
Allow from all
</Directory>
ErrorLog /var/log/apache2/error.log
# Possible values include: debug, info, notice, warn, error, crit,
# alert, emerg.
LogLevel warn
CustomLog /var/log/apache2/access.log combined
ServerSignature On
Alias /doc/ "/usr/share/doc/"
<Directory "/usr/share/doc/">
Options Indexes MultiViews FollowSymLinks
AllowOverride None
Order deny,allow
Deny from all
Allow from 127.0.0.0/255.0.0.0 ::1/128
</Directory>
</VirtualHost>

View file

@ -0,0 +1,33 @@
<IfModule mod_ssl.c>
<VirtualHost *:443>
DocumentRoot /var/www/webmail
ServerName mail.DOMAINNAME
ServerAlias webmail.DOMAINNAME
ServerAdmin webmaster@DOMAINNAME
DirectoryIndex index.html index.php
ErrorLog /var/log/apache2/ssl-error.log
CustomLog /var/log/apache2/access.log combined
AddType application/x-httpd-php .php
php_admin_flag safe_mode Off
SSLEngine on
SSLCACertificateFile /etc/ssl/certs/cacert.pem
SSLCertificateFile /etc/apache2/ssl/www.pem
SSLCertificateKeyFile /etc/apache2/ssl/www.key
ErrorDocument 400 /error/invalidSyntax.html
ErrorDocument 401 /error/authorizationRequired.html
ErrorDocument 403 /error/forbidden.html
ErrorDocument 404 /error/fileNotFound.html
ErrorDocument 405 /error/methodNotAllowed.html
ErrorDocument 500 /error/internalServerError.html
ErrorDocument 503 /error/overloaded.html
SetEnvIf User-Agent ".*MSIE.*" nokeepalive ssl-unclean-shutdown downgrade-1.0 force-response-1.0
Alias /munin "/var/www/munin/"
# Alias /webmail "/usr/share/squirrelmail"
</VirtualHost>

View file

@ -0,0 +1,144 @@
#
# Sample configuration file for ISC dhcpd for Debian
#
# $Id: dhcpd.conf,v 1.1.1.1 2002/05/21 00:07:44 peloy Exp $
#
# The ddns-updates-style parameter controls whether or not the server will
# attempt to do a DNS update when a lease is confirmed. We default to the
# behavior of the version 2 packages ('none', since DHCP v2 didn't
# have support for DDNS.)
# modified rob@egressive.com 20070522
ddns-update-style interim;
# option definitions common to all supported networks...
# modified rob@egressive.com 20070522
option domain-name "DOMAIN.CO.NZ";
option domain-name-servers ns1.DOMAIN.CO.NZ;
# modified rob@egressive.com 20070522
default-lease-time 21600;
max-lease-time 43200;
# modified rob@egressive.com 20070522
one-lease-per-client on;
# If this DHCP server is the official DHCP server for the local
# network, the authoritative directive should be uncommented.
# modified rob@egressive.com 20070522
authoritative;
# Use this to send dhcp log messages to a different log file (you also
# have to hack syslog.conf to complete the redirection).
log-facility local7;
include "/etc/dhcp3/rndc.key";
zone DOMAIN.CO.NZ. {
primary 192.168.1.1;
key rndc-key;
}
zone 1.168.192.in-addr.arpa. {
primary 192.168.1.1;
key rndc-key;
}
subnet 192.168.1.0 netmask 255.255.255.0 {
range 192.168.1.101 192.168.1.200;
option routers 192.168.1.1;
option subnet-mask 255.255.255.0;
option domain-name "DOMAIN.CO.NZ";
option domain-name-servers 192.168.1.1;
option broadcast-address 192.168.1.255;
option netbios-name-servers 192.168.1.1;
allow unknown-clients;
default-lease-time 21600;
max-lease-time 43200;
}
# No service will be given on this subnet, but declaring it helps the
# DHCP server to understand the network topology.
#subnet 10.152.187.0 netmask 255.255.255.0 {
#}
# This is a very basic subnet declaration.
#subnet 10.254.239.0 netmask 255.255.255.224 {
# range 10.254.239.10 10.254.239.20;
# option routers rtr-239-0-1.example.org, rtr-239-0-2.example.org;
#}
# This declaration allows BOOTP clients to get dynamic addresses,
# which we don't really recommend.
#subnet 10.254.239.32 netmask 255.255.255.224 {
# range dynamic-bootp 10.254.239.40 10.254.239.60;
# option broadcast-address 10.254.239.31;
# option routers rtr-239-32-1.example.org;
#}
# A slightly different configuration for an internal subnet.
#subnet 10.5.5.0 netmask 255.255.255.224 {
# range 10.5.5.26 10.5.5.30;
# option domain-name-servers ns1.internal.example.org;
# option domain-name "internal.example.org";
# option routers 10.5.5.1;
# option broadcast-address 10.5.5.31;
# default-lease-time 600;
# max-lease-time 7200;
#}
# Hosts which require special configuration options can be listed in
# host statements. If no address is specified, the address will be
# allocated dynamically (if possible), but the host-specific information
# will still come from the host declaration.
#host passacaglia {
# hardware ethernet 0:0:c0:5d:bd:95;
# filename "vmunix.passacaglia";
# server-name "toccata.fugue.com";
#}
# Fixed IP addresses can also be specified for hosts. These addresses
# should not also be listed as being available for dynamic assignment.
# Hosts for which fixed IP addresses have been specified can boot using
# BOOTP or DHCP. Hosts for which no fixed address is specified can only
# be booted with DHCP, unless there is an address range on the subnet
# to which a BOOTP client is connected which has the dynamic-bootp flag
# set.
#host fantasia {
# hardware ethernet 08:00:07:26:c0:a5;
# fixed-address fantasia.fugue.com;
#}
# You can declare a class of clients and then do address allocation
# based on that. The example below shows a case where all clients
# in a certain class get addresses on the 10.17.224/24 subnet, and all
# other clients get addresses on the 10.0.29/24 subnet.
#class "foo" {
# match if substring (option vendor-class-identifier, 0, 4) = "SUNW";
#}
#shared-network 224-29 {
# subnet 10.17.224.0 netmask 255.255.255.0 {
# option routers rtr-224.example.org;
# }
# subnet 10.0.29.0 netmask 255.255.255.0 {
# option routers rtr-29.example.org;
# }
# pool {
# allow members of "foo";
# range 10.17.224.10 10.17.224.250;
# }
# pool {
# deny members of "foo";
# range 10.0.29.10 10.0.29.230;
# }
#}

View file

@ -0,0 +1,918 @@
## Dovecot configuration file
# '#' character and everything after it is treated as comments. Extra spaces
# and tabs are ignored. If you want to use either of these explicitly, put the
# value inside quotes, eg.: key = "# char and trailing whitespace "
# Default values are shown after each value, it's not required to uncomment
# any of the lines. Exception to this are paths, they're just examples
# with real defaults being based on configure options. The paths listed here
# are for configure --prefix=/usr --sysconfdir=/etc --localstatedir=/var
# --with-ssldir=/etc/ssl
# Base directory where to store runtime data.
#base_dir = /var/run/dovecot/
# Protocols we want to be serving:
# imap imaps pop3 pop3s
#protocols = imap imaps
# modified rob@egressive.com 20070519
protocols = imap imaps pop3 pop3s
# IP or host address where to listen in for connections. It's not currently
# possible to specify multiple addresses. "*" listens in all IPv4 interfaces.
# "[::]" listens in all IPv6 interfaces, but may also listen in all IPv4
# interfaces depending on the operating system. If you want to specify ports
# for each service, you will need to configure these settings inside the
# protocol imap/pop3 { ... } section, so you can specify different ports
# for IMAP/POP3.
#listen = *
# IP or host address where to listen in for SSL connections. Defaults
# to above if not specified.
#ssl_listen =
# Disable SSL/TLS support.
#ssl_disable = no
# PEM encoded X.509 SSL/TLS certificate and private key. They're opened before
# dropping root privileges, so keep the key file unreadable by anyone but
# root.
#ssl_cert_file = /etc/ssl/certs/ssl-cert-snakeoil.pem
#ssl_key_file = /etc/ssl/private/ssl-cert-snakeoil.key
# modified rob@egressive.com 20070520
ssl_cert_file = /etc/ssl/certs/postfix-dovecot.pem
ssl_key_file = /etc/ssl/private/postfix-dovecot.key
# If key file is password protected, give the password here. Alternatively
# give it when starting dovecot with -p parameter.
#ssl_key_password =
# File containing trusted SSL certificate authorities. Usually not needed.
#ssl_ca_file =
# modified rob@egressive.com 20070520
ssl_ca_file = /etc/ssl/certs/cacert.pem
# Request client to send a certificate.
#ssl_verify_client_cert = no
# How often to regenerate the SSL parameters file. Generation is quite CPU
# intensive operation. The value is in hours, 0 disables regeneration
# entirely.
#ssl_parameters_regenerate = 168
# SSL ciphers to use
#ssl_cipher_list = ALL:!LOW
# Disable LOGIN command and all other plaintext authentications unless
# SSL/TLS is used (LOGINDISABLED capability). Note that 127.*.*.* and
# IPv6 ::1 addresses are considered secure, this setting has no effect if
# you connect from those addresses.
#disable_plaintext_auth = yes
# modified rob@egressive.com 20070519
disable_plaintext_auth = no
# Use this logfile instead of syslog(). /dev/stderr can be used if you want to
# use stderr for logging (ONLY /dev/stderr - otherwise it is closed).
#log_path =
# For informational messages, use this logfile instead of the default
#info_log_path =
# Prefix for each line written to log file. % codes are in strftime(3)
# format.
log_timestamp = "%Y-%m-%d %H:%M:%S "
# Syslog facility to use if you're logging to syslog. Usually if you don't
# want to use "mail", you'll use local0..local7. Also other standard
# facilities are supported.
#syslog_facility = mail
##
## Login processes
##
# Directory where authentication process places authentication UNIX sockets
# which login needs to be able to connect to. The sockets are created when
# running as root, so you don't have to worry about permissions. Note that
# everything in this directory is deleted when Dovecot is started.
#login_dir = /var/run/dovecot/login
# chroot login process to the login_dir. Only reason not to do this is if you
# wish to run the whole Dovecot without roots.
# http://wiki.dovecot.org/Rootless
#login_chroot = yes
# User to use for the login process. Create a completely new user for this,
# and don't use it anywhere else. The user must also belong to a group where
# only it has access, it's used to control access for authentication process.
# Note that this user is NOT used to access mails.
# http://wiki.dovecot.org/UserIds
#login_user = dovecot
# Set max. process size in megabytes. If you don't use
# login_process_per_connection you might need to grow this.
#login_process_size = 32
# Should each login be processed in it's own process (yes), or should one
# login process be allowed to process multiple connections (no)? Yes is more
# secure, espcially with SSL/TLS enabled. No is faster since there's no need
# to create processes all the time.
#login_process_per_connection = yes
# Number of login processes to create. If login_process_per_connection is
# yes, this is the number of extra processes waiting for users to log in.
#login_processes_count = 3
# Maximum number of extra login processes to create. The extra process count
# usually stays at login_processes_count, but when multiple users start logging
# in at the same time more extra processes are created. To prevent fork-bombing
# we check only once in a second if new processes should be created - if all
# of them are used at the time, we double their amount until limit set by this
# setting is reached. This setting is used only if login_process_per_use is yes.
#login_max_processes_count = 128
# Maximum number of connections allowed in login state. When this limit is
# reached, the oldest connections are dropped. If login_process_per_connection
# is no, this is a per-process value, so the absolute maximum number of users
# logging in actually login_processes_count * max_logging_users.
#login_max_logging_users = 256
# Greeting message for clients.
#login_greeting = Dovecot ready.
# Space-separated list of elements we want to log. The elements which have
# a non-empty variable value are joined together to form a comma-separated
# string.
#login_log_format_elements = user=<%u> method=%m rip=%r lip=%l %c
# Login log format. %$ contains login_log_format_elements string, %s contains
# the data we want to log.
#login_log_format = %$: %s
##
## Mail processes
##
# Maximum number of running mail processes. When this limit is reached,
# new users aren't allowed to log in.
#max_mail_processes = 1024
# Show more verbose process titles (in ps). Currently shows user name and
# IP address. Useful for seeing who are actually using the IMAP processes
# (eg. shared mailboxes or if same uid is used for multiple accounts).
#verbose_proctitle = no
# Show protocol level SSL errors.
#verbose_ssl = no
# Valid UID range for users, defaults to 500 and above. This is mostly
# to make sure that users can't log in as daemons or other system users.
# Note that denying root logins is hardcoded to dovecot binary and can't
# be done even if first_valid_uid is set to 0.
#first_valid_uid = 500
#last_valid_uid = 0
# Valid GID range for users, defaults to non-root/wheel. Users having
# non-valid GID as primary group ID aren't allowed to log in. If user
# belongs to supplementary groups with non-valid GIDs, those groups are
# not set.
#first_valid_gid = 1
#last_valid_gid = 0
# Grant access to these extra groups for mail processes. Typical use would be
# to give "mail" group write access to /var/mail to be able to create dotlocks.
mail_extra_groups = mail
# ':' separated list of directories under which chrooting is allowed for mail
# processes (ie. /var/mail will allow chrooting to /var/mail/foo/bar too).
# This setting doesn't affect login_chroot or auth_chroot variables.
# WARNING: Never add directories here which local users can modify, that
# may lead to root exploit. Usually this should be done only if you don't
# allow shell access for users. See
# /usr/share/doc/dovecot-common/configuration.txt for more information.
#valid_chroot_dirs =
# Default chroot directory for mail processes. This can be overridden for
# specific users in user database by giving /./ in user's home directory
# (eg. /home/./user chroots into /home). Note that usually there is no real
# need to do chrooting, Dovecot doesn't allow users to access files outside
# their mail directory anyway.
#mail_chroot =
# Enable mail process debugging. This can help you figure out why Dovecot
# isn't finding your mails.
#mail_debug = no
# Default MAIL environment to use when it's not set. By leaving this empty
# dovecot tries to do some automatic detection as described in
# /usr/share/doc/dovecot-common/mail-storages.txt. There's a few special
# variables you can use, eg.:
#
# %u - username
# %n - user part in user@domain, same as %u if there's no domain
# %d - domain part in user@domain, empty if there's no domain
# %h - home directory
#
# See /usr/share/doc/dovecot-common/variables.txt for full list. Some examples:
#
# default_mail_env = maildir:/var/mail/%1u/%u/Maildir
# default_mail_env = mbox:~/mail/:INBOX=/var/mail/%u
# default_mail_env = mbox:/var/mail/%d/%n/:INDEX=/var/indexes/%d/%n
#
#default_mail_env =
# modified rob@egressive.com 20070519
default_mail_env = maildir:~/.Mail
# If you need to set multiple mailbox locations or want to change default
# namespace settings, you can do it by defining namespace sections:
#
# You can have private, shared and public namespaces. The only difference
# between them is how Dovecot announces them to client via NAMESPACE
# extension. Shared namespaces are meant for user-owned mailboxes which are
# shared to other users, while public namespaces are for more globally
# accessible mailboxes.
#
# REMEMBER: If you add any namespaces, the default namespace must be added
# explicitly, ie. default_mail_env does nothing unless you have a namespace
# without a location setting. Default namespace is simply done by having a
# namespace with empty prefix.
namespace private {
# Hierarchy separator to use. You should use the same separator for all
# namespaces or some clients get confused. '/' is usually a good one.
separator = /
# Prefix required to access this namespace. This needs to be different for
# all namespaces. For example "Public/".
#prefix =
# Physical location of the mailbox. This is in same format as
# default_mail_env, which is also the default for it.
#location =
# There can be only one INBOX, and this setting defines which namespace
# has it.
inbox = yes
# If namespace is hidden, it's not advertised to clients via NAMESPACE
# extension or shown in LIST replies. This is mostly useful when converting
# from another server with different namespaces which you want to depricate
# but still keep working. For example you can create hidden namespaces with
# prefixes "~/mail/", "~%u/mail/" and "mail/".
#hidden = yes
}
namespace public {
separator = /
prefix = Public/
# This assumes that the user has write access to the directory:
location = maildir:/home/mail/public:CONTROL=~/.Mail/control/public:INDEX=~/.Mail/index/public
}
# Space-separated list of fields to initially save into cache file. Currently
# these fields are allowed:
#
# flags, date.sent, date.received, size.virtual, size.physical
# mime.parts, imap.body, imap.bodystructure
#
# Different IMAP clients work in different ways, so they benefit from
# different cached fields. Some do not benefit from them at all. Caching more
# than necessary generates useless disk I/O, so you don't want to do that
# either.
#
# Dovecot attempts to automatically figure out what client wants and it keeps
# only that. However the first few times a mailbox is opened, Dovecot hasn't
# yet figured out what client needs, so it may not perform optimally. If you
# know what fields the majority of your clients need, it may be useful to set
# these fields by hand. If client doesn't actually use them, Dovecot will
# eventually drop them.
#
# Usually you should just leave this field alone. The potential benefits are
# typically unnoticeable.
#mail_cache_fields =
# Space-separated list of fields that Dovecot should never save to cache file.
# Useful if you want to save disk space at the cost of more I/O when the fields
# needed.
#mail_never_cache_fields =
# The minimum number of mails in a mailbox before updates are done to cache
# file. This allows optimizing Dovecot's behavior to do less disk writes at
# the cost of more disk reads.
#mail_cache_min_mail_count = 0
# When IDLE command is running, mailbox is checked once in a while to see if
# there are any new mails or other changes. This setting defines the minimum
# time to wait between those checks. Dovecot is however able to use dnotify
# and inotify with Linux to reply immediately after the change occurs.
#mailbox_idle_check_interval = 30
# Allow full filesystem access to clients. There's no access checks other than
# what the operating system does for the active UID/GID. It works with both
# maildir and mboxes, allowing you to prefix mailboxes names with eg. /path/
# or ~user/.
#mail_full_filesystem_access = no
# Maximum allowed length for mail keyword name. It's only forced when trying
# to create new keywords.
#mail_max_keyword_length = 50
# Save mails with CR+LF instead of plain LF. This makes sending those mails
# take less CPU, especially with sendfile() syscall with Linux and FreeBSD.
# But it also creates a bit more disk I/O which may just make it slower.
# Also note that if other software reads the mboxes/maildirs, they may handle
# the extra CRs wrong and cause problems.
#mail_save_crlf = no
# Use mmap() instead of read() to read mail files. read() seems to be a bit
# faster with my Linux/x86 and it's better with NFS, so that's the default.
# Note that OpenBSD 3.3 and older don't work right with mail_read_mmaped = yes.
#mail_read_mmaped = no
# Don't use mmap() at all. This is required if you store indexes in remote
# filesystems (NFS or clustered filesystem).
#mmap_disable = no
# Don't write() to mmaped files. This is required for some operating systems
# which use separate caches for them, such as OpenBSD.
#mmap_no_write = no
# Locking method for index files. Alternatives are fcntl, flock and dotlock.
# Dotlocking uses some tricks which may create more disk I/O than other locking
# methods. NOTE: If you use NFS, remember to change also mmap_disable setting!
# Solaris doesn't support flock, so Solaris users need to change this to fcntl.
#lock_method = flock
# By default LIST command returns all entries in maildir beginning with dot.
# Enabling this option makes Dovecot return only entries which are directories.
# This is done by stat()ing each entry, so it causes more disk I/O.
# (For systems setting struct dirent->d_type, this check is free and it's
# done always regardless of this setting)
#maildir_stat_dirs = no
# Copy mail to another folders using hard links. This is much faster than
# actually copying the file. This is problematic only if something modifies
# the mail in one folder but doesn't want it modified in the others. I don't
# know any MUA which would modify mail files directly. IMAP protocol also
# requires that the mails don't change, so it would be problematic in any case.
# If you care about performance, enable it.
# modified rob@egressive.com 20070521
#maildir_copy_with_hardlinks = no
maildir_copy_with_hardlinks = no
# Which locking methods to use for locking mbox. There's four available:
# dotlock: Create <mailbox>.lock file. This is the oldest and most NFS-safe
# solution. If you want to use /var/mail/ like directory, the users
# will need write access to that directory.
# fcntl : Use this if possible. Works with NFS too if lockd is used.
# flock : May not exist in all systems. Doesn't work with NFS.
# lockf : May not exist in all systems. Doesn't work with NFS.
#
# You can use multiple locking methods; if you do the order they're declared
# in is important to avoid deadlocks if other MTAs/MUAs are using multiple
# locking methods as well. Some operating systems don't allow using some of
# them simultaneously.
#mbox_read_locks = fcntl
#mbox_write_locks = dotlock fcntl
# Maximum time in seconds to wait for lock (all of them) before aborting.
#mbox_lock_timeout = 300
# If dotlock exists but the mailbox isn't modified in any way, override the
# lock file after this many seconds.
#mbox_dotlock_change_timeout = 30
# When mbox changes unexpectedly we have to fully read it to find out what
# changed. If the mbox is large this can take a long time. Since the change
# is usually just a newly appended mail, it'd be faster to simply read the
# new mails. If this setting is enabled, Dovecot does this but still safely
# fallbacks to re-reading the whole mbox file whenever something in mbox isn't
# how it's expected to be. The only real downside to this setting is that if
# some other MUA changes message flags, Dovecot doesn't notice it immediately.
# Note that a full sync is done with SELECT, EXAMINE, EXPUNGE and CHECK
# commands.
#mbox_dirty_syncs = yes
# Like mbox_dirty_syncs, but don't do full syncs even with SELECT, EXAMINE,
# EXPUNGE or CHECK commands. If this is set, mbox_dirty_syncs is ignored.
#mbox_very_dirty_syncs = no
# Delay writing mbox headers until doing a full write sync (EXPUNGE and CHECK
# commands and when closing the mailbox). This is especially useful for POP3
# where clients often delete all mails. The downside is that our changes
# aren't immediately visible to other MUAs.
#mbox_lazy_writes = yes
# If mbox size is smaller than this (in kilobytes), don't write index files.
# If an index file already exists it's still read, just not updated.
#mbox_min_index_size = 0
# Maximum dbox file size in kilobytes until it's rotated.
#dbox_rotate_size = 2048
# Minimum dbox file size in kilobytes before it's rotated
# (overrides dbox_rotate_days)
#dbox_rotate_min_size = 16
# Maximum dbox file age in days until it's rotated. Day always begins from
# midnight, so 1 = today, 2 = yesterday, etc. 0 = check disabled.
#dbox_rotate_days = 0
# umask to use for mail files and directories
#umask = 0077
# Drop all privileges before exec()ing the mail process. This is mostly
# meant for debugging, otherwise you don't get core dumps. It could be a small
# security risk if you use single UID for multiple users, as the users could
# ptrace() each others processes then.
#mail_drop_priv_before_exec = no
# Set max. process size in megabytes. Most of the memory goes to mmap()ing
# files, so it shouldn't harm much even if this limit is set pretty high.
#mail_process_size = 256
# Log prefix for mail processes. See
# /usr/share/doc/dovecot-common/variables.txt for list of possible variables
#you can use.
#mail_log_prefix = "%Us(%u): "
##
## IMAP specific settings
##
protocol imap {
# Login executable location.
#login_executable = /usr/lib/dovecot/imap-login
# IMAP executable location. Changing this allows you to execute other
# binaries before the imap process is executed.
#
# This would write rawlogs into ~/dovecot.rawlog/ directory:
# mail_executable = /usr/lib/dovecot/rawlog /usr/lib/dovecot/imap
#
# This would attach gdb into the imap process and write backtraces into
# /tmp/gdbhelper.* files:
# mail_executable = /usr/lib/dovecot/gdbhelper /usr/lib/dovecot/imap
#
#mail_executable = /usr/lib/dovecot/imap
# Maximum IMAP command line length in bytes. Some clients generate very long
# command lines with huge mailboxes, so you may need to raise this if you get
# "Too long argument" or "IMAP command line too large" errors often.
#imap_max_line_length = 65536
# Support for dynamically loadable modules.
#mail_use_modules = no
#mail_modules = /usr/lib/dovecot/modules/imap
# Send IMAP capabilities in greeting message. This makes it unnecessary for
# clients to request it with CAPABILITY command, so it saves one round-trip.
# Many clients however don't understand it and ask the CAPABILITY anyway.
#login_greeting_capability = no
# Workarounds for various client bugs:
# delay-newmail:
# Send EXISTS/RECENT new mail notifications only when replying to NOOP
# and CHECK commands. Some clients ignore them otherwise, for example
# OSX Mail. Outlook Express breaks more badly though, without this it
# may show user "Message no longer in server" errors. Note that OE6 still
# breaks even with this workaround if synchronization is set to
# "Headers Only".
# outlook-idle:
# Outlook and Outlook Express never abort IDLE command, so if no mail
# arrives in half a hour, Dovecot closes the connection. This is still
# fine, except Outlook doesn't connect back so you don't see if new mail
# arrives.
# netscape-eoh:
# Netscape 4.x breaks if message headers don't end with the empty "end of
# headers" line. Normally all messages have this, but setting this
# workaround makes sure that Netscape never breaks by adding the line if
# it doesn't exist. This is done only for FETCH BODY[HEADER.FIELDS..]
# commands. Note that RFC says this shouldn't be done.
# tb-extra-mailbox-sep:
# With mbox storage a mailbox can contain either mails or submailboxes,
# but not both. Thunderbird separates these two by forcing server to
# accept '/' suffix in mailbox names in subscriptions list.
# The list is space-separated.
#imap_client_workarounds = outlook-idle
# modified rob@egressive.com 20070519
imap_client_workarounds = outlook-idle
}
##
## POP3 specific settings
##
protocol pop3 {
# Login executable location.
#login_executable = /usr/lib/dovecot/pop3-login
# POP3 executable location
#mail_executable = /usr/lib/dovecot/pop3
# Don't try to set mails non-recent or seen with POP3 sessions. This is
# mostly intended to reduce disk I/O. With maildir it doesn't move files
# from new/ to cur/, with mbox it doesn't write Status-header.
#pop3_no_flag_updates = no
# Support LAST command which exists in old POP3 specs, but has been removed
# from new ones. Some clients still wish to use this though. Enabling this
# makes RSET command clear all \Seen flags from messages.
#pop3_enable_last = no
# POP3 UIDL format to use. You can use following variables:
#
# %v - Mailbox UIDVALIDITY
# %u - Mail UID
# %m - MD5 sum of the mailbox headers in hex (mbox only)
# %f - filename (maildir only)
#
# If you want UIDL compatibility with other POP3 servers, use:
# UW's ipop3d : %08Xv%08Xu
# Courier version 0 : %f
# Courier version 1 : %u
# Courier version 2 : %v-%u
# Cyrus (<= 2.1.3) : %u
# Cyrus (>= 2.1.4) : %v.%u
# Older Dovecots : %v.%u
#
# Note that Outlook 2003 seems to have problems with %v.%u format which was
# Dovecot's default, so if you're building a new server it would be a good
# idea to change this. %08Xu%08Xv should be pretty fail-safe.
#
# NOTE: Nowadays this is required to be set explicitly, since the old
# default was bad but it couldn't be changed without breaking existing
# installations. %08Xu%08Xv will be the new default, so use it for new
# installations.
#
#pop3_uidl_format =
# modified rob@egressive.com 20070519
pop3_uidl_format = %08Xu%08Xv
# POP3 logout format string:
# %t - number of TOP commands
# %T - number of bytes sent to client as a result of TOP command
# %r - number of RETR commands
# %R - number of bytes sent to client as a result of RETR command
# %d - number of deleted messages
# %m - number of messages (before deletion)
# %s - mailbox size in bytes (before deletion)
#pop3_logout_format = top=%t/%T, retr=%r/%R, del=%d/%m, size=%s
# Support for dynamically loadable modules.
#mail_use_modules = no
#mail_modules = /usr/lib/dovecot/modules/pop3
# Workarounds for various client bugs:
# outlook-no-nuls:
# Outlook and Outlook Express hang if mails contain NUL characters.
# This setting replaces them with 0x80 character.
# oe-ns-eoh:
# Outlook Express and Netscape Mail breaks if end of headers-line is
# missing. This option simply sends it if it's missing.
# The list is space-separated.
#pop3_client_workarounds =
# rob@egressive.com 20070519
pop3_client_workarounds = outlook-no-nuls oe-ns-eoh
}
##
## dovecot-lda specific settings
##
# protocol lda {
# If you wish to use plugins you need to specify plugin directory
# For example quota enforcing is implemented by plugin
#module_dir = /usr/local/lib/dovecot/lda
# Address from LDA should send MDNs like out of quota
# postmaster_address = postmaster@your.dom
# If there is no user-specific Sieve-script, global Sieve script is
# executed if set.
#global_script_path =
# UNIX socket path to master authentication server to find users.
#auth_socket_path = /var/run/dovecot-auth-master
# }
##
## Authentication processes
##
# Executable location
#auth_executable = /usr/lib/dovecot/dovecot-auth
# Set max. process size in megabytes.
#auth_process_size = 256
# Authentication cache size in kilobytes. 0 means it's disabled.
# Note that bsdauth, PAM and vpopmail require cache_key to be set for caching
# to be used. Also note that currently auth cache doesn't work very well if
# you're using multiple passdbs with same usernames in them.
#auth_cache_size = 0
# Time to live in seconds for cached data. After this many seconds the cached
# record is no longer used, *except* if the main database lookup returns
# internal failure.
#auth_cache_ttl = 3600
# Space separated list of realms for SASL authentication mechanisms that need
# them. You can leave it empty if you don't want to support multiple realms.
# Many clients simply use the first one listed here, so keep the default realm
# first.
#auth_realms =
# Default realm/domain to use if none was specified. This is used for both
# SASL realms and appending @domain to username in plaintext logins.
#auth_default_realm =
# List of allowed characters in username. If the user-given username contains
# a character not listed in here, the login automatically fails. This is just
# an extra check to make sure user can't exploit any potential quote escaping
# vulnerabilities with SQL/LDAP databases. If you want to allow all characters,
# set this value to empty.
#auth_username_chars = abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01234567890.-_@
# Username character translations before it's looked up from databases. The
# value contains series of from -> to characters. For example "#@/@" means
# that '#' and '/' characters are translated to '@'.
#auth_username_translation =
# Username to use for users logging in with ANONYMOUS SASL mechanism
#auth_anonymous_username = anonymous
# More verbose logging. Useful for figuring out why authentication isn't
# working.
#auth_verbose = no
# Even more verbose logging for debugging purposes. Shows for example SQL
# queries.
#auth_debug = no
# In case of password mismatches, log the passwords and used scheme so the
# problem can be debugged. Requires auth_debug=yes to be set.
#auth_debug_passwords = no
# Maximum number of dovecot-auth worker processes. They're used to execute
# blocking passdb and userdb queries (eg. MySQL and PAM). They're
# automatically created and destroyed as needed.
#auth_worker_max_count = 30
# Kerberos keytab to use for the GSSAPI mechanism. Will use the system
# default (usually /etc/krb5.keytab) if not specified.
#auth_krb5_keytab =
auth default {
# Space separated list of wanted authentication mechanisms:
# plain digest-md5 cram-md5 apop anonymous gssapi
mechanisms = plain
##
## dovecot-lda specific settings
##
# socket listen {
# master {
# path = /var/run/dovecot-auth-master
# mode = 0600
# user = vmail # User running Dovecot LDA
# #group = mail # Or alternatively mode 0660 + LDA user in this group
# }
# }
#
# Password database is used to verify user's password (and nothing more).
# You can have multiple passdbs and userdbs. This is useful if you want to
# allow both system users (/etc/passwd) and virtual users to login without
# duplicating the system users into virtual database.
#
# http://wiki.dovecot.org/Authentication
#
# Users can be temporarily disabled by adding a passdb with deny=yes.
# If the user is found from that database, authentication will fail.
# The deny passdb should always be specified before others, so it gets
# checked first. Here's an example:
#passdb passwd-file {
# File contains a list of usernames, one per line
#args = /etc/dovecot.deny
#deny = yes
#}
# PAM authentication. Preferred nowadays by most systems.
# Note that PAM can only be used to verify if user's password is correct,
# so it can't be used as userdb. If you don't want to use a separate user
# database (passwd usually), you can use static userdb.
passdb pam {
# [session=yes] [cache_key=<key>] [<service name>]
#
# session=yes makes Dovecot open and immediately close PAM session. Some
# PAM plugins need this to work, such as pam_mkhomedir.
#
# cache_key can be used to enable authentication caching for PAM
# (auth_cache_size also needs to be set). It isn't enabled by default
# because PAM modules can do all kinds of checks besides checking password,
# such as checking IP address. Dovecot can't know about these checks
# without some help. cache_key is simply a list of variables (see
# /usr/share/doc/dovecot-common/variables.txt) which must match for the
# cached data to be used.
# Here are some examples:
# %u - Username must match. Probably sufficient for most uses.
# %u%r - Username and remote IP address must match.
# %u%s - Username and service (ie. IMAP, POP3) must match.
#
# If service name is "*", it means the authenticating service name
# is used, eg. pop3 or imap.
#
# Some examples:
# args = session=yes *
# args = cache_key=%u dovecot
#args = dovecot
}
# /etc/passwd or similar, using getpwnam()
# In many systems nowadays this uses Name Service Switch, which is
# configured in /etc/nsswitch.conf.
#passdb passwd {
#}
# /etc/shadow or similiar, using getspnam(). Deprecated by PAM nowadays.
#passdb shadow {
#}
# BSD authentication. Used by at least OpenBSD.
#passdb bsdauth {
# [cache_key=<key>] - See cache_key in PAM for explanation.
#args =
#}
# passwd-like file with specified location
#passdb passwd-file {
# Path for passwd-file
#args =
#}
# checkpassword executable authentication
# NOTE: You will probably want to use "userdb prefetch" with this.
#passdb checkpassword {
# Path for checkpassword binary
#args =
#}
# SQL database
#passdb sql {
# Path for SQL configuration file, see /etc/dovecot/dovecot-sql.conf for
# example
#args =
#}
# LDAP database
#passdb ldap {
# Path for LDAP configuration file, see /etc/dovecot/dovecot-ldap.conf for
# example
#args =
#}
# vpopmail authentication
#passdb vpopmail {
# [cache_key=<key>] - See cache_key in PAM for explanation.
#args =
#}
#
# User database specifies where mails are located and what user/group IDs
# own them. For single-UID configuration use "static".
#
# http://wiki.dovecot.org/Authentication
# http://wiki.dovecot.org/VirtualUsers
#
# /etc/passwd or similar, using getpwnam()
# In many systems nowadays this uses Name Service Switch, which is
# configured in /etc/nsswitch.conf.
userdb passwd {
}
# passwd-like file with specified location
#userdb passwd-file {
# Path for passwd-file
#args =
#}
# static settings generated from template
#userdb static {
# Template for settings. Can return anything a userdb could normally
# return, eg.: uid, gid, home, mail, nice
#
# A few examples:
#
# args = uid=500 gid=500 home=/var/mail/%u
# args = uid=500 gid=500 home=/home/%u mail=mbox:/home/%u/mail nice=10
#
#args =
#}
# SQL database
#userdb sql {
# Path for SQL configuration file, see /etc/dovecot/dovecot-sql.conf for
# example
#args =
#}
# LDAP database
#userdb ldap {
# Path for LDAP configuration file, see /etc/dovecot/dovecot-ldap.conf for
# example
#args =
#}
# vpopmail
#userdb vpopmail {
#}
# "prefetch" user database means that the passdb already provided the
# needed information and there's no need to do a separate userdb lookup.
# This can be made to work with SQL and LDAP databases, see their example
# configuration files for more information how to do it.
# http://wiki.dovecot.org/AuthSpecials
#userdb prefetch {
#}
# User to use for the process. This user needs access to only user and
# password databases, nothing else. Only shadow and pam authentication
# requires roots, so use something else if possible. Note that passwd
# authentication with BSDs internally accesses shadow files, which also
# requires roots. Note that this user is NOT used to access mails.
# That user is specified by userdb above.
user = root
# Directory where to chroot the process. Most authentication backends don't
# work if this is set, and there's no point chrooting if auth_user is root.
# Note that valid_chroot_dirs isn't needed to use this setting.
#chroot =
# Number of authentication processes to create
#count = 1
# Require a valid SSL client certificate or the authentication fails.
#ssl_require_client_cert = no
# Take the username from client's SSL certificate, using X509_NAME_oneline()
# which typically uses subject's Distinguished Name.
#ssl_username_from_cert = no
}
# It's possible to export the authentication interface to other programs,
# for example SMTP server which supports talking to Dovecot. Client socket
# handles the actual authentication - you give it a username and password
# and it returns OK or failure. So it's pretty safe to allow anyone access to
# it. Master socket is used to a) query if given client was successfully
# authenticated, b) userdb lookups.
# listener sockets will be created by Dovecot's master process using the
# settings given inside the auth section
#auth default_with_listener {
# mechanisms = plain
# passdb pam {
# }
# userdb passwd {
# }
# socket listen {
# master {
# path = /var/run/dovecot-auth-master
# # WARNING: Giving untrusted users access to master socket may be a
# # security risk, don't give too wide permissions to it!
# #mode = 0600
# # Default user/group is the one who started dovecot-auth (root)
# #user =
# #group =
# }
# client {
# path = /var/run/dovecot-auth-client
# mode = 0660
# }
# }
#}
# connect sockets are assumed to be already running, Dovecot's master
# process only tries to connect to them. They don't need any other settings
# than path for the master socket, as the configuration is done elsewhere.
# Note that the client sockets must exist in login_dir.
#auth external {
# socket connect {
# master {
# path = /var/run/dovecot-auth-master
# }
# }
#}
plugin {
# Here you can give some extra environment variables to mail processes.
# This is mostly meant for passing parameters to plugins. %variable
# expansion is done for all values.
# Quota plugin
#quota = dirsize:%h/mail
# Convert plugin. If set, specifies the source storage path which is
# converted to destination storage (default_mail_env).
#convert_mail = mbox:%h/mail
}

View file

@ -0,0 +1,2 @@
# MailScanner hold directory
/^Received:/ HOLD

View file

@ -0,0 +1,141 @@
#! /bin/sh
#
# skeleton example file to build /etc/init.d/ scripts.
# This file should be used to construct scripts for /etc/init.d.
#
# Written by Miquel van Smoorenburg <miquels@cistron.nl>.
# Modified for Debian GNU/Linux
# by Ian Murdock <imurdock@gnu.ai.mit.edu>.
#
# Version: @(#)skeleton 1.8 03-Mar-1998 miquels@cistron.nl
#
# This file was automatically customized by dh-make on Fri, 4 Jan 2002 20:05:18 +0100
PATH=/sbin:/bin:/usr/sbin:/usr/bin
NAME=MailScanner
DAEMON=/usr/sbin/$NAME
DESC="mail spam/virus scanner"
CONFFILE=/etc/MailScanner/MailScanner.conf
test -f $DAEMON || exit 0
#set -e
run_mailscanner=0
run_nice=0
if [ -f /etc/default/mailscanner ]; then
. /etc/default/mailscanner
fi
if [ $run_mailscanner = 0 ]; then
if [ -z "$satisfy_nitpicking_on_removal" ]; then
cat <<-EOF
Please edit the file /etc/MailScanner/MailScanner.conf according to
your needs. Then configure sendmail or exim for use with mailscanner.
After you are done you will have to edit /etc/default/mailscanner as
well. There you will have to set the variable run_mailscanner to 1,
and then type "/etc/init.d/mailscanner start" to start the mailscanner
daemon.
EOF
fi
exit 0
fi
# sanity check for permissions
check_dir()
{
if [ ! -d $1 ]; then
echo >&2 "$0: directory $1: does not exist"
exit 1
fi
actual="$(stat -c %U $1)"
if [ "$actual" != "$2" ]; then
echo >&2 "$0: directory $1: wrong owner (expected $2 but is $actual)"
exit 1
fi
actual="$(stat -c %G $1)"
if [ "$actual" != "$3" ]; then
echo >&2 "$0: directory $1: wrong group (expected $3 but is $actual)"
exit 1
fi
}
# modified rob@egressive.com 20070212
check_dir_eg()
{
if [ ! -d $1 ]; then
mkdir -p $1
fi
chown $2:$3 $1
}
user=$(echo $(awk -F= '/^Run As User/ {print $2; exit}' $CONFFILE))
quarantine_group=$(echo $(awk -F= '/^Quarantine Group/ {print $2; exit}' $CONFFILE))
group=$(echo $(awk -F= '/^Run As Group/ {print $2; exit}' $CONFFILE))
# modified rob@egressive.com 20070212
check_dir /var/spool/MailScanner ${user:-mail} ${quarantine_group:-mail}
check_dir /var/lib/MailScanner ${user:-mail} ${group:-mail}
# modified rob@egressive.com 20070212
check_dir_eg /var/run/MailScanner ${user:-mail} ${group:-mail}
check_dir_eg /var/lock/subsys/MailScanner ${user:-mail} ${group:-mail}
case "$1" in
start)
echo -n "Starting $DESC: "
/usr/bin/nice -$run_nice \
start-stop-daemon --start --quiet \
--exec $DAEMON >/dev/null 2>&1
RETVAL=$?
if [ $RETVAL -eq 0 ]; then
touch /var/lock/subsys/mailscanner
rm -f /var/lock/subsys/MailScanner.off
fi
echo "$NAME."
;;
stop)
echo -n "Stopping $DESC: "
start-stop-daemon --stop --quiet \
--name $NAME --quiet >/dev/null 2>&1
RETVAL=$?
if [ $RETVAL -eq 0 ]; then
rm -f /var/lock/subsys/mailscanner
touch /var/lock/subsys/MailScanner.off
fi
if ps axww | grep -i $DAEMON | grep -qv grep; then
echo -n "(waiting"
for i in 1 2 3 4 5 6 7 8 9 10; do
sleep $i
if ! ps axww | grep -i $DAEMON | grep -qv grep; then
break;
fi
echo -n .
done
echo -n ") "
fi
rm -f /var/run/$NAME/*
echo "$NAME."
;;
restart|force-reload)
#
# If the "reload" option is implemented, move the "force-reload"
# option to the "reload" entry above. If not, "force-reload" is
# just the same as "restart".
#
$0 stop
$0 start
;;
*)
N=/etc/init.d/$NAME
# echo "Usage: $N {start|stop|restart|reload|force-reload}" >&2
echo "Usage: $N {start|stop|restart|force-reload}" >&2
exit 1
;;
esac
exit 0

View file

@ -0,0 +1,137 @@
<?
/*
MailWatch for MailScanner
Copyright (C) 2003 Steve Freegard (smf@f2s.com)
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 more 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
*/
///////////////////////////////////////////////////////////////////////////////
// Settings - modify to suit your configuration
///////////////////////////////////////////////////////////////////////////////
// Debug messages
define(DEBUG, false);
// Database settings
define(DB_TYPE, 'mysql');
define(DB_USER, 'mailwatch');
define(DB_PASS, 'eepGur&');
define(DB_HOST, 'localhost');
define(DB_NAME, 'mailscanner');
define(DB_DSN, DB_TYPE.'://'.DB_USER.":".DB_PASS."@".DB_HOST."/".DB_NAME);
// LDAP settings
define(LDAP_HOST,'localhost');
define(LDAP_PORT,'389');
define(LDAP_DN,'o=fsmg');
define(LDAP_SITE,'default');
// Paths
define(MAILWATCH_HOME, '/var/www/mailscanner');
define(MS_CONFIG_DIR, '/etc/MailScanner/');
define(MS_LIB_DIR, '/usr/lib/MailScanner/');
define(CACHE_DIR, './images/cache/'); // JpGraph cache
define(TTF_DIR,'./jpgraph/fonts/'); // JpGraph fonts
define(SA_DIR,'/usr/bin/');
define(SA_RULES_DIR, '/usr/share/spamassassin/');
define(SA_PREFS, MS_CONFIG_DIR.'spam.assassin.prefs.conf');
define(FPDF_FONTPATH,'./fpdf/font/');
// Default number of results on Recent Messages and Message Listing Report
define(MAX_RESULTS, 50);
// Default refresh rate in seconds for the Recent Messages screen
define(STATUS_REFRESH, 30);
// Set the following to a value greater than zero to limit the length of the
// From, To and Subject columns in the 'Recent Messages' screen.
define(FROMTO_MAXLEN, 50);
define(SUBJECT_MAXLEN, 0);
// Date/Time settings
define(DATE_FORMAT, '%d/%m/%y');
define(TIME_FORMAT, '%H:%i:%s');
// Quarantine settings
// The quarantine flag is only available on MailScanner >=4.43
// it will dramtically improved the speed of quarantine operations
// but requires that you use the quarantine_manager.php in place of
// the clean.quarantine script provided with MailScanner.
define(QUARANTINE_USE_FLAG, true);
define(QUARANTINE_DAYS_TO_KEEP, 30);
define(QUARANTINE_MAIL_HOST, '127.0.0.1');
define(QUARANTINE_FROM_ADDR, 'postmaster@DOMAIN_NAME');
define(QUARANTINE_REPORT_FROM_NAME, 'MailWatch for MailScanner');
define(QUARANTINE_REPORT_SUBJECT, 'Message Quarantine Report');
define(QUARANTINE_SUBJECT, 'Message released from quarantine');
define(QUARANTINE_MSG_BODY, 'Please find the original message that was quarantined attached to this mail.
Regards,
Postmaster');
define(QUARANTINE_REPORT_HOSTURL, 'http://'.chop(`hostname`).'/mailscanner/');
define(QUARANTINE_REPORT_DAYS, 7);
define(QUARANTINE_USE_SENDMAIL, false);
define(QUARANTINE_SENDMAIL_PATH, '/usr/sbin/sendmail');
// This turns virus names into links that can be used to get more information
// about a given virus or virus alias. Comment out or set to false to disable.
define(VIRUS_INFO, "http://www.rainingfrogs.co.uk/index.php?virus=%s&search=contains&Search=Search");
// define(VIRUS_INFO, "http://www.viruslist.com/en/find?search_mode=virus&words=%s");
// When filtering data - only use the envelope 'To' address or 'To' domain.
// This greatly increases perfomance as MySQL will not use indexes when
// two different fields are OR'd together.
define(FILTER_TO_ONLY, false);
// Set this to true to hide things that won't work correctly if you have
// a distributed set of MailScanners logging to a single database.
define(DISTRIBUTED_SETUP, false);
// PHP memory limit when viewing details and attachments of messages
// "128M" should be fine in most cases, but you may need to increase it if
// you're having problems viewing the details of large messages
define(MEMORY_LIMIT, "128M");
// RPC-only mode - used primarily for testing (you shouldn't need to enable this)
define(RPC_ONLY, false);
// Display the inbound/outbound mail queue lengths
// Note: this only works with Sendmail & Exim
// You will also need to run mailwatch/mailq.php from cron.
define(MAILQ, false);
// Do you want an audit trail?
define(AUDIT, false);
// Do you want the whitelist/blacklist functionality enabled??
// You'll need to configure MailScanner to use it accordingly.
define(LISTS, true);
// Are we running on MSEE?
define(MSEE, false);
// Force SSL connections only?
define(SSL_ONLY, false);
// Strip HTML from messages in the quarantine when viewed?
// This is probably a good idea...
define(STRIP_HTML, true);
// List of allowed tags - set as blank to strip everything
define(ALLOWED_TAGS, '<a><br><b><body><div><font><h1><h2><h3><h4><head><html><i><li><ol><p><small><span><strong><table><title><tr><td><th><u><ul>');
// Override VIRUS_REGEX??
// define(VIRUS_REGEX, '/(\S+) was infected by (\S+)/'); // SophosSAVI
?>

View file

@ -0,0 +1,2 @@
From: 127.0.0.1 /etc/MailScanner/filename.rules.allowall.conf
FromOrTo: default /etc/MailScanner/filename.rules.conf

View file

@ -0,0 +1 @@
allow .* - -

View file

@ -0,0 +1,2 @@
From: 127.0.0.1 /etc/MailScanner/filetype.rules.allowall.conf
FromOrTo: default /etc/MailScanner/filetype.rules.conf

View file

@ -0,0 +1 @@
allow .* - -

View file

@ -0,0 +1,2 @@
From: 127.0.0.1 no
FromOrTo: default yes

View file

@ -0,0 +1,7 @@
# This is where you can build a Spam WhiteList
# Addresses matching in here, with the value
# "yes" will never be marked as spam.
#From: 152.78. yes
#From: 130.246. yes
From: 127.0.0.1 yes
FromOrTo: default no

View file

@ -0,0 +1,15 @@
include "/etc/bind/rndc.key";
zone "DOMAIN.CO.NZ" {
type master;
file "/var/lib/named/var/cache/bind/DOMAIN.CO.NZ";
allow-update { key "rndc-key"; };
// allow-transfer {192.168.0.0/24; };
};
zone "1.168.192.in-addr.arpa" {
type master;
file "/var/lib/named/var/cache/bind/rev.192.168.1";
allow-update { key "rndc-key"; };
// allow-transfer {192.168.0.0/24; };
};

View file

@ -0,0 +1,314 @@
#
# OpenSSL example configuration file.
# This is mostly being used for generation of certificate requests.
#
# This definition stops the following lines choking if HOME isn't
# defined.
HOME = .
RANDFILE = $ENV::HOME/.rnd
# Extra OBJECT IDENTIFIER info:
#oid_file = $ENV::HOME/.oid
oid_section = new_oids
# To use this configuration file with the "-extfile" option of the
# "openssl x509" utility, name here the section containing the
# X.509v3 extensions to use:
# extensions =
# (Alternatively, use a configuration file that has only
# X.509v3 extensions in its main [= default] section.)
[ new_oids ]
# We can add new OIDs in here for use by 'ca' and 'req'.
# Add a simple OID like this:
# testoid1=1.2.3.4
# Or use config file substitution like this:
# testoid2=${testoid1}.5.6
####################################################################
[ ca ]
default_ca = CA_default # The default ca section
####################################################################
[ CA_default ]
dir = ./demoCA # Where everything is kept
certs = $dir/certs # Where the issued certs are kept
crl_dir = $dir/crl # Where the issued crl are kept
database = $dir/index.txt # database index file.
#unique_subject = no # Set to 'no' to allow creation of
# several ctificates with same subject.
new_certs_dir = $dir/newcerts # default place for new certs.
certificate = $dir/cacert.pem # The CA certificate
serial = $dir/serial # The current serial number
crlnumber = $dir/crlnumber # the current crl number
# must be commented out to leave a V1 CRL
crl = $dir/crl.pem # The current CRL
private_key = $dir/private/cakey.pem# The private key
RANDFILE = $dir/private/.rand # private random number file
x509_extensions = usr_cert # The extentions to add to the cert
# Comment out the following two lines for the "traditional"
# (and highly broken) format.
name_opt = ca_default # Subject Name options
cert_opt = ca_default # Certificate field options
# Extension copying option: use with caution.
# copy_extensions = copy
# Extensions to add to a CRL. Note: Netscape communicator chokes on V2 CRLs
# so this is commented out by default to leave a V1 CRL.
# crlnumber must also be commented out to leave a V1 CRL.
# crl_extensions = crl_ext
default_days = 1825 # how long to certify for
default_crl_days= 30 # how long before next CRL
default_md = sha1 # which md to use.
preserve = no # keep passed DN ordering
# A few difference way of specifying how similar the request should look
# For type CA, the listed attributes must be the same, and the optional
# and supplied fields are just that :-)
policy = policy_match
# For the CA policy
[ policy_match ]
countryName = match
stateOrProvinceName = match
organizationName = match
organizationalUnitName = optional
commonName = supplied
emailAddress = optional
# For the 'anything' policy
# At this point in time, you must list all acceptable 'object'
# types.
[ policy_anything ]
countryName = optional
stateOrProvinceName = optional
localityName = optional
organizationName = optional
organizationalUnitName = optional
commonName = supplied
emailAddress = optional
####################################################################
[ req ]
default_bits = 1024
default_keyfile = privkey.pem
distinguished_name = req_distinguished_name
attributes = req_attributes
x509_extensions = v3_ca # The extentions to add to the self signed cert
# Passwords for private keys if not present they will be prompted for
# input_password = secret
# output_password = secret
# This sets a mask for permitted string types. There are several options.
# default: PrintableString, T61String, BMPString.
# pkix : PrintableString, BMPString.
# utf8only: only UTF8Strings.
# nombstr : PrintableString, T61String (no BMPStrings or UTF8Strings).
# MASK:XXXX a literal mask value.
# WARNING: current versions of Netscape crash on BMPStrings or UTF8Strings
# so use this option with caution!
string_mask = nombstr
# req_extensions = v3_req # The extensions to add to a certificate request
[ req_distinguished_name ]
countryName = Country Name (2 letter code)
countryName_default = NZ
countryName_min = 2
countryName_max = 2
stateOrProvinceName = State or Province Name (full name)
stateOrProvinceName_default = Canterbury
localityName = Locality Name (eg, city)
localityName_default = Christchurch
0.organizationName = Organization Name (eg, company)
0.organizationName_default = Internet Widgits Pty Ltd
# we can do this but it is not needed normally :-)
#1.organizationName = Second Organization Name (eg, company)
#1.organizationName_default = World Wide Web Pty Ltd
organizationalUnitName = Organizational Unit Name (eg, section)
#organizationalUnitName_default =
commonName = Common Name (eg, YOUR name)
commonName_max = 64
emailAddress = Email Address
emailAddress_max = 64
# SET-ex3 = SET extension number 3
[ req_attributes ]
challengePassword = A challenge password
challengePassword_min = 4
challengePassword_max = 20
unstructuredName = An optional company name
[ usr_cert ]
# These extensions are added when 'ca' signs a request.
# This goes against PKIX guidelines but some CAs do it and some software
# requires this to avoid interpreting an end user certificate as a CA.
basicConstraints=CA:FALSE
# Here are some examples of the usage of nsCertType. If it is omitted
# the certificate can be used for anything *except* object signing.
# This is OK for an SSL server.
# nsCertType = server
# For an object signing certificate this would be used.
# nsCertType = objsign
# For normal client use this is typical
# nsCertType = client, email
# and for everything including object signing:
# nsCertType = client, email, objsign
# This is typical in keyUsage for a client certificate.
# keyUsage = nonRepudiation, digitalSignature, keyEncipherment
# This will be displayed in Netscape's comment listbox.
nsComment = "OpenSSL Generated Certificate"
# PKIX recommendations harmless if included in all certificates.
subjectKeyIdentifier=hash
authorityKeyIdentifier=keyid,issuer
# This stuff is for subjectAltName and issuerAltname.
# Import the email address.
# subjectAltName=email:copy
# An alternative to produce certificates that aren't
# deprecated according to PKIX.
# subjectAltName=email:move
# Copy subject details
# issuerAltName=issuer:copy
#nsCaRevocationUrl = http://www.domain.dom/ca-crl.pem
#nsBaseUrl
#nsRevocationUrl
#nsRenewalUrl
#nsCaPolicyUrl
#nsSslServerName
[ v3_req ]
# Extensions to add to a certificate request
basicConstraints = CA:FALSE
keyUsage = nonRepudiation, digitalSignature, keyEncipherment
[ v3_ca ]
# Extensions for a typical CA
# PKIX recommendation.
subjectKeyIdentifier=hash
authorityKeyIdentifier=keyid:always,issuer:always
# This is what PKIX recommends but some broken software chokes on critical
# extensions.
#basicConstraints = critical,CA:true
# So we do this instead.
basicConstraints = CA:true
# Key usage: this is typical for a CA certificate. However since it will
# prevent it being used as an test self-signed certificate it is best
# left out by default.
# keyUsage = cRLSign, keyCertSign
# Some might want this also
# nsCertType = sslCA, emailCA
# Include email address in subject alt name: another PKIX recommendation
# subjectAltName=email:copy
# Copy issuer details
# issuerAltName=issuer:copy
# DER hex encoding of an extension: beware experts only!
# obj=DER:02:03
# Where 'obj' is a standard or added object
# You can even override a supported extension:
# basicConstraints= critical, DER:30:03:01:01:FF
[ crl_ext ]
# CRL extensions.
# Only issuerAltName and authorityKeyIdentifier make any sense in a CRL.
# issuerAltName=issuer:copy
authorityKeyIdentifier=keyid:always,issuer:always
[ proxy_cert_ext ]
# These extensions should be added when creating a proxy certificate
# This goes against PKIX guidelines but some CAs do it and some software
# requires this to avoid interpreting an end user certificate as a CA.
basicConstraints=CA:FALSE
# Here are some examples of the usage of nsCertType. If it is omitted
# the certificate can be used for anything *except* object signing.
# This is OK for an SSL server.
# nsCertType = server
# For an object signing certificate this would be used.
# nsCertType = objsign
# For normal client use this is typical
# nsCertType = client, email
# and for everything including object signing:
# nsCertType = client, email, objsign
# This is typical in keyUsage for a client certificate.
# keyUsage = nonRepudiation, digitalSignature, keyEncipherment
# This will be displayed in Netscape's comment listbox.
nsComment = "OpenSSL Generated Certificate"
# PKIX recommendations harmless if included in all certificates.
subjectKeyIdentifier=hash
authorityKeyIdentifier=keyid,issuer:always
# This stuff is for subjectAltName and issuerAltname.
# Import the email address.
# subjectAltName=email:copy
# An alternative to produce certificates that aren't
# deprecated according to PKIX.
# subjectAltName=email:move
# Copy subject details
# issuerAltName=issuer:copy
#nsCaRevocationUrl = http://www.domain.dom/ca-crl.pem
#nsBaseUrl
#nsRevocationUrl
#nsRenewalUrl
#nsCaPolicyUrl
#nsSslServerName
# This really needs to be in place for it to be a proxy certificate.
proxyCertInfo=critical,language:id-ppl-anyLanguage,pathlen:3,policy:foo

View file

@ -0,0 +1,291 @@
#################################################
# Sample OpenVPN 2.0 config file for #
# multi-client server. #
# #
# This file is for the server side #
# of a many-clients <-> one-server #
# OpenVPN configuration. #
# #
# OpenVPN also supports #
# single-machine <-> single-machine #
# configurations (See the Examples page #
# on the web site for more info). #
# #
# This config should work on Windows #
# or Linux/BSD systems. Remember on #
# Windows to quote pathnames and use #
# double backslashes, e.g.: #
# "C:\\Program Files\\OpenVPN\\config\\foo.key" #
# #
# Comments are preceded with '#' or ';' #
#################################################
# Which local IP address should OpenVPN
# listen on? (optional)
;local a.b.c.d
# Which TCP/UDP port should OpenVPN listen on?
# If you want to run multiple OpenVPN instances
# on the same machine, use a different port
# number for each one. You will need to
# open up this port on your firewall.
port 1194
# TCP or UDP server?
;proto tcp
proto udp
# "dev tun" will create a routed IP tunnel,
# "dev tap" will create an ethernet tunnel.
# Use "dev tap0" if you are ethernet bridging
# and have precreated a tap0 virtual interface
# and bridged it with your ethernet interface.
# If you want to control access policies
# over the VPN, you must create firewall
# rules for the the TUN/TAP interface.
# On non-Windows systems, you can give
# an explicit unit number, such as tun0.
# On Windows, use "dev-node" for this.
# On most systems, the VPN will not function
# unless you partially or fully disable
# the firewall for the TUN/TAP interface.
dev tap
;dev tun
# Windows needs the TAP-Win32 adapter name
# from the Network Connections panel if you
# have more than one. On XP SP2 or higher,
# you may need to selectively disable the
# Windows firewall for the TAP adapter.
# Non-Windows systems usually don't need this.
;dev-node MyTap
# SSL/TLS root certificate (ca), certificate
# (cert), and private key (key). Each client
# and the server must have their own cert and
# key file. The server and all clients will
# use the same ca file.
#
# See the "easy-rsa" directory for a series
# of scripts for generating RSA certificates
# and private keys. Remember to use
# a unique Common Name for the server
# and each of the client certificates.
#
# Any X509 key management system can be used.
# OpenVPN can also use a PKCS #12 formatted key file
# (see "pkcs12" directive in man page).
ca keys/ca.crt
cert keys/server.crt
key keys/server.key # This file should be kept secret
# Diffie hellman parameters.
# Generate your own with:
# openssl dhparam -out dh1024.pem 1024
# Substitute 2048 for 1024 if you are using
# 2048 bit keys.
dh keys/dh1024.pem
# Configure server mode and supply a VPN subnet
# for OpenVPN to draw client addresses from.
# The server will take 10.8.0.1 for itself,
# the rest will be made available to clients.
# Each client will be able to reach the server
# on 10.8.0.1. Comment this line out if you are
# ethernet bridging. See the man page for more info.
server 10.8.0.0 255.255.255.0
# Maintain a record of client <-> virtual IP address
# associations in this file. If OpenVPN goes down or
# is restarted, reconnecting clients can be assigned
# the same virtual IP address from the pool that was
# previously assigned.
ifconfig-pool-persist ipp.txt
# Configure server mode for ethernet bridging.
# You must first use your OS's bridging capability
# to bridge the TAP interface with the ethernet
# NIC interface. Then you must manually set the
# IP/netmask on the bridge interface, here we
# assume 10.8.0.4/255.255.255.0. Finally we
# must set aside an IP range in this subnet
# (start=10.8.0.50 end=10.8.0.100) to allocate
# to connecting clients. Leave this line commented
# out unless you are ethernet bridging.
;server-bridge 10.8.0.4 255.255.255.0 10.8.0.50 10.8.0.100
# Push routes to the client to allow it
# to reach other private subnets behind
# the server. Remember that these
# private subnets will also need
# to know to route the OpenVPN client
# address pool (10.8.0.0/255.255.255.0)
# back to the OpenVPN server.
;push "route 192.168.10.0 255.255.255.0"
push "route 192.168.1.0 255.255.255.0"
# To assign specific IP addresses to specific
# clients or if a connecting client has a private
# subnet behind it that should also have VPN access,
# use the subdirectory "ccd" for client-specific
# configuration files (see man page for more info).
# EXAMPLE: Suppose the client
# having the certificate common name "Thelonious"
# also has a small subnet behind his connecting
# machine, such as 192.168.40.128/255.255.255.248.
# First, uncomment out these lines:
;client-config-dir ccd
;route 192.168.40.128 255.255.255.248
# Then create a file ccd/Thelonious with this line:
# iroute 192.168.40.128 255.255.255.248
# This will allow Thelonious' private subnet to
# access the VPN. This example will only work
# if you are routing, not bridging, i.e. you are
# using "dev tun" and "server" directives.
# EXAMPLE: Suppose you want to give
# Thelonious a fixed VPN IP address of 10.9.0.1.
# First uncomment out these lines:
;client-config-dir ccd
;route 10.9.0.0 255.255.255.252
# Then add this line to ccd/Thelonious:
# ifconfig-push 10.9.0.1 10.9.0.2
# Suppose that you want to enable different
# firewall access policies for different groups
# of clients. There are two methods:
# (1) Run multiple OpenVPN daemons, one for each
# group, and firewall the TUN/TAP interface
# for each group/daemon appropriately.
# (2) (Advanced) Create a script to dynamically
# modify the firewall in response to access
# from different clients. See man
# page for more info on learn-address script.
;learn-address ./script
# If enabled, this directive will configure
# all clients to redirect their default
# network gateway through the VPN, causing
# all IP traffic such as web browsing and
# and DNS lookups to go through the VPN
# (The OpenVPN server machine may need to NAT
# the TUN/TAP interface to the internet in
# order for this to work properly).
# CAVEAT: May break client's network config if
# client's local DHCP server packets get routed
# through the tunnel. Solution: make sure
# client's local DHCP server is reachable via
# a more specific route than the default route
# of 0.0.0.0/0.0.0.0.
;push "redirect-gateway"
# Certain Windows-specific network settings
# can be pushed to clients, such as DNS
# or WINS server addresses. CAVEAT:
# http://openvpn.net/faq.html#dhcpcaveats
;push "dhcp-option DNS 10.8.0.1"
;push "dhcp-option WINS 10.8.0.1"
# Uncomment this directive to allow different
# clients to be able to "see" each other.
# By default, clients will only see the server.
# To force clients to only see the server, you
# will also need to appropriately firewall the
# server's TUN/TAP interface.
;client-to-client
# Uncomment this directive if multiple clients
# might connect with the same certificate/key
# files or common names. This is recommended
# only for testing purposes. For production use,
# each client should have its own certificate/key
# pair.
#
# IF YOU HAVE NOT GENERATED INDIVIDUAL
# CERTIFICATE/KEY PAIRS FOR EACH CLIENT,
# EACH HAVING ITS OWN UNIQUE "COMMON NAME",
# UNCOMMENT THIS LINE OUT.
;duplicate-cn
# The keepalive directive causes ping-like
# messages to be sent back and forth over
# the link so that each side knows when
# the other side has gone down.
# Ping every 10 seconds, assume that remote
# peer is down if no ping received during
# a 120 second time period.
keepalive 10 120
# For extra security beyond that provided
# by SSL/TLS, create an "HMAC firewall"
# to help block DoS attacks and UDP port flooding.
#
# Generate with:
# openvpn --genkey --secret ta.key
#
# The server and each client must have
# a copy of this key.
# The second parameter should be '0'
# on the server and '1' on the clients.
;tls-auth ta.key 0 # This file is secret
# Select a cryptographic cipher.
# This config item must be copied to
# the client config file as well.
;cipher BF-CBC # Blowfish (default)
;cipher AES-128-CBC # AES
;cipher DES-EDE3-CBC # Triple-DES
# Enable compression on the VPN link.
# If you enable it here, you must also
# enable it in the client config file.
comp-lzo
# The maximum number of concurrently connected
# clients we want to allow.
;max-clients 100
# It's a good idea to reduce the OpenVPN
# daemon's privileges after initialization.
#
# You can uncomment this out on
# non-Windows systems.
user nobody
group nogroup
# The persist options will try to avoid
# accessing certain resources on restart
# that may no longer be accessible because
# of the privilege downgrade.
persist-key
persist-tun
# Output a short status file showing
# current connections, truncated
# and rewritten every minute.
status openvpn-status.log
# By default, log messages will go to the syslog (or
# on Windows, if running as a service, they will go to
# the "\Program Files\OpenVPN\log" directory).
# Use log or log-append to override this default.
# "log" will truncate the log file on OpenVPN startup,
# while "log-append" will append to it. Use one
# or the other (but not both).
;log openvpn.log
;log-append openvpn.log
# Set the appropriate level of log
# file verbosity.
#
# 0 is silent, except for fatal errors
# 4 is reasonable for general usage
# 5 and 6 can help to debug connection problems
# 9 is extremely verbose
verb 3
# Silence repeating messages. At most 20
# sequential messages of the same message
# category will be output to the log.
;mute 20

View file

@ -0,0 +1,49 @@
# easy-rsa parameter settings
# NOTE: If you installed from an RPM,
# don't edit this file in place in
# /usr/share/openvpn/easy-rsa --
# instead, you should copy the whole
# easy-rsa directory to another location
# (such as /etc/openvpn) so that your
# edits will not be wiped out by a future
# OpenVPN package upgrade.
# This variable should point to
# the top level of the easy-rsa
# tree.
export D=`pwd`
# This variable should point to
# the openssl.cnf file included
# with easy-rsa.
export KEY_CONFIG=$D/openssl.cnf
# Edit this variable to point to
# your soon-to-be-created key
# directory.
#
# WARNING: clean-all will do
# a rm -rf on this directory
# so make sure you define
# it correctly!
export KEY_DIR=$D/../keys
# Issue rm -rf warning
echo NOTE: when you run ./clean-all, I will be doing a rm -rf on $KEY_DIR
# Increase this to 2048 if you
# are paranoid. This will slow
# down TLS negotiation performance
# as well as the one-time DH parms
# generation process.
export KEY_SIZE=1024
# These are the default values for fields
# which will be placed in the certificate.
# Don't leave any of these fields blank.
export KEY_COUNTRY=NZ
export KEY_PROVINCE=Canterbury
export KEY_CITY=Christchurch
export KEY_ORG="Limited"
export KEY_EMAIL="support@egressive.com"

View file

@ -0,0 +1,7 @@
<Limit LOGIN>
Order allow,deny
Allow from localhost
Deny from all
</Limit>

View file

@ -0,0 +1,11 @@
$TTL 86400 ; 1 day
1.168.192.in-addr.arpa. IN SOA ns1.DOMAIN.CO.NZ. support@egressive.com. (
2007052001 ; serial
604800 ; refresh (1 week)
86400 ; retry (1 day)
2419200 ; expire (4 weeks)
86400 ; minimum (1 day)
)
NS ns1.DOMAIN.CO.NZ.
$ORIGIN 8.168.192.in-addr.arpa.
1 PTR mail.DOMAIN.CO.NZ.

View file

@ -0,0 +1,138 @@
#======================= Global Settings =======================
[global]
workgroup = DOMAIN_NAME
# server string is the equivalent of the NT Description field
server string = SERVER_STRING
wins support = yes
dns proxy = no
time server = yes
netbios name = NETBIOS_NAME
#### Networking ####
; interfaces = 127.0.0.0/8 eth0
;;;; bind interfaces only = true
#### Debugging/Accounting ####
log file = /var/log/samba/log.%m
max log size = 1000
syslog = 0
panic action = /usr/share/samba/panic-action %d
log level = 3
####### Authentication #######
; security = user
encrypt passwords = true
passdb backend = tdbsam
obey pam restrictions = yes
passwd program = /usr/bin/passwd %u
# modified rob@egressive.com 20070213 to make sure users can change password
# passwd chat = *Enter\snew\sUNIX\spassword:* %n\n *Retype\snew\sUNIX\spassword:* %n\n *password\supdated\ssuccessfully* .
passwd chat = *password:* %n\n *password:* %n\n *success*
unix password sync = yes
########## Domains ###########
domain logons = yes
logon drive = H:
logon path = \\%N\profiles\%U
logon script = %U.cmd
domain master = yes
preferred master = yes
enable privileges = yes
#
# Scripts
#
add user script = /usr/sbin/useradd -m %u
delete user script = /usr/sbin/userdel -r %u
add group script = /usr/sbin/groupadd %g
delete group script = /usr/sbin/groupdel %g
add user to group script = /usr/sbin/usermod -G %g %u
add machine script = /usr/sbin/useradd -s /bin/false/ -d /var/lib/nobody %u
#
# Winbind
#
idmap uid = 10000-20000
idmap gid = 10000-20000
template shell = /bin/bash
########## Misc ###########
socket options = TCP_NODELAY
# added rob@egressive.com 20070226
# PDB and PNX are used by profax - attempt to sort out speed issues
level2 oplocks = yes
oplocks = yes
veto oplock files = /*.mdb/*.MDB/*.ldb/*.LDB/*.dbf/*.DBF/*.pdb/*.PDB/*.pnx/*.PNX/
######### Printing ########
load printers = yes
printing = cups
printcap name = CUPS
cups options = Raw
#======================= Share Definitions =======================
[homes]
comment = Home Directories
browseable = no
valid users = %S
writable = yes
create mask = 0600
directory mask = 0700
[netlogon]
comment = Network Logon Service
path = /home/samba/netlogon
admin users = Administrator
valid users = %U
guest ok = yes
writable = no
share modes = no
[profiles]
comment = User Profiles
path = /home/samba/profiles
valid users = %U
guest ok = no
browseable = no
create mask = 0640
directory mask = 0750
writable = yes
[profdata]
comment = User Profile Data
path = /home/samba/profdata
valid users = %U
guest ok = no
browseable = no
create mask = 0660
directory mask = 0770
writable = yes
#[printers]
# comment = All Printers
# browseable = no
# path = /var/spool/samba
# printable = yes
# guest ok = yes
# rob@egresisve.com 20070213
; public = no
; writable = no
; create mode = 0700
#[print$]
# comment = Printer Drivers
## path = /var/lib/samba/printers
# browseable = no
# writable = yes
# guest ok = no
[printers]
comment = All Printers
browseable = no
path = /var/spool/samba
printable = yes
public = no
writable = no
create mode = 0700
# Windows clients look for this share name as a source of downloadable
# printer drivers
[print$]
comment = Printer Drivers
path = /var/lib/samba/printers
browseable = yes
read only = yes
guest ok = no
# Uncomment to allow remote administration of Windows print drivers.
# Replace 'ntadmin' with the name of the group your admin users are
# members of.
write list = root, @domainadmins

View file

@ -0,0 +1,39 @@
#
# deb cdrom:[Ubuntu-Server 6.06.1 _Feisty Drake_ - Release i386 (20060807.1)]/ feisty main restricted
#deb cdrom:[Ubuntu-Server 6.06.1 _Feisty Drake_ - Release i386 (20060807.1)]/ feisty main restricted
deb http://debcache.unleash.net.nz:9999/ubuntu/ feisty main restricted
deb-src http://debcache.unleash.net.nz:9999/ubuntu/ feisty main restricted
## Major bug fix updates produced after the final release of the
## distribution.
deb http://debcache.unleash.net.nz:9999/ubuntu/ feisty-updates main restricted
deb-src http://debcache.unleash.net.nz:9999/ubuntu/ feisty-updates main restricted
## Uncomment the following two lines to add software from the 'universe'
## repository.
## N.B. software from this repository is ENTIRELY UNSUPPORTED by the Ubuntu
## team, and may not be under a free licence. Please satisfy yourself as to
## your rights to use the software. Also, please note that software in
## universe WILL NOT receive any review or updates from the Ubuntu security
## team.
deb http://debcache.unleash.net.nz:9999/ubuntu/ feisty universe
deb-src http://debcache.unleash.net.nz:9999/ubuntu/ feisty universe
## Uncomment the following two lines to add software from the 'backports'
## repository.
## N.B. software from this repository may not have been tested as
## extensively as that contained in the main release, although it includes
## newer versions of some applications which may provide useful features.
## Also, please note that software in backports WILL NOT receive any review
## or updates from the Ubuntu security team.
deb http://debcache.unleash.net.nz:9999/ubuntu/ feisty-backports main restricted universe multiverse
deb-src http://debcache.unleash.net.nz:9999/ubuntu/ feisty-backports main restricted universe multiverse
deb http://debcache.unleash.net.nz:9999/ubuntu feisty-security main restricted
deb-src http://debcache.unleash.net.nz:9999/ubuntu feisty-security main restricted
deb http://debcache.unleash.net.nz:9999/ubuntu feisty-security universe
deb-src http://debcache.unleash.net.nz:9999/ubuntu feisty-security universe

View file

@ -0,0 +1,296 @@
# =============== MailScanner: spam.assassin.prefs.conf ===============
# Version 2.13.1
# SpamAssassin preferences for MailScanner users should be placed in
# this file to avoid being overwritten by a SpamAssassin upgrade.
# For a complete listing of configurable parameters, please see:
# http://www.spamassassin.org/doc/Mail_SpamAssassin_Conf.html
# =============== SpamAssassin Preferences ===============
#
# the file installed by SpamAssassin:
# /etc/mail/spamassassin/local.cf
# Should be disabled
# typically use these commands:
# mv /etc/mail/spamassassin/local.cf \
# /etc/mail/spamassassin/local.cf.saved
# When running SpamAssassin or sa-learn from the command line,
# or a script, you should always specify that SpamAssassin use
# this file to load SpamAssassin preferences, i.e:
# sa-learn --ham -p /etc/MailScanner/spam.assassin.prefs.conf \
# --mbox ham_mbox
# spamassassin -D -p etc/MailScanner/spam.assassin.prefs.conf \
# --lint
# Additional SpamAssassin rule files should be placed in:
# /etc/mail/spamassasssin (default location)
# or in the directory specified in MailScanner.conf setting:
# SpamAssassin Local Rules Dir =
# dns_available { yes | test[: name1 name2...] | no } (default: test)
# By default, SpamAssassin will query some default hosts on the internet
# to attempt to check if DNS is working on not. The problem is that it can
# introduce some delay if your network connection is down, and in some
# cases it can wrongly guess that DNS is unavailable because the test
# connections failed. SpamAssassin includes a default set of 13 servers,
# among which 3 are picked randomly.
dns_available yes
# =============== White list and Black list addresses ===============
# While you can white list here but see below for a better place.
# White list addresses should be added in
# /etc/MailScanner/rules/spam.whitelist.rules
# Black list addresses should be added in
# /etc/MailScanner/rules/spam.blacklist.rules
# FSL Notes: we need to set the default rule for:
# Is Definitely Spam = no
# to:
# %rules-dir/spam.blacklist.rules
# and create a default rules-dir/spam.blacklist.rules file
# =============== OK Locales ===============
ok_locales en
# FSL Notes: we only support English this is unnecessary
# =============== Bayesian Filtering ===============
# By default, the Bayesian engine is used. This is a real CPU hog
# and uses a lot of system resources to work.
# On a small overloaded system, you might need to disable it.
# use_bayes 0
# If your root filesystem is filling up because SpamAssassin is putting
# large databases in /.spamassassin or /root/.spamassassin, you can
# move them using the following lines to point to their new locations.
# The last part of the path is not a directory name, but actually the
# start of the filenames. So with the settings below, the Bayes files
# will be created as /var/spool/spamassassin/bayes_msgcount, etc.
# FSL Note: we need to coordinate the Bayes File Placement
# With MailWatch
bayes_path /var/spool/MailScanner/spamassassin/bayes
# This is actually used as a mask, not a raw chmod setting.
# Thanks for Matt Kettler for spotting this one.
bayes_file_mode 0660
# Bump up SpamAssassin scores on the high and low end
# score BAYES_00 -15.0
# score BAYES_05 -5.0
score BAYES_95 5.0
score BAYES_99 15.0
# To disable bayes autolearn
# bayes_auto_learn 0
# For feeding spam and and ham for saved messages, mailboxes
# or directories:
# This MUST be customized for each site :(
# Change unconfigured-debian-site to match your %org-name% as
# set in MailScanner.conf
bayes_ignore_header ORG_NAME-MailScanner
bayes_ignore_header ORG_NAME-MailScanner-SpamCheck
bayes_ignore_header ORG_NAME-MailScanner-SpamScore
bayes_ignore_header ORG_NAME-MailScanner-Information
# When using the scheduled Bayes expiry feature, in MailScanner.conf
# you probably want to turn off auto-expiry in SpamAssassin as it will
# rarely complete before it is killed for taking too long.
# You will just end up with # MailScanner: big bayes_toks.new files
# wasting space.
# FSL Note: we run Bayes expire from a cron job
bayes_auto_expire 0
# If you are using a UNIX machine with all database files on local disks,
# and no sharing of those databases across NFS filesystems, you can use a
# more efficient, but non-NFS-safe, locking mechanism. Do this by adding
# the line "lock_method flock" to the /etc/mail/spamassassin/local.cf
# file. This is strongly recommended if you're not using NFS, as it is
# much faster than the NFS-safe locker.
lock_method flock
# The --auto-whitelist and -a options for "spamd" and "spamassassin" to
# turn on the auto-whitelist have been removed and replaced by the
# "use_auto_whitelist" configuration option which is also now turned on by
# default.
use_auto_whitelist 0
# =============== RBSL related items ===============
# By default, SpamAssassin will run RBL checks. If your ISP already
# does this, stop RBL checks in SpamAssassin by un-commenting the
# following line
# skip_rbl_checks 1
# paths to utilities
pyzor_path /usr/bin/pyzor
dcc_path /usr/bin/dccproc
# Uncomment the lines below to stop using the specific service
# To stop Razor2 checks, uncomment the following line
# use_razor2 0
# To stop DCC checks, uncomment the following line
# use_dcc 0
# To stop Pyzor checks, uncomment the following line
# use_pyzor 0
# The timeouts for blacklists and Razor are rather generous in the
# default state that SpamAssassin is shipped. Reducing these
# stops a lot of timeouts from removing SpamAssassin scores
# altogether.
rbl_timeout 20
razor_timeout 10
pyzor_timeout 10
# If you specify these scores, SpamAssassin will do RBL checks as well
# as MailScanner, which just wastes CPU power and network bandwidth.
# Either do them here by un-commenting the rules below
# (if you have paid for them) or else uncomment the "skip_rbl_checks" #
# line above and let MailScanner do the checks instead.
score RCVD_IN_BL_SPAMCOP_NET 4
# These next 3 will cost you money, see mailscanner.conf.
#score RCVD_IN_RBL 10
#score RCVD_IN_RSS 1
#score RCVD_IN_DUL 1
# =============== SpamAssassin Header Processing ===============
# SpamAssassin will attempt to discover the address used in the 'MAIL FROM:'
# phase of the SMTP transaction that delivered this message, if this data
# has been made available by the SMTP server. This is used in the EnvelopeFrom
# pseudo-header, and for various rules such as SPF checking.
# This should be explicitly set for MailScanner
envelope_sender_header X-MailScanner-From
# =============== Adding SpamAssassin Rules ===============
# Add your own customized scores for some tests below. The default
# scores are read from the installed "spamassassin.cf" file, but you
# can override or disable the here.
# To see the list of tests and their default scores, go to
# http://spamassassin.taint.org/tests.html
# These next 3 lines will add a local rule to SpamAssassin to help
# protect you from the friendlygreetings.com nasty-gram which will
# send lots of spam from your PC if you let it. Not really a virus,
# but you don't want your users all clicking on it.
header FRIEND_GREETINGS Subject =~ /you have an E-Card from/i
describe FRIEND_GREETINGS Nasty E-card from FriendGreetings.com
score FRIEND_GREETINGS 100.0
header FRIEND_GREETINGS2 Subject =~ /you have a greeting card from/i
describe FRIEND_GREETINGS2 Nasty E-card from FriendGreetings.com
score FRIEND_GREETINGS2 100.0
# =============== Disable SpamAssassin Rules ===============
# To disable a SpamAssassin rule simply add an uncommented
# line similar to:
# score SUBJ_ILLEGAL_CHARS 0.0
# =============== Change SpamAssassin Rules scores ===============
# To Change a SpamAssassin rule Score simply add an uncommented
# line similar to:
# score SUBJ_ILLEGAL_CHARS 2.1
# =============== Special Case Rules ===============
# IE explorer spoofing
uri IE_VULN /%([01][0-9a-f]|7f).*@/i
score IE_VULN 100.0
describe IE_VULN Internet Explorer vulnerability
# added Mon Jan 12 16:14:04 EST 2004 to stop the forgers of
# Not needed ins SA 3.0
# HABEAUS headers
# score HABEAS_SWE -2.0
#### Special Case Rules #####
# =============== Historic Rules ===============
# Osirusoft RBSL is dead
# score RCVD_IN_OSIRUSOFT_COM 0.0
# score X_OSIRU_OPEN_RELAY 0.0
# score X_OSIRU_DUL 0.0
# score X_OSIRU_SPAM_SRC 0.0
# score X_OSIRU_SPAMWARE_SITE 0.0
# score X_OSIRU_DUL_FH 0.0
# score RCVD_IN_RFCI 0.0
# score DNS_FROM_RFCI_DSN 0.0
# =============== Your Edits Go Here ===============
score RCVD_IN_RSL 0
# Steve@fsl.com edit Sun Jan 16 12:17:16 CST 2005
# disable the ALL_TRUSTED ruleset that comes with SA 3.x.
# It's generating too many false positives
# If you have problems where ALL_TRUSTED is matching external email,
# including spam, then SpamAssassin has become confused about which hosts are
# a part of your trusted_networks. The most common cause of this is having a
# gateway mail exchanger that has a reserved IP and gets NATed by your
# firewall. Fortunately the problem is easy to fix by manually declaring a
# trusted_networks setting. See man Mail::SpamAssassin::Conf for details.
# Once manually set, SA won't try to guess.
#
# If that does not fix your problem, the other possibility is you have an MTA
# that generates malformed Received: headers. If you've modified your
# Received: header format, please put it back to the standard format.
# SpamAssassin is quite tolerant of deviations from the RFC 2822 format, but
# there are some combinations it can't handle. If the malformed headers are
# being made by some form of network appliance that you can't fix, report a
# bug to your vendor, and as a short-term fix set the score of ALL_TRUSTED to
# 0. However, realize that other problems may occur as a result of the
# mis-parsed headers and the root cause does need fixing.
#
#score ALL_TRUSTED 0
pyzor_options --homedir /var/spool/postfix/
razor_config /var/spool/postfix/.razor/razor-agent.conf
trusted_networks 192.168.1.0/24 127.0.0.1

File diff suppressed because it is too large Load diff