diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..cbb3a13 --- /dev/null +++ b/.gitignore @@ -0,0 +1,4 @@ +*.rpm +*.log +*spec-20* +*.tar.gz diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..67656b4 --- /dev/null +++ b/Makefile @@ -0,0 +1,21 @@ +# Makefile for source rpm: smeserver-learn +# $Id: Makefile,v 1.1 2020/12/20 11:47:11 brianr Exp $ +NAME := smeserver-learn +SPECFILE = $(firstword $(wildcard *.spec)) + +define find-makefile-common +for d in common ../common ../../common ; do if [ -f $$d/Makefile.common ] ; then if [ -f $$d/CVS/Root -a -w $$/Makefile.common ] ; then cd $$d ; cvs -Q update ; fi ; echo "$$d/Makefile.common" ; break ; fi ; done +endef + +MAKEFILE_COMMON := $(shell $(find-makefile-common)) + +ifeq ($(MAKEFILE_COMMON),) +# attept a checkout +define checkout-makefile-common +test -f CVS/Root && { cvs -Q -d $$(cat CVS/Root) checkout common && echo "common/Makefile.common" ; } || { echo "ERROR: I can't figure out how to checkout the 'common' module." ; exit -1 ; } >&2 +endef + +MAKEFILE_COMMON := $(shell $(checkout-makefile-common)) +endif + +include $(MAKEFILE_COMMON) diff --git a/README.md b/README.md index fae3789..2ec9bf8 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,16 @@ -# smeserver-learn +# smeserver-learn -SMEServer Koozali developed git repo for smeserver-learn smecontribs \ No newline at end of file +SMEServer Koozali developed git repo for smeserver-learn smecontribs + +## Wiki +
https://wiki.koozali.org/Learn +
https://wiki.koozali.org/Learn/fr + +## Bugzilla +Show list of outstanding bugs: [here](https://bugs.koozali.org/buglist.cgi?component=smeserver-learn&product=SME%20Contribs&query_format=advanced&limit=0&bug_status=UNCONFIRMED&bug_status=NEW&bug_status=ASSIGNED&bug_status=REOPENED&bug_status=CONFIRMED) + +## Description + +
*This description has been generated by an LLM AI system and cannot be relied on to be fully correct.* +*Once it has been checked, then this comment will be deleted* +
diff --git a/contriborbase b/contriborbase new file mode 100644 index 0000000..9b7fd51 --- /dev/null +++ b/contriborbase @@ -0,0 +1 @@ +contribs10 diff --git a/createlinks b/createlinks new file mode 100644 index 0000000..facd866 --- /dev/null +++ b/createlinks @@ -0,0 +1,14 @@ +#! /usr/bin/perl -w + +use esmith::Build::CreateLinks qw(:all); + + +templates2events("/etc/cron.d/Learn", qw(email-update bootstrap-console-save )); +safe_touch('root/etc/e-smith/db/configuration/defaults/Learn/Exclude'); +safe_touch('root/etc/e-smith/db/configuration/defaults/Learn/Include'); + +my $event="smeserver-learn-update"; +templates2events("/etc/cron.d/Learn",$event); +templates2events("/etc/mail/spamassassin/local.cf",$event); +event_link("LearnSpam-init", $event, "04"); +event_link("LearnSpam-run", $event, "30"); diff --git a/root/etc/cron.d/Learn b/root/etc/cron.d/Learn new file mode 100644 index 0000000..c1fa455 --- /dev/null +++ b/root/etc/cron.d/Learn @@ -0,0 +1 @@ +# Learn auto-exec disabled diff --git a/root/etc/e-smith/db/configuration/defaults/Learn/Verbose b/root/etc/e-smith/db/configuration/defaults/Learn/Verbose new file mode 100644 index 0000000..86981e6 --- /dev/null +++ b/root/etc/e-smith/db/configuration/defaults/Learn/Verbose @@ -0,0 +1 @@ +enabled diff --git a/root/etc/e-smith/db/configuration/defaults/Learn/cron b/root/etc/e-smith/db/configuration/defaults/Learn/cron new file mode 100644 index 0000000..f1931f6 --- /dev/null +++ b/root/etc/e-smith/db/configuration/defaults/Learn/cron @@ -0,0 +1 @@ +daily diff --git a/root/etc/e-smith/db/configuration/defaults/Learn/type b/root/etc/e-smith/db/configuration/defaults/Learn/type new file mode 100644 index 0000000..24e1098 --- /dev/null +++ b/root/etc/e-smith/db/configuration/defaults/Learn/type @@ -0,0 +1 @@ +service diff --git a/root/etc/e-smith/db/configuration/defaults/LearnAsHam/LearnNew b/root/etc/e-smith/db/configuration/defaults/LearnAsHam/LearnNew new file mode 100644 index 0000000..7a68b11 --- /dev/null +++ b/root/etc/e-smith/db/configuration/defaults/LearnAsHam/LearnNew @@ -0,0 +1 @@ +disabled diff --git a/root/etc/e-smith/db/configuration/defaults/LearnAsHam/RemoveSPAMTag b/root/etc/e-smith/db/configuration/defaults/LearnAsHam/RemoveSPAMTag new file mode 100644 index 0000000..86981e6 --- /dev/null +++ b/root/etc/e-smith/db/configuration/defaults/LearnAsHam/RemoveSPAMTag @@ -0,0 +1 @@ +enabled diff --git a/root/etc/e-smith/db/configuration/defaults/LearnAsHam/Uniq b/root/etc/e-smith/db/configuration/defaults/LearnAsHam/Uniq new file mode 100644 index 0000000..86981e6 --- /dev/null +++ b/root/etc/e-smith/db/configuration/defaults/LearnAsHam/Uniq @@ -0,0 +1 @@ +enabled diff --git a/root/etc/e-smith/db/configuration/defaults/LearnAsHam/dir b/root/etc/e-smith/db/configuration/defaults/LearnAsHam/dir new file mode 100644 index 0000000..dba009a --- /dev/null +++ b/root/etc/e-smith/db/configuration/defaults/LearnAsHam/dir @@ -0,0 +1 @@ +LearnAsHam diff --git a/root/etc/e-smith/db/configuration/defaults/LearnAsHam/status b/root/etc/e-smith/db/configuration/defaults/LearnAsHam/status new file mode 100644 index 0000000..7a68b11 --- /dev/null +++ b/root/etc/e-smith/db/configuration/defaults/LearnAsHam/status @@ -0,0 +1 @@ +disabled diff --git a/root/etc/e-smith/db/configuration/defaults/LearnAsHam/tag b/root/etc/e-smith/db/configuration/defaults/LearnAsHam/tag new file mode 100644 index 0000000..c9f2ad2 --- /dev/null +++ b/root/etc/e-smith/db/configuration/defaults/LearnAsHam/tag @@ -0,0 +1 @@ +[HAM] diff --git a/root/etc/e-smith/db/configuration/defaults/LearnAsHam/type b/root/etc/e-smith/db/configuration/defaults/LearnAsHam/type new file mode 100644 index 0000000..24e1098 --- /dev/null +++ b/root/etc/e-smith/db/configuration/defaults/LearnAsHam/type @@ -0,0 +1 @@ +service diff --git a/root/etc/e-smith/db/configuration/defaults/LearnAsSpam/DelayToMove b/root/etc/e-smith/db/configuration/defaults/LearnAsSpam/DelayToMove new file mode 100644 index 0000000..573541a --- /dev/null +++ b/root/etc/e-smith/db/configuration/defaults/LearnAsSpam/DelayToMove @@ -0,0 +1 @@ +0 diff --git a/root/etc/e-smith/db/configuration/defaults/LearnAsSpam/DeleteAfterLearn b/root/etc/e-smith/db/configuration/defaults/LearnAsSpam/DeleteAfterLearn new file mode 100644 index 0000000..7a68b11 --- /dev/null +++ b/root/etc/e-smith/db/configuration/defaults/LearnAsSpam/DeleteAfterLearn @@ -0,0 +1 @@ +disabled diff --git a/root/etc/e-smith/db/configuration/defaults/LearnAsSpam/LearnNew b/root/etc/e-smith/db/configuration/defaults/LearnAsSpam/LearnNew new file mode 100644 index 0000000..7a68b11 --- /dev/null +++ b/root/etc/e-smith/db/configuration/defaults/LearnAsSpam/LearnNew @@ -0,0 +1 @@ +disabled diff --git a/root/etc/e-smith/db/configuration/defaults/LearnAsSpam/SpamLinks b/root/etc/e-smith/db/configuration/defaults/LearnAsSpam/SpamLinks new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/root/etc/e-smith/db/configuration/defaults/LearnAsSpam/SpamLinks @@ -0,0 +1 @@ + diff --git a/root/etc/e-smith/db/configuration/defaults/LearnAsSpam/Uniq b/root/etc/e-smith/db/configuration/defaults/LearnAsSpam/Uniq new file mode 100644 index 0000000..86981e6 --- /dev/null +++ b/root/etc/e-smith/db/configuration/defaults/LearnAsSpam/Uniq @@ -0,0 +1 @@ +enabled diff --git a/root/etc/e-smith/db/configuration/defaults/LearnAsSpam/dir b/root/etc/e-smith/db/configuration/defaults/LearnAsSpam/dir new file mode 100644 index 0000000..0ac03ea --- /dev/null +++ b/root/etc/e-smith/db/configuration/defaults/LearnAsSpam/dir @@ -0,0 +1 @@ +LearnAsSpam diff --git a/root/etc/e-smith/db/configuration/defaults/LearnAsSpam/status b/root/etc/e-smith/db/configuration/defaults/LearnAsSpam/status new file mode 100644 index 0000000..7a68b11 --- /dev/null +++ b/root/etc/e-smith/db/configuration/defaults/LearnAsSpam/status @@ -0,0 +1 @@ +disabled diff --git a/root/etc/e-smith/db/configuration/defaults/LearnAsSpam/tag b/root/etc/e-smith/db/configuration/defaults/LearnAsSpam/tag new file mode 100644 index 0000000..669d1b9 --- /dev/null +++ b/root/etc/e-smith/db/configuration/defaults/LearnAsSpam/tag @@ -0,0 +1 @@ +[SPAM] diff --git a/root/etc/e-smith/db/configuration/defaults/LearnAsSpam/type b/root/etc/e-smith/db/configuration/defaults/LearnAsSpam/type new file mode 100644 index 0000000..24e1098 --- /dev/null +++ b/root/etc/e-smith/db/configuration/defaults/LearnAsSpam/type @@ -0,0 +1 @@ +service diff --git a/root/etc/e-smith/db/configuration/defaults/LearnInWL/LearnNew b/root/etc/e-smith/db/configuration/defaults/LearnInWL/LearnNew new file mode 100644 index 0000000..7a68b11 --- /dev/null +++ b/root/etc/e-smith/db/configuration/defaults/LearnInWL/LearnNew @@ -0,0 +1 @@ +disabled diff --git a/root/etc/e-smith/db/configuration/defaults/LearnInWL/RemoveSPAMTag b/root/etc/e-smith/db/configuration/defaults/LearnInWL/RemoveSPAMTag new file mode 100644 index 0000000..86981e6 --- /dev/null +++ b/root/etc/e-smith/db/configuration/defaults/LearnInWL/RemoveSPAMTag @@ -0,0 +1 @@ +enabled diff --git a/root/etc/e-smith/db/configuration/defaults/LearnInWL/Uniq b/root/etc/e-smith/db/configuration/defaults/LearnInWL/Uniq new file mode 100644 index 0000000..86981e6 --- /dev/null +++ b/root/etc/e-smith/db/configuration/defaults/LearnInWL/Uniq @@ -0,0 +1 @@ +enabled diff --git a/root/etc/e-smith/db/configuration/defaults/LearnInWL/dir b/root/etc/e-smith/db/configuration/defaults/LearnInWL/dir new file mode 100644 index 0000000..b87af59 --- /dev/null +++ b/root/etc/e-smith/db/configuration/defaults/LearnInWL/dir @@ -0,0 +1 @@ +LearnInWL diff --git a/root/etc/e-smith/db/configuration/defaults/LearnInWL/status b/root/etc/e-smith/db/configuration/defaults/LearnInWL/status new file mode 100644 index 0000000..7a68b11 --- /dev/null +++ b/root/etc/e-smith/db/configuration/defaults/LearnInWL/status @@ -0,0 +1 @@ +disabled diff --git a/root/etc/e-smith/db/configuration/defaults/LearnInWL/tag b/root/etc/e-smith/db/configuration/defaults/LearnInWL/tag new file mode 100644 index 0000000..68c9e7e --- /dev/null +++ b/root/etc/e-smith/db/configuration/defaults/LearnInWL/tag @@ -0,0 +1 @@ +[WL] diff --git a/root/etc/e-smith/db/configuration/defaults/LearnInWL/type b/root/etc/e-smith/db/configuration/defaults/LearnInWL/type new file mode 100644 index 0000000..24e1098 --- /dev/null +++ b/root/etc/e-smith/db/configuration/defaults/LearnInWL/type @@ -0,0 +1 @@ +service diff --git a/root/etc/e-smith/db/configuration/force/spamassassin/UseBayes b/root/etc/e-smith/db/configuration/force/spamassassin/UseBayes new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/root/etc/e-smith/db/configuration/force/spamassassin/UseBayes @@ -0,0 +1 @@ +1 diff --git a/root/etc/e-smith/db/configuration/force/spamassassin/status b/root/etc/e-smith/db/configuration/force/spamassassin/status new file mode 100644 index 0000000..86981e6 --- /dev/null +++ b/root/etc/e-smith/db/configuration/force/spamassassin/status @@ -0,0 +1 @@ +enabled diff --git a/root/etc/e-smith/events/actions/LearnSpam-init b/root/etc/e-smith/events/actions/LearnSpam-init new file mode 100644 index 0000000..f3a812b --- /dev/null +++ b/root/etc/e-smith/events/actions/LearnSpam-init @@ -0,0 +1,20 @@ +#!/bin/bash + +# default is 0, if kept to 0 we can not play there +/sbin/e-smith/db configuration setprop spamassassin UseBayes 1 + +# default is empty, we shall set it if we want to have a run +/sbin/e-smith/config getprop spamassassin BayesAutoLearnThresholdSpam >/dev/null|| /sbin/e-smith/config setprop spamassassin BayesAutoLearnThresholdSpam 6.00 +/sbin/e-smith/config getprop spamassassin BayesAutoLearnThresholdNonspam >/dev/null|| /sbin/e-smith/config setprop spamassassin BayesAutoLearnThresholdNonspam 0.10 + +# we really need spamassassin running +/sbin/e-smith/config setprop spamassassin status enabled + +# default is 0 for no reject +#/sbin/e-smith/config setprop spamassassin RejectLevel 12 + +# default is 5 +#/sbin/e-smith/config setprop spamassassin TagLevel 4 + +# default is medium +#/sbin/e-smith/config setprop spamassassin Sensitivity custom diff --git a/root/etc/e-smith/events/actions/LearnSpam-run b/root/etc/e-smith/events/actions/LearnSpam-run new file mode 100644 index 0000000..a2cccda --- /dev/null +++ b/root/etc/e-smith/events/actions/LearnSpam-run @@ -0,0 +1,6 @@ +#!/bin/bash + +sa-learn --sync --dbpath /var/spool/spamd/.spamassassin -u spamd +chown spamd.spamd /var/spool/spamd/.spamassassin/bayes_* +chown spamd.spamd /var/spool/spamd/.spamassassin/bayes.mutex +chmod 640 /var/spool/spamd/.spamassassin/bayes_* diff --git a/root/etc/e-smith/templates.metadata/etc/cron.d/Learn b/root/etc/e-smith/templates.metadata/etc/cron.d/Learn new file mode 100644 index 0000000..3709f0b --- /dev/null +++ b/root/etc/e-smith/templates.metadata/etc/cron.d/Learn @@ -0,0 +1 @@ +PERMS=0644 diff --git a/root/etc/e-smith/templates/etc/cron.d/Learn/Learn b/root/etc/e-smith/templates/etc/cron.d/Learn/Learn new file mode 100644 index 0000000..4f0c435 --- /dev/null +++ b/root/etc/e-smith/templates/etc/cron.d/Learn/Learn @@ -0,0 +1,17 @@ +{ + my $freq = $Learn{cron} || 'none'; + my $min = int(rand(60)); + my $hour = int(rand(5)); + my $learn = '/usr/bin/Learn.pl'; + if ($freq eq 'hourly') { + return "$min * * * * root $learn\n"; + } elsif ($freq eq 'daily') { + return "$min $hour * * * root $learn\n"; + } elsif ($freq eq 'weekly') { + return "$min $hour * * 0 root $learn\n"; + } elsif ($freq eq 'monthly') { + return "$min $hour 15 * * root $learn\n"; + } else { + return "# Learn auto-exec disabled\n"; + } +} diff --git a/root/usr/bin/Learn.pl b/root/usr/bin/Learn.pl new file mode 100755 index 0000000..8bae448 --- /dev/null +++ b/root/usr/bin/Learn.pl @@ -0,0 +1,291 @@ +#!/usr/bin/perl + +############################################################################# +# +# This script has been developed +# by Jesper Knudsen at http://sme.swerts-knudsen.dk +# And modified by Emmanuel Jooris at http://sme.firewall-services.com +# +# Revision History: +# +# January 18, 2006: Initial version +# June 06, 2008: Modification for add LearnAsHam and LearnInWL +# March 06, 2016: adding tmp and new subdir, tag filtering, improvements... JP Pialasse +############################################################################# + +use Sys::Hostname; +use Email::Simple; +use esmith::AccountsDB; +use esmith::ConfigDB; +use Digest::MD5 qw(md5 md5_hex md5_base64); +use File::Find; +use File::Copy; +use File::Copy::Recursive; +use File::Basename; +use File::Path; +use Encode qw/encode decode/; +use utf8; + +my $hostname = hostname(); + +#Opening databases +my $adb = esmith::AccountsDB->open_ro() + or die "Could not open AccountsDB ( reason : ".esmith::DB->error." )\n"; +my $sadb = esmith::ConfigDB->open_ro() + or die "Could not open ConfigurationDB ( reason : ".esmith::DB->error." )\n"; + +# some variables of interest +my $subjectTAG= $sadb->get_prop("spamassassin", "Subject"); +my $tag= $sadb->get_prop("LearnAsSpam", "tag"); +my $MessageRetentionTime = $sadb->get_prop('spamassassin', '$MessageRetentionTime')|| "15"; +my $DelayToMove = $sadb->get_prop("LearnAsSpam", "DelayToMove") || $MessageRetentionTime ; # delay in day before moving files +$DelayToMove= $DelayToMove<$MessageRetentionTime ? $DelayToMove : 0; # set 0 to disable +my $agesecs=60*60*24*$DelayToMove; #converts $agedays to seconds +my $daysago=time-$agesecs; #the time stamp of $agedays ago in seconds +my $daysago2=localtime($daysago); #the time stamp of $agedays ago in words - mainly for printing +my $SpamLinks = $sadb->get_prop("LearnAsSpam", "SpamLinks") || ""; +my @files; + +#getting user list +my @users = $adb->users; +#adding admin +my @admin = $adb->get('admin'); +push @users ,@admin; + +# getting WL before running +open(SADB, "/home/e-smith/db/spamassassin"); +binmode(SADB); +my $md5 = Digest::MD5->new->addfile(SADB)->b64digest; +close(SADB); + +#Verbose mode +my $verbose= $sadb->get_prop("Learn", "Verbose") || "enabled"; +my $outputfile=($verbose eq "disabled")? "/dev/null": '/tmp/LearnLog.txt'; +my $LOG; +open ( $LOG, '+>', $outputfile) unless ($verbose eq "enabled"); +# select new filehandle +select $LOG unless ($verbose eq "enabled"); +my $currentuser; + +# Running for every user +foreach my $user (@users) { + my $firstname = $user->prop('FirstName'); + my $lastname = $user->prop('LastName'); + my $key = $user->key; + # verification if user included or excluded + my @include= split(',',$sadb->get_prop("Learn", "Include")) if $sadb->get_prop("Learn", "Include"); + my @exclude= split(',',$sadb->get_prop("Learn", "Exclude")) if $sadb->get_prop("Learn", "Exclude"); + next if ( (@exclude) and @found = grep { $_ eq $key } @exclude ); + next unless ( ! (@include) or @found = grep { $_ eq $key } @include ); + + $currentuser = sprintf("Checking for user (%s): %s %s\n", $key,$firstname, $lastname); + print $currentuser unless ($verbose eq "active"); + + my $MailDir = ($key eq "admin")? "/home/e-smith" . "/Maildir" : "/home/e-smith/files/users/" . $key . "/Maildir"; + + my @modes = ("LearnAsSpam","LearnAsHam","LearnInWL"); + foreach my $mode (@modes) { + # verificating mode is enabled + if ($sadb->get_prop($mode, "status") ne "enabled") { next; } + + # getting dir name to search according to actual mode + my $dirname = $sadb->get_prop($mode, "dir"); + if ( !(defined($dirname)) ) { + Vact();print "Errors in DB, dir subkey not present for key $mode\n"; + next; + } + # adding heading periode if missing as this is an IMAP folder + if ($sadb->get_prop($mode, "Uniq") eq "enabled") { + $dirname= (substr($dirname, 0, 1) eq '.')? $dirname: ".$dirname"; + } + + #searching dir : fix to avoid to get multiple dir as default + opendir(LOGDIR, $MailDir); + my @logdirs = ($sadb->get_prop($mode, "Uniq") eq "enabled")? sort grep { /^$dirname$/ } readdir(LOGDIR) :sort grep { /$dirname/ } readdir(LOGDIR); + closedir(LOGDIR); + + ($login,$pass,$uid,$gid) = getpwnam($key) or die "$key not in passwd file"; + # mk dir if not exist + if (! @logdirs and ($sadb->get_prop($mode, "Uniq") eq "enabled")) { + Vact();print "+->mkdir :". $MailDir . "/" . $dirname . "\n"; + foreach $a ('','/cur','/tmp','/new'){ + mkdir $MailDir . "/" . $dirname . "$a"; + chown $uid,$gid,$MailDir . "/" . $dirname . "$a"; + } + }; + + my $junkdir = $MailDir . "/.junkmail"; + unless ( -d $junkdir ) { + Vact();print "+->mkdir :". $junkdir . "\n"; + foreach $a ('','/cur','/tmp','/new'){ + mkdir $junkdir . "/" . "$a"; + chown $uid,$gid,$junkdir . "/" . "$a"; + } + + } + + # create junkmail links if necessary + my $Spamlinks = $user->prop('SpamLinks') || ""; + if ($mode eq "LearnAsSpam" and ($SpamLinks or $Spamlinks ) ) { + $Spamlinks= $SpamLinks ? $SpamLinks .",". $Spamlinks : $Spamlinks; + $Spamlinks =~ s/,$//; + foreach $a (split(",",$Spamlinks)){ + $a=(substr($a, 0, 1) eq '.')? $a: ".$a"; + my $Link= $MailDir . "/" . $a; + next if ( $Link eq ".." || $Link eq "." || $Link eq "" ); + next if ( -l $Link); + if (-d $Link) { + Vact(); print "+->move previous dir $Link content to $junkdir\n"; + File::Copy::Recursive::dirmove($Link, $junkdir) or die "Can't move folder in place of our wanted link from %Link to $junkdir: $!"; + #side effect : ownership is lost + @files = ( glob( $junkdir . '/cur/*' ),glob( $junkdir . '/new/*' ), glob( $junkdir . '/tmp/*' ) ); + chown $uid, $gid, @files; + }; + if (! -e $Link) { + Vact(); print "+->create link $Link on $junkdir\n"; + symlink($junkdir, $Link) or die "Can't create symlink from $Link to $junkdir: $!"; + }; + } + } + + # moving junkmail content if we want to check it another time before deleting + # sometime files will get there whithout any spamassassin check ( MUA moving it here) + if ($mode eq "LearnAsSpam" and $sadb->get_prop($mode, "DeleteAfterLearn") eq "enabled" and $DelayToMove >0) { + my $SpamDir = $MailDir . "/" . $logdir . "/cur/"; + return unless (-e $SpamDir and -d $SpamDir); + @files=(); + find(\&wanted, $junkdir ."/cur" ); + find(\&wanted, $junkdir ."/new" ) if ($sadb->get_prop($mode, "LearnNew") eq "enabled" or $sadb->get_prop($mode, "LearnNew") eq "junkmail"); + sub wanted { + $filesecs = (stat("$File::Find::dir/$_"))[9]; #GETS THE 9TH ELEMENT OF file STAT - THE MODIFIED TIME + $filesecs2=localtime($filesecs); + if ($filesecs<$daysago && -f){ #-f=regular files + push (@files,"$File::Find::dir/$_"); + push (@files,"$filesecs2"); + } + } + my %filehash=@files; #puts the array into a hash for easy printing. Key=file, Value=date + undef @files; + foreach $filename (sort keys %filehash){ + Vact(); print "--> moving $filename $filehash{$filename}\n"; + move $filename,"$MailDir/$dirname/cur" ; + } + } + + + # loop through all matching directories + foreach my $logdir (@logdirs) { + #sa-learn here to avoid its loading for each files, when it can walk in directories on itself! + my $SpamDir = ($sadb->get_prop($mode, "LearnNew") eq "enabled")? $MailDir . "/" . $logdir : $MailDir . "/" . $logdir . "/cur/" ; + #taking action according to actual mode + my $counter = 0; + find( { wanted => sub { -f && $_ =~ m/($logdir\/cur|$logdir\/new|$logdir\/tmp)/ && $counter++;}, no_chdir => 1, follow_fast => 1 }, $SpamDir ); + if ($mode eq "LearnAsSpam" and $counter>0) { + my $result = `/usr/bin/sa-learn --spam $SpamDir`; + chomp($result); Vact(); printf("+Learning Spam from %s: %s\n",$logdir,$result); + } + elsif ($mode eq "LearnAsHam" and $counter>0) { + my $result = `/usr/bin/sa-learn --ham $SpamDir`; + chomp($result); Vact(); printf("+Learning Ham from %s: %s\n",$logdir,$result); + } + + @list= ($sadb->get_prop($mode, "LearnNew") eq "enabled") ? ('/cur/','/new/'):('/cur/'); + foreach $a (@list){ + my $SpamDir = $MailDir . "/" . $logdir . "$a"; + # list and sort file in dir + opendir(SPAMDIR, $SpamDir); + my @spamfiles = sort grep { /$hostname/ } readdir(SPAMDIR); + closedir(SPAMDIR); + + # + foreach my $spamfile (@spamfiles) { + my $filetolearn = $SpamDir . $spamfile; + my $filetolearnbash = $filetolearn; + $filetolearnbash =~ s/;/\\;/g; + $filetolearnbash =~ s/:/\\:/g; + + #taking action according to actual mode + if ($mode eq "LearnInWL") { + Vact(); printf("+Learning in WhiteList: %s\n",$filetolearnbash); + `/usr/bin/LearnInWL.pl $filetolearnbash`; + } + # if we are in LearnAsSpam mode and DeleteAfterLearn is enabled delete message, else tagging a move message + if ($mode eq "LearnAsSpam" and $sadb->get_prop($mode, "DeleteAfterLearn") eq "enabled") { + `rm -f $filetolearn`; + } + else { + if (defined($sadb->get_prop($mode, "tag"))) { + # Opening, reading in one scalar and parsing mail + $/=undef; + open(MAILFILE,"<:encoding(UTF-8)",$filetolearn); + my $emailbrut = ; + close(MAILFILE); + $/="\n"; + my $email = Email::Simple->new($emailbrut); + + #changing subject (tagging), opening and writing new mail + my $Subject= $email->header("Subject"); + if ( ($mode ne "LearnAsSpam") && ($sadb->get_prop($mode, "RemoveSPAMTag") eq "enabled") ) { + for my $test ( quotemeta $subjectTAG , quotemeta $tag) { + ($Subject= $Subject) =~ s/$test//; + } + # we also remove Spam tag or client will move the mail again in spam dir + $email->header_set("X-Spam-Flag",'NO'); + $email->header_set("X-Spam-Level",'*'); + $email->header_set("X-Spam-Status",'No, score=0.0 required=4.0 autolearn=disabled'); + } + # encoding as MIME Q (not B) with UTF8 as default. + my $cleanTag= encode("MIME-Q",$sadb->get_prop($mode, "tag")); + $email->header_set("Subject",$cleanTag.$Subject); + open(MAILFILEWRITE,">","$filetolearn"); + print(MAILFILEWRITE $email->as_string); + close(MAILFILEWRITE) + } + my $mvdir; + if ($mode eq "LearnAsSpam") { + $mvdir = $MailDir . "/.junkmail/cur/"; + } + else { + $mvdir = $MailDir . "/cur/"; + } + `mv $filetolearn $mvdir`; + } + } + } + } + } + +} + +open(SADB, "/home/e-smith/db/spamassassin"); +binmode(SADB); +my $newmd5 = Digest::MD5->new->addfile(SADB)->b64digest; +close(SADB); + +# fix for bad ownership of bayes files +system('/bin/chown','spamd:spamd','/var/spool/spamd/.spamassassin/bayes_toks'); + +if ($newmd5 ne $md5) { + `expand-template /etc/mail/spamassassin/local.cf`; + `/usr/bin/systemctl restart spamassassin.service`; + print "\n"; +} + +# restore STDOUT +select STDOUT; +# read log and print on STDOUT if mode active +if ($verbose eq "active"){ + seek $LOG, 0, 0; + while (<$LOG>) { + print $_; + } +} +close($LOG) unless ($verbose eq "enabled"); +unlink $outputfile unless ($verbose eq "disabled"); + +# sub to print the user line if something happen on active verbose mode +sub Vact() { +return unless ($verbose eq "active"); +print $currentuser; +$currentuser=""; +} diff --git a/root/usr/bin/LearnInWL.pl b/root/usr/bin/LearnInWL.pl new file mode 100755 index 0000000..7b88fa5 --- /dev/null +++ b/root/usr/bin/LearnInWL.pl @@ -0,0 +1,36 @@ +#!/usr/bin/perl + +############################################################################# +# +# This script has been developed +# by Emmanuel Jooris at http://sme.firewall-services.com +# +# Revision History: +# +# June 06, 2008: : Initial dev version +############################################################################# + +use Email::Simple; +use esmith::ConfigDB; +use warnings; + +$/=undef; +open(MAIL,$ARGV[0]); +$file = ; +close(MAIL); +$/="\n"; +my $email = Email::Simple->new($file); +my $from_header = $email->header("From"); +my $sadb = esmith::ConfigDB->open("spamassassin") + or die "Could not open SpamAssasinDB ( reason : )".esmith::DB->error." )\n"; + +if ($from_header =~ m/<.*?>/) { + $from_mail = $&; + $from_mail =~ s///; +} +elsif ($from_header =~ m/@/) { + $from_mail = $&; +} +$from_mail =~ tr/[A-Z]/[a-z]/; +$sadb->set_prop("wbl.global",$from_mail,"White"); diff --git a/smeserver-learn.spec b/smeserver-learn.spec new file mode 100644 index 0000000..45a5fe9 --- /dev/null +++ b/smeserver-learn.spec @@ -0,0 +1,131 @@ +# $Id: smeserver-learn.spec,v 1.4 2021/02/23 19:39:09 jpp Exp $ +# Authority: unnilennium +# Name: Jean-Philippe Pialasse. +%define name smeserver-learn +%define version 1.0 +%define release 17 + +Summary: SME Server Mails Learning script +Name: %{name} +Version: %{version} +Release: %{release}%{?dist} +License: GPL +Group: Networking/Daemons +Source: %{name}-%{version}.tar.xz + +Packager: JP Pialasse +BuildRoot: /var/tmp/%{name}-%{version}-%{release}-buildroot +BuildArchitectures: noarch +Requires: perl-Email-Simple +BuildRequires: e-smith-devtools >= 1.13.1-03 + +%description +Scripts which allows users to interact with spamassassin rules simply +by droping mail in special folders of their mailbox (working only with imap) +- Learn mail as spam +- Learn mail as ham +- Whitelist the sender so his mails won't be taged as spam again + +%changelog +* Sat Sep 07 2024 cvs2git.sh aka Brian Read 1.0-17.sme +- Roll up patches and move to git repo [SME: 12338] + +* Sat Sep 07 2024 BogusDateBot +- Eliminated rpmbuild "bogus date" warnings due to inconsistent weekday, + by assuming the date is correct and changing the weekday. + +* Tue Feb 23 2021 Jean-Philipe Pialasse 1.0-16.sme +- make use of systemd [SME: 11281] +- create an update event to configure the contrib without reboot [SME: 11281] +- untag ham to avoid client to move them back to spamdir [SME: 10732] +- move existing spamdir before creating link to replace them [SME: 9524] + +* Thu Dec 31 2020 Brian Read 1.0-15.sme +- Remove-deprecated-defined [SME: 11281] + +* Sun Dec 20 2020 Brian Read 1.0-14.sme +- Initial Import in SME 10 [SME: 11281] + +* Fri Jul 29 2016 Jean-Philipe Pialasse 1.0-13.sme +- fix permission problem on bayes_tok [SME: 9446] + +* Sat May 14 2016 Jean-Philipe Pialasse 1.0-12.sme +- fix verbose disabled unlink /dev/null [SME: 9512] + +* Tue Mar 29 2016 Jean-Philipe Pialasse 1.0-11.sme +- first import in SME9 [SME: 9414] + +* Wed Mar 16 2016 JP Pialasse 1.0-10.sme +- fix encoding problem when removing or adding tags [SME: 9282] +- fix moving file not working MOVE patch [SME: 9314] +- NFR: setting for verbose (enabled,disabled, active) VERBOSE patch [SME: 9313] + +* Tue Mar 15 2016 JP Pialasse 1.0-8.sme +- NFR: check admin Maildir [SME: 9279] +- NFR: restrict utilization to some users [SME: 9280] + +* Wed Mar 09 2016 JP Pialasse 1.0-7.sme +- fix find not restrictive enough when learning also new [SME: 6862] + +* Tue Mar 08 2016 JP Pialasse 1.0-6.sme +- new version SME8 and SME9 +- fix wrong default db key DeleteAfterLearn [SME: 7083] +- added inspection of temp and new subdir [SME: 6862] +- moved default db keys as file outside of spec +- new db properties: (LearnAsHam,LearnInWL)RemoveSPAMTag, (*)LeanNew,(*)Uniq,(LearnAsSpam)SpamLinks +- new account db property for user: SpamLinks +- import to buildsys [SME: 4423] +- use sa-learn per dir and not per message [SME: 1701] +- merge enhancements [SME: 4423] [SME: 1701] +- NFR: create links +- NFR: filter out SPAM tag from HAM and InWL mails +- NFR: added auto create folders if multiple folder disabled +- NFR: create db key for multiple folder to inspect +- enhanced move to junkmail or inbox +- moving job from crontab to /etc/cron.d/Learn +- fixed typo in event email-update (r3) +- fixed wrong file permission on /etc/cron.d/Lean [SME: 9283] (r4) +- fixed messy output [SME: 9284] (r5) +- fixed replaced cron file on update [SME: 9286](r6) + +* Wed Jun 25 2008 Emmmanuel JOORIS 0.0.1-3 +- add dependencies to spec file + +* Mon Jun 23 2008 Daniel B. 0.0.1-2 +- add spaces after the tags + +* Wed Jun 18 2008 Daniel B. 0.0.1-1 +- full path for Learn script in crontab templates +- rename to smeserver-learn +- Fix default tag for Ham mail to [HAM] +- Lean.pl will be executed daily by default + +* Wed Jun 11 2008 Emmanuel JOORIS +- 0.0.1-0 +- Original version + +%prep +%setup + +%build +perl createlinks + +%install +rm -rf $RPM_BUILD_ROOT +(cd root ; find . -depth -print | cpio -dump $RPM_BUILD_ROOT) +rm -f %{name}-%{version}-filelist +/sbin/e-smith/genfilelist $RPM_BUILD_ROOT |\ +sed -e "s@^$RPM_BUILD_ROOT@@g" \ +-e "s@^%attr(0644,root,root) /etc/cron.d/Learn@%attr(0644,root,root)%config(noreplace) /etc/cron.d/Learn@"\ +> %{name}-%{version}-filelist + +%clean +#rm -rf $RPM_BUILD_ROOT + +%post + +%postun + +%files -f %{name}-%{version}-filelist +%defattr(-,root,root) +