diff --git a/indimail-x/configure.ac b/indimail-x/configure.ac index f8e9c30be..f59ad7f9f 100644 --- a/indimail-x/configure.ac +++ b/indimail-x/configure.ac @@ -90,7 +90,7 @@ CPPFLAGS=$saveCPPFLAGS AC_CHECK_HEADERS([dirent.h limits.h sys/ioctl.h net/if.h linux/sockios.h sys/sockio.h]) AC_CHECK_HEADERS([openssl/evp.h sys/syscall.h sys/select.h sys/un.h]) AC_CHECK_HEADERS([crypt.h inttypes.h]) -AC_CHECK_HEADERS([fnmatch.h udb.h elf.h magic.h a.out.h malloc.h sys/utsname.h sys/ipc.h asm/ioctls.h]) +AC_CHECK_HEADERS([udb.h elf.h magic.h a.out.h malloc.h sys/utsname.h sys/ipc.h asm/ioctls.h]) AC_CHECK_HEADERS([gsasl.h]) AC_CHECK_HEADERS([sodium_random.h]) @@ -105,7 +105,7 @@ AC_TYPE_GETGROUPS # Checks for library functions. AC_FUNC_CHOWN -AC_CHECK_FUNCS(strsignal fdatasync sigaction sigprocmask fnmatch gethostname fchown getmntent getmntinfo setenv unsetenv rresvport) +AC_CHECK_FUNCS(strsignal fdatasync sigaction sigprocmask gethostname fchown getmntent getmntinfo setenv unsetenv rresvport) defaultprefix="/usr" if test x$prefix = xNONE then diff --git a/indimail-x/doc/ChangeLog b/indimail-x/doc/ChangeLog index a2d77edd1..79a109f6d 100644 --- a/indimail-x/doc/ChangeLog +++ b/indimail-x/doc/ChangeLog @@ -56,6 +56,26 @@ Release 3.4.5-1.1 Start 25/04/2023 End XX/XX/XXXX 28. parseAddress.c: handle address without domain component 29. storeHeader.c: return error if parseAddress is unsuccessful 30. vfilter.c: run vdelivermail if storeHeader is unsuccessful +05/09/2023 +31. vcfilter.c: allow both textual and numberical values for -c and -h option +32. vfilter_header.c: added function headerNumber() to convert textual filter + name to filter number +33. vadddomain_handle.in: replace header, comparision numbers with textual + names +34. vfilter.c, spam.c: replace fnmatch with matchregex from libqmail +35. configure.ac: Removed check for fnmatch +36. vfilter.c, vcfilter.c, variables.c, vfilter_insert.c: removed "Sender not + in addressbook" +06/09/2023 +37. vdelivermail.c: prepend dot '.' to delivery folder if folder doesn't start + with dot +38. vfilter_filterNo.c: start with filter no 1 for filter not matching 'My ID + not in To, Cc, Bcc' +39. vfilter_insert.c: handle negative header_num, empty keyword for 'My ID not + in To, Cc, Bcc' +07/09/2023 +40. vdelivermail: Bounce mail if env variable BOUNCE_MAIL is set +41. vfilter.c: set BOUNCE_MAIL env variable to bounce mail using vdelivermail * Sun Apr 23 2023 19:21:03 +0000 Manvendra Bhangui 3.4.4-1.1%{?dist} Release 3.4.4-1.1 Start 26/03/2023 End 23/04/2023 diff --git a/indimail-x/osh.c b/indimail-x/osh.c index c079065d2..ce774f643 100644 --- a/indimail-x/osh.c +++ b/indimail-x/osh.c @@ -1,5 +1,8 @@ /* * $Log: osh.c,v $ + * Revision 1.4 2023-09-05 21:47:22+05:30 Cprogrammer + * added return type for gethostname + * * Revision 1.3 2022-10-20 11:58:04+05:30 Cprogrammer * converted function prototype to ansic * @@ -33,7 +36,7 @@ */ #ifndef lint -static char *rcsid = "@(#) $Id: osh.c,v 1.3 2022-10-20 11:58:04+05:30 Cprogrammer Exp mbhangui $"; +static char *rcsid = "@(#) $Id: osh.c,v 1.4 2023-09-05 21:47:22+05:30 Cprogrammer Exp mbhangui $"; #endif #ifdef HAVE_CONFIG_H @@ -804,6 +807,7 @@ command(int *waitpid, int makepipe, int *pipepfd) } /*- of command */ #ifndef HAVE_GETHOSTNAME +int gethostname(char *host, int len) { struct utsname name; diff --git a/indimail-x/spam.c b/indimail-x/spam.c index fdbce6ce3..36dd8537a 100644 --- a/indimail-x/spam.c +++ b/indimail-x/spam.c @@ -1,5 +1,8 @@ /* * $Log: spam.c,v $ + * Revision 1.6 2023-09-05 21:47:40+05:30 Cprogrammer + * use matchregex from libqmail + * * Revision 1.5 2023-03-20 10:18:16+05:30 Cprogrammer * standardize getln handling * @@ -46,6 +49,7 @@ #include #include #include +#include #endif #include "common.h" #include "spam.h" @@ -53,14 +57,12 @@ #include "lowerit.h" #ifndef lint -static char sccsid[] = "$Id: spam.c,v 1.5 2023-03-20 10:18:16+05:30 Cprogrammer Exp mbhangui $"; +static char sccsid[] = "$Id: spam.c,v 1.6 2023-09-05 21:47:40+05:30 Cprogrammer Exp mbhangui $"; #endif #define BADMAIL 1 #define BADRCPT 2 #define SPAMDB 3 -#define REGCOMP(X,Y) regcomp(&X, Y, REG_EXTENDED|REG_ICASE) -#define REGEXEC(X,Y) regexec(&X, Y, (size_t)0, (regmatch_t *)0, (int)0) static char *parseLine1(char *); static char *parseLine2(char *); @@ -70,35 +72,6 @@ static maddr **spammer_hash; static maddr **ignored_hash; static int bounce, maxaddr; -static int -matchregex(char *text, char *regex) -{ - regex_t qreg; - char errbuf[512]; - int retval = 0; - - /*- build the regex */ - if ((retval = REGCOMP(qreg, regex)) != 0) { - regerror(retval, &qreg, errbuf, sizeof(errbuf)); - regfree(&qreg); - strerr_warn5(text, ": ", regex, ": ", errbuf, 0); - return (-retval); - } - /*- execute the regex */ - if ((retval = REGEXEC(qreg, text)) != 0) { - /*- did we just not match anything? */ - if (retval == REG_NOMATCH) { - regfree(&qreg); - return (0); - } - regfree(&qreg); - return (-retval); - } - /*- signal the match */ - regfree(&qreg); - return (1); -} - static void die_nomem() { @@ -497,7 +470,7 @@ isIgnored(char *email) !stralloc_0(&pattern)) die_nomem(); } - if (matchregex(email, pattern.s) == 1) + if (matchregex(email, pattern.s, 0) == 1) return (1); } else { if (*(p->mail) == '@') diff --git a/indimail-x/tests/testindimail-virtual b/indimail-x/tests/testindimail-virtual index 867e60ad8..c27860ad3 100755 --- a/indimail-x/tests/testindimail-virtual +++ b/indimail-x/tests/testindimail-virtual @@ -1,6 +1,6 @@ #!/bin/sh # -# $Id: testindimail-virtual,v 1.6 2023-08-23 13:09:26+05:30 Cprogrammer Exp mbhangui $ +# $Id: testindimail-virtual,v 1.8 2023-09-08 11:19:10+05:30 Cprogrammer Exp mbhangui $ # start=$(date +'%s') user=$(whoami) @@ -256,7 +256,6 @@ setup_config() exit 1 fi fi - #unshare mount --bind $in_cnf /etc/mysql/indimail.cnf # MySQL Database Creation if [ ! -d $qmaildir/mysqldb/data/mysql ] ; then @@ -302,6 +301,8 @@ setup_config() if [ ! -f $sysconfdir/headerlist ] ; then cp /etc/indimail/headerlist $sysconfdir fi + $sudo chown $user $sysconfdir/headerlist + $sudo chmod 644 $sysconfdir/headerlist # nssd config $sudo $svctool --sysconfdir=$sysconfdir --config=nssd \ --threads=5 --timeout=-1 \ @@ -625,6 +626,11 @@ create_domain() { mkdir -p $sysconfdir/users mkdir -p $testdir/mail + if [ $# -eq 3 ] ; then + opt="-f" + else + opt="" + fi $sudo env - \ PATH=/bin:/usr/bin \ ASSIGNDIR=$sysconfdir/users \ @@ -632,7 +638,7 @@ create_domain() CONTROLDIR=$cntrldir \ DOMAINDIR=$qmaildir \ SERVICEDIR=$servicedir \ - vadddomain -B $testdir/mail -d $qmaildir $1 $2 > $logdir/setup/vadddomain.log + vadddomain $opt -B $testdir/mail -d $qmaildir $1 $2 > $logdir/setup/vadddomain.log if [ $? -eq 0 ] ; then tcount=$(expr $tcount + 1) echo " testing command vadddomain succeeded" @@ -972,6 +978,8 @@ test_services() check_mail() { + # $1 - user + # $2 - Maildir count=0 ret=1 ( @@ -1086,7 +1094,6 @@ do_smtp_auth_swaks() [ -z "$failed" ] && failed="inlookup PWD query" || failed="$failed, inlookup PWD query" [ $continue_on_err -eq 0 ] && exit 1 || return 0 fi - echo fi done } @@ -1743,21 +1750,53 @@ do_post_handle() do_qmail_inject() { # $1 - user - # $2 - From - # $3 - To + # $2 - envelope From + # $3 - envelope To + # $4 - subject + # $5 - header + # $6 - from + # $7 - to + # $8 - cc + if [ $# -eq 8 ] ; then + cc=$8 + else + cc="" + fi + if [ $# -eq 7 ] ; then + to=$7 + else + to=$3 + fi + if [ $# -eq 6 ] ; then + from=$6 + else + from=$2 + fi + if [ $# -eq 5 ] ; then + header=$5 + else + header="" + fi if [ $# -eq 4 ] ; then subj=$4 else subj="Testing qmail-inject" fi ( - echo "From: $2" - echo "To: $3" + echo "From: $from" + echo "To: $to" + if [ -n "$cc" ] ; then + echo "Cc: $cc" + fi echo "Subject: $subj" + if [ -n "$header" ] ; then + echo $header + fi echo "Date: $(date -R)" echo echo "Test message" - ) | $sudo $setuidgid -g qcerts $1 env - \ + ) > /tmp/mail.txt + cat /tmp/mail.txt | $sudo $setuidgid -g qcerts $1 env - \ CONTROLDIR=$cntrldir \ QUEUEDIR=$qmaildir/queue \ QMAILQUEUE=$qmail_queue \ @@ -1892,7 +1931,6 @@ do_cleanup_failed() do_cleanup() { touch $testdir/cleanup.done - #$sudo umount /etc/mysql/indimail.cnf delete_domain $domain1 1 >/dev/null 2>&1 do_svscan_stop # Cleanup @@ -1916,12 +1954,11 @@ do_cleanup() /bin/rm -f $sysconfdir/nssd.conf $sudo /bin/rm -rf $qmaildir/domains $sudo /bin/rm -rf $testdir/mail - #$sudo /bin/rm -rf $qmaildir/mysqldb - #$sudo /bin/rm -f $in_cnf } do_autoresponder() { + echo "Starting Autoresponder test" destdir1=$($sudo $setuidgid indimail envdir $servicedir/smtpd/variables vuserinfo -d $1 | awk '{print $3}') destdir2=$($sudo $setuidgid indimail envdir $servicedir/smtpd/variables vuserinfo -d $2 | awk '{print $3}') echo "Testing Autoresponder" > /tmp/vacation.$$ @@ -1975,6 +2012,433 @@ do_autoresponder() fi } +run_vcfilter() +{ + $sudo env - \ + PATH=/bin:/usr/bin:/usr/sbin \ + ASSIGNDIR=$sysconfdir/users \ + SYSCONFDIR=$sysconfdir \ + CONTROLDIR=$cntrldir \ + "$@" +} + +do_plain_user_tests() +{ + for hash in "default" $hash_supported + do + echo + echo "Starting SMTP AUTH, qmail-remote, IMAP/POP3 login tests for hash $hash plain/cram users" + t1="$password2""$hash" + t2="$password3""$hash" + create_plain_user $testuser1 $t1 $hash + create_cram_user $testuser2 $t2 $hash + do_inquerytest $testuser1 + do_inquerytest $testuser2 + echo 1 > $servicedir/smtpd/variables/ENABLE_CRAM + if [ "$hash" = "DES" ] ; then + echo -1 > $servicedir/smtpd/variables/PASSWORD_HASH + else + > $servicedir/smtpd/variables/PASSWORD_HASH + fi + do_smtp_auth_swaks $testuser1 $t1 1 + do_smtp_auth_qmr_o $domain1 $testuser1 $t1 1 + > $servicedir/smtpd/variables/ENABLE_CRAM + do_smtp_auth_swaks $testuser2 $t2 2 + do_smtp_auth_qmr_o $domain1 $testuser2 $t2 2 + for j in 1 2 + do + case $j in + 1) + str="incache=0" + for i in imap pop3 + do + for k in d d-ssl + do + > $servicedir/"$i"$k/variables/PASSWD_CACHE + > $servicedir/"$i"$k/variables/QUERY_CACHE + if [ "$hash" = "DES" ] ; then + echo -1 > $servicedir/"$i"$k/variables/PASSWORD_HASH + else + > $servicedir/"$i"$k/variables/PASSWORD_HASH + fi + done + done + ;; + 2) + str="incache=1" + for i in imap pop3 + do + for k in d d-ssl + do + echo 1 > $servicedir/"$i"$k/variables/PASSWD_CACHE + echo 1 > $servicedir/"$i"$k/variables/QUERY_CACHE + echo 1 > $servicedir/"$i"$k/variables/OPEN_SMTP + if [ "$hash" = "DES" ] ; then + echo -1 > $servicedir/"$i"$k/variables/PASSWORD_HASH + else + > $servicedir/"$i"$k/variables/PASSWORD_HASH + fi + done + done + ;; + esac + for i in imap pop3 + do + for k in d d-ssl + do + $sudo svc -r $servicedir/"$i"$k + done + done + destdir1=$($sudo $setuidgid indimail envdir $servicedir/smtpd/variables vuserinfo -d $testuser1 | awk '{print $3}') + destdir2=$($sudo $setuidgid indimail envdir $servicedir/smtpd/variables vuserinfo -d $testuser2 | awk '{print $3}') + check_service pop3d 3 + check_service pop3d-ssl 3 + test_pop3 $testuser2 $t2 $testuser1 $destdir2/Maildir + test_pop3 $testuser1 $t1 $testuser2 $destdir1/Maildir + check_service imapd 3 + check_service imapd-ssl 3 + test_imap $testuser2 $t2 $testuser1 $destdir2/Maildir + test_imap $testuser1 $t1 $testuser2 $destdir1/Maildir + echo " testing SMTP AUTH, qmail-remote, IMAP/POP3 login tests for hash $hash plain/cram users succeeded" + done + delete_user $testuser1 + delete_user $testuser2 + done +} + +do_scram_user_tests() +{ + echo 1 > $servicedir/smtpd/variables/ENABLE_CRAM + for hash in $hash_supported + do + echo + echo "Starting SMTP AUTH, IMAP/POP3 login, GSASL tests for hash $hash scram users" + t1="$password1""$hash" + t2="$password2""$hash" + create_scram_user SCRAM-SHA-1 $testuser1 $t1 $hash + create_scram_user SCRAM-SHA-256 $testuser2 $t2 $hash + $sudo svc -h $servicedir/inlookup.infifo + if [ "$hash" = "DES" ] ; then + echo -1 > $servicedir/smtpd/variables/PASSWORD_HASH + else + > $servicedir/smtpd/variables/PASSWORD_HASH + fi + $sudo svc -r $servicedir/smtpd + sleep $sleep_int + check_service smtpd 3 + do_smtp_auth_swaks $testuser1 $t1 3 + do_smtp_auth_qmr_o $domain1 $testuser1 $t1 3 + for j in 1 2 + do + case $j in + 1) + str="incache=0" + > $servicedir/smtpd/variables/PASSWD_CACHE + > $servicedir/smtpd/variables/QUERY_CACHE + for i in imap pop3 + do + for k in d d-ssl + do + > $servicedir/"$i"$k/variables/PASSWD_CACHE + > $servicedir/"$i"$k/variables/QUERY_CACHE + if [ "$hash" = "DES" ] ; then + echo -1 > $servicedir/"$i"$k/variables/PASSWORD_HASH + else + > $servicedir/"$i"$k/variables/PASSWORD_HASH + fi + done + done + ;; + 2) + str="incache=1" + echo 1 > $servicedir/smtpd/variables/PASSWD_CACHE + echo 1 > $servicedir/smtpd/variables/QUERY_CACHE + for i in imap pop3 + do + for k in d d-ssl + do + echo 1 > $servicedir/"$i"$k/variables/PASSWD_CACHE + echo 1 > $servicedir/"$i"$k/variables/QUERY_CACHE + if [ "$hash" = "DES" ] ; then + echo -1 > $servicedir/"$i"$k/variables/PASSWORD_HASH + else + > $servicedir/"$i"$k/variables/PASSWORD_HASH + fi + done + done + ;; + esac + $sudo svc -r $servicedir/smtpd + check_service smtpd 3 + if [ -x $gsasl ] ; then + do_gsasl_test "SCRAM-SHA-1" $testuser1 $t1 + do_gsasl_test "SCRAM-SHA-1-PLUS" $testuser1 $t1 + do_gsasl_test "SCRAM-SHA-256" $testuser2 $t2 + do_gsasl_test "SCRAM-SHA-256-PLUS" $testuser2 $t2 + fi + do_smtp_auth_qmr_scram "SCRAM-SHA-1" $domain1 $testuser1 $t1 + do_smtp_auth_qmr_scram "SCRAM-SHA-1-PLUS" $domain1 $testuser1 $t1 + do_smtp_auth_qmr_scram "SCRAM-SHA-256" $domain1 $testuser2 $t2 + do_smtp_auth_qmr_scram "SCRAM-SHA-256-PLUS" $domain1 $testuser2 $t2 + + for i in imap pop3 + do + for k in d d-ssl + do + $sudo svc -r $servicedir/"$i"$k + done + done + destdir1=$($sudo $setuidgid indimail envdir $servicedir/smtpd/variables vuserinfo -d $testuser1 | awk '{print $3}') + check_service pop3d 3 + test_pop3 $testuser1 $t1 $testuser2 $destdir1 + check_service pop3d-ssl 3 + test_imap $testuser1 $t1 $testuser2 $destdir1 + done + delete_user $testuser1 + delete_user $testuser2 + echo " testing SMTP AUTH, IMAP/POP3 login, GSASL tests for hash $hash scram users succeeded" + done + tcount=$(expr $tcount + 3) + printf " testing command tcpserver non-encrypted succeeded\n" + printf " testing command tcpclient non-encrypted succeeded\n" + printf " testing command tcpclient encrypted succeeded\n" +} + +do_vfilter() +{ + echo "Starting VFILTER tests" + $sudo env - \ + PATH=/bin:/usr/bin:/usr/sbin \ + ASSIGNDIR=$sysconfdir/users \ + SYSCONFDIR=$sysconfdir \ + CONTROLDIR=$cntrldir \ + vmoddomain -f 1 -h bounce-no-mailbox $domain1 > $logdir/setup/vmoddomain.log + if [ $? -eq 0 ] ; then + tcount=$(expr $tcount + 1) + echo " testing command vmoddomain set vfilter succeeded" + else + fcount=$(expr $fcount + 1) + if [ $prompt -eq 1 ] ; then + less $logdir/setup/vadddomain.log + fi + echo " testing command vmoddomain set vfilter failed" + [ -z "$failed" ] && failed="vmoddomain set vfilter" || failed="$failed, vmoddomain set vfilter" + [ $continue_on_err -eq 0 ] && exit 1 || return 0 + fi + + # Comparisions tets + # 0 - Equals 1 - Contains + # 2 - Does not contain 3 - Starts with + # 4 - Ends with 5 - My id not in To, CC, Bcc + # 6 - Numerical Logical Expression 7 - RegExp + + destdir1=$($sudo $setuidgid indimail envdir $servicedir/smtpd/variables vuserinfo -d $testuser1 | awk '{print $3}') + destdir2=$($sudo $setuidgid indimail envdir $servicedir/smtpd/variables vuserinfo -d $testuser2 | awk '{print $3}') + vcount=1 + for i in "Equals" "Contains" "Does not contain" "Starts with" "Ends with" \ + "My id not in To, CC, Bcc" "Numerical Logical Expression" "RegExp" + do + sudo /bin/rm -rf $destdir1/Maildir/.Quarantine + # Test delivery to folder after matching folder + case $i in + "Equals") + run_vcfilter vcfilter -i -t "$i-Test" -c "$i" -k "virus found" -f Quarantine -b 0 -h "X-QHPSI" $testuser2 + do_qmail_inject $user $testuser1 $testuser2 "Testing Vfilter" "X-QHPSI: virus found" + run_vcfilter vcfilter -d 1 $testuser2 + ;; + "Contains") + run_vcfilter vcfilter -i -t "$i-Test" -c "$i" -k "Vfilter $vcount" -f Quarantine -b 0 -h "X-QHPSI" $testuser2 + do_qmail_inject $user $testuser1 $testuser2 "Testing Vfilter" "X-QHPSI: Test Vfilter $vcount" + run_vcfilter vcfilter -d 1 $testuser2 + ;; + "Does not contain") + run_vcfilter vcfilter -i -t "$i-Test" -c "$i" -k "xxx yyyy zzz" -f Quarantine -b 0 -h "X-QHPSI" $testuser2 + do_qmail_inject $user $testuser1 $testuser2 "Testing Vfilter" "X-QHPSI: abcdefgh" + run_vcfilter vcfilter -d 1 $testuser2 + ;; + "Starts with") + run_vcfilter vcfilter -i -t "$i-Test" -c "$i" -k "yyy xxxx zzz" -f Quarantine -b 0 -h "X-QHPSI" $testuser2 + do_qmail_inject $user $testuser1 $testuser2 "Testing Vfilter" "X-QHPSI: yyy xxxx zzz" + run_vcfilter vcfilter -d 1 $testuser2 + ;; + "Ends with") + run_vcfilter vcfilter -i -t "$i-Test" -c "$i" -k "yyy1 zzz" -f Quarantine -b 0 -h "X-QHPSI" $testuser2 + do_qmail_inject $user $testuser1 $testuser2 "Testing Vfilter" "X-QHPSI: yyy yyy1 zzz" + run_vcfilter vcfilter -d 1 $testuser2 + ;; + "My id not in To, CC, Bcc") + run_vcfilter vcfilter -i -t "$i-Test" -c "$i" -f Quarantine -b 0 $testuser2 + do_qmail_inject $user $testuser1 $testuser2 "Testing Vfilter" "" abcd@$domain1 efgh@$domain1 hijk@$domain1 + run_vcfilter vcfilter -d 0 $testuser2 + ;; + "Numerical Logical Expression") + run_vcfilter vcfilter -i -t "Numerical Logical Expression" -c "$i" -k "%p >= 11.2" -f Quarantine -b 0 -h "X-QHPSI" $testuser2 + do_qmail_inject $user $testuser1 $testuser2 "Testing Vfilter" "X-QHPSI: 12.24" + run_vcfilter vcfilter -d 1 $testuser2 + ;; + "RegExp") + run_vcfilter vcfilter -i -t "Regular Expression" -c "$i" -k "abd.*efgh $count" -f Quarantine -b 0 -h "X-QHPSI" $testuser2 + do_qmail_inject $user $testuser1 $testuser2 "Testing Vfilter" "X-QHPSI: abd.dfkdjf...efgh $count" + run_vcfilter vcfilter -d 1 $testuser2 + ;; + esac + check_mail indimail $destdir2/Maildir/.Quarantine + if [ $? -eq 0 ] ; then + tcount=$(expr $tcount + 1) + echo " testing vfilter delivery to matched folder comparision=$i succeeded" + else + fcount=$(expr $fcount + 1) + echo " testing vfilter delivery to matched folder comparision=$i failed" + [ -z "$failed" ] && failed="do_vfilter folder comparision=$i" || failed="$failed, do_vfilter folder comparision=$i" + [ $continue_on_err -eq 0 ] && exit 1 || return 0 + fi + vcount=$(expr $vcount + 1) + done + + # -b bounce action + # 0 - Do not Bounce to sender + # 3'&user@domain' - Forward to another id and Bounce + # 3'|program' - Feed mail to another program and Bounce + echo "X-Header" >> $sysconfdir/headerlist + + # bounce to sender test + # 1 - Bounce to sender + run_vcfilter vcfilter -i -t "Test bounce" -c "Equals" -k "Test Header" -f /NoDeliver -b 1 -h "X-Header" $testuser2 + do_qmail_inject $user $testuser1 $testuser2 "Testing Vfilter" "X-Header: Test Header" + run_vcfilter vcfilter -d 1 $testuser2 + check_mail indimail $destdir1/Maildir + if [ $? -eq 0 ] ; then + tcount=$(expr $tcount + 1) + echo " testing vfilter delivery for bounce on match succeeded" + else + fcount=$(expr $fcount + 1) + echo " testing vfilter delivery for bounce on match failed" + [ -z "$failed" ] && failed="do_vfilter bounce on match" || failed="$failed, do_vfilter bounce on match" + [ $continue_on_err -eq 0 ] && exit 1 || return 0 + fi + + # forward to another id test + # 2'&user@domain' - Forward to another id + run_vcfilter vcfilter -i -t "Test bounce" -c "Equals" -k "Test Header" -f /NoDeliver -b "2&$testuser1" -h "X-Header" $testuser2 + do_qmail_inject $user $testuser1 $testuser2 "Testing Vfilter" "X-Header: Test Header" + run_vcfilter vcfilter -d 1 $testuser2 + check_mail indimail $destdir1/Maildir + if [ $? -eq 0 ] ; then + tcount=$(expr $tcount + 1) + echo " testing vfilter delivery for forward on match succeeded" + else + fcount=$(expr $fcount + 1) + echo " testing vfilter delivery for forward on match failed" + [ -z "$failed" ] && failed="do_vfilter forward on match" || failed="$failed, do_vfilter forward on match" + [ $continue_on_err -eq 0 ] && exit 1 || return 0 + fi + + # feed to another program test + # 2'|program' - Feed mail to another program + ( + echo "#!/bin/sh" + echo "$qmail_inject $testuser1" + ) > $testdir/forwarder + chmod +x $testdir/forwarder + run_vcfilter vcfilter -i -t "Test bounce" -c "Equals" -k "Test Header" -f /NoDeliver -b "2|$testdir/forwarder" -h "X-Header" $testuser2 + do_qmail_inject $user $testuser1 $testuser2 "Testing Vfilter" "X-Header: Test Header" + run_vcfilter vcfilter -d 1 $testuser2 + check_mail indimail $destdir1/Maildir + if [ $? -eq 0 ] ; then + /bin/rm -rf $testdir/forwarder + tcount=$(expr $tcount + 1) + echo " testing vfilter delivery for feed program on match succeeded" + else + /bin/rm -rf $testdir/forwarder + fcount=$(expr $fcount + 1) + echo " testing vfilter delivery for feed program on match failed" + [ -z "$failed" ] && failed="do_vfilter feed program on match" || failed="$failed, do_vfilter feed program on match" + [ $continue_on_err -eq 0 ] && exit 1 || return 0 + fi + + # forward to another id and bounce test + # 3'&user@domain' - Forward to another id and Bounce + destdir3=$($sudo $setuidgid indimail envdir $servicedir/smtpd/variables vuserinfo -d $testuser3 | awk '{print $3}') + run_vcfilter vcfilter -i -t "Test bounce" -c "Equals" -k "Test Header" -f /NoDeliver -b "3&$testuser3" -h "X-Header" $testuser2 + do_qmail_inject $user $testuser1 $testuser2 "Testing Vfilter" "X-Header: Test Header" + run_vcfilter vcfilter -d 1 $testuser2 + check_mail indimail $destdir1/Maildir + ret1=$? + if [ $ret1 -eq 0 ] ; then + check_mail indimail $destdir3/Maildir + if [ $? -ne 0 ] ; then + echo failed to forward to $testuser3 + ret1=1 + fi + else + echo failed to bounce to $testuser1 + fi + if [ $ret1 -eq 0 ] ; then + tcount=$(expr $tcount + 1) + echo " testing vfilter delivery for forward and bounce on match succeeded" + else + fcount=$(expr $fcount + 1) + echo " testing vfilter delivery for forward and bounce on match failed" + echo "Press ENTER2" + read key + [ -z "$failed" ] && failed="do_vfilter forward and bounce on match" || failed="$failed, do_vfilter forward and bounce on match" + [ $continue_on_err -eq 0 ] && exit 1 || return 0 + fi + + + # feed to another program and bounce test + # 3'|program' - Feed mail to another program and Bounce + ( + echo "#!/bin/sh" + echo "$qmail_inject $testuser3" + ) > $testdir/forwarder + chmod +x $testdir/forwarder + run_vcfilter vcfilter -i -t "Test bounce" -c "Equals" -k "Test Header" -f /NoDeliver -b "3|$testdir/forwarder" -h "X-Header" $testuser2 + do_qmail_inject $user $testuser1 $testuser2 "Testing Vfilter" "X-Header: Test Header" + run_vcfilter vcfilter -d 1 $testuser2 + check_mail indimail $destdir1/Maildir + ret1=$? + if [ $ret1 -eq 0 ] ; then + check_mail indimail $destdir3/Maildir + if [ $? -ne 0 ] ; then + echo failed to forward to $testuser3 + ret1=1 + fi + else + echo failed to bounce to $testuser1 + fi + if [ $ret1 -eq 0 ] ; then + /bin/rm -rf $testdir/forwarder + tcount=$(expr $tcount + 1) + echo " testing vfilter delivery for feed program and bounce on match succeeded" + else + /bin/rm -rf $testdir/forwarder + fcount=$(expr $fcount + 1) + echo " testing vfilter delivery for feed program and bounce on match failed" + [ -z "$failed" ] && failed="do_vfilter feed program and bounce on match" || failed="$failed, do_vfilter feed program and bounce on match" + [ $continue_on_err -eq 0 ] && exit 1 || return 0 + fi + + $sudo env - \ + PATH=/bin:/usr/bin:/usr/sbin \ + ASSIGNDIR=$sysconfdir/users \ + SYSCONFDIR=$sysconfdir \ + CONTROLDIR=$cntrldir \ + vmoddomain -f 0 -h bounce-no-mailbox $domain1 > $logdir/setup/vmoddomain.log + if [ $? -eq 0 ] ; then + tcount=$(expr $tcount + 1) + echo " testing command vmoddomain unset vfilter succeeded" + else + fcount=$(expr $fcount + 1) + if [ $prompt -eq 1 ] ; then + less $logdir/setup/vadddomain.log + fi + echo " testing command vmoddomain unset vfilter failed" + [ -z "$failed" ] && failed="vmoddomain unset vfilter" || failed="$failed, vmoddomain unset vfilter" + [ $continue_on_err -eq 0 ] && exit 1 || return 0 + fi +} + ## begin getopt usage() { @@ -2047,8 +2511,6 @@ check_service mysql.3307 create_domain $domain1 pass do_vdominfo do_dbinfo -echo - create_plain_user $testuser1 $password2 change_password $testuser1 $password1 do_vmoduser $testuser1 @@ -2060,216 +2522,32 @@ if [ -f /etc/nsswitch.conf ] ; then fi fi delete_user $testuser1 -echo -echo "Starting SMTP AUTH, qmail-remote, IMAP/POP3 login tests for plain/cram users" -$sudo svc -2 $servicedir/inlookup.infifo -check_service inlookup.infifo - -for hash in "default" $hash_supported -do - t1="$password2""$hash" - t2="$password3""$hash" - create_plain_user $testuser1 $t1 $hash - create_cram_user $testuser2 $t2 $hash - do_inquerytest $testuser1 - do_inquerytest $testuser2 - echo - echo 1 > $servicedir/smtpd/variables/ENABLE_CRAM - if [ "$hash" = "DES" ] ; then - echo -1 > $servicedir/smtpd/variables/PASSWORD_HASH - else - > $servicedir/smtpd/variables/PASSWORD_HASH - fi - do_smtp_auth_swaks $testuser1 $t1 1 - do_smtp_auth_qmr_o $domain1 $testuser1 $t1 1 - #echo - > $servicedir/smtpd/variables/ENABLE_CRAM - do_smtp_auth_swaks $testuser2 $t2 2 - do_smtp_auth_qmr_o $domain1 $testuser2 $t2 2 - echo - for j in 1 2 - do - case $j in - 1) - str="incache=0" - for i in imap pop3 - do - for k in d d-ssl - do - > $servicedir/"$i"$k/variables/PASSWD_CACHE - > $servicedir/"$i"$k/variables/QUERY_CACHE - if [ "$hash" = "DES" ] ; then - echo -1 > $servicedir/"$i"$k/variables/PASSWORD_HASH - else - > $servicedir/"$i"$k/variables/PASSWORD_HASH - fi - done - done - ;; - 2) - str="incache=1" - for i in imap pop3 - do - for k in d d-ssl - do - echo 1 > $servicedir/"$i"$k/variables/PASSWD_CACHE - echo 1 > $servicedir/"$i"$k/variables/QUERY_CACHE - echo 1 > $servicedir/"$i"$k/variables/OPEN_SMTP - if [ "$hash" = "DES" ] ; then - echo -1 > $servicedir/"$i"$k/variables/PASSWORD_HASH - else - > $servicedir/"$i"$k/variables/PASSWORD_HASH - fi - done - done - ;; - esac - for i in imap pop3 - do - for k in d d-ssl - do - $sudo svc -r $servicedir/"$i"$k - done - done - destdir1=$($sudo $setuidgid indimail envdir $servicedir/smtpd/variables vuserinfo -d $testuser1 | awk '{print $3}') - destdir2=$($sudo $setuidgid indimail envdir $servicedir/smtpd/variables vuserinfo -d $testuser2 | awk '{print $3}') - check_service pop3d 3 - check_service pop3d-ssl 3 - test_pop3 $testuser2 $t2 $testuser1 $destdir2/Maildir - echo - test_pop3 $testuser1 $t1 $testuser2 $destdir1/Maildir - echo - check_service imapd 3 - check_service imapd-ssl 3 - test_imap $testuser2 $t2 $testuser1 $destdir2/Maildir - echo - test_imap $testuser1 $t1 $testuser2 $destdir1/Maildir - echo - done - delete_user $testuser1 - delete_user $testuser2 - echo -done -echo " testing SMTP AUTH, qmail-remote, IMAP/POP3 login tests for plain/cram users succeeded" echo - -echo 1 > $servicedir/smtpd/variables/ENABLE_CRAM -for hash in $hash_supported -do - echo "Starting SMTP AUTH, IMAP/POP3 login, GSASL tests for hash $hash scram users" - t1="$password1""$hash" - t2="$password2""$hash" - create_scram_user SCRAM-SHA-1 $testuser1 $t1 $hash - create_scram_user SCRAM-SHA-256 $testuser2 $t2 $hash - $sudo svc -h $servicedir/inlookup.infifo - echo - sleep $sleep_int - - for j in 1 2 - do - case $j in - 1) - str="incache=0" - > $servicedir/smtpd/variables/PASSWD_CACHE - > $servicedir/smtpd/variables/QUERY_CACHE - if [ "$hash" = "DES" ] ; then - echo -1 > $servicedir/smtpd/variables/PASSWORD_HASH - else - > $servicedir/smtpd/variables/PASSWORD_HASH - fi - for i in imap pop3 - do - for k in d d-ssl - do - > $servicedir/"$i"$k/variables/PASSWD_CACHE - > $servicedir/"$i"$k/variables/QUERY_CACHE - if [ "$hash" = "DES" ] ; then - echo -1 > $servicedir/"$i"$k/variables/PASSWORD_HASH - else - > $servicedir/"$i"$k/variables/PASSWORD_HASH - fi - done - done - ;; - 2) - str="incache=1" - echo 1 > $servicedir/smtpd/variables/PASSWD_CACHE - echo 1 > $servicedir/smtpd/variables/QUERY_CACHE - if [ "$hash" = "DES" ] ; then - echo -1 > $servicedir/smtpd/variables/PASSWORD_HASH - else - > $servicedir/smtpd/variables/PASSWORD_HASH - fi - for i in imap pop3 - do - for k in d d-ssl - do - echo 1 > $servicedir/"$i"$k/variables/PASSWD_CACHE - echo 1 > $servicedir/"$i"$k/variables/QUERY_CACHE - if [ "$hash" = "DES" ] ; then - echo -1 > $servicedir/"$i"$k/variables/PASSWORD_HASH - else - > $servicedir/"$i"$k/variables/PASSWORD_HASH - fi - done - done - ;; - esac - $sudo svc -r $servicedir/smtpd - for i in imap pop3 - do - for k in d d-ssl - do - $sudo svc -r $servicedir/"$i"$k - done - done - destdir1=$($sudo $setuidgid indimail envdir $servicedir/smtpd/variables vuserinfo -d $testuser1 | awk '{print $3}') - check_service pop3d 3 - test_pop3 $testuser1 $t1 $testuser2 $destdir1 - echo - check_service pop3d-ssl 3 - test_imap $testuser1 $t1 $testuser2 $destdir1 - echo - check_service smtpd 3 - if [ -x $gsasl ] ; then - do_gsasl_test "SCRAM-SHA-1" $testuser1 $t1 - do_gsasl_test "SCRAM-SHA-1-PLUS" $testuser1 $t1 - do_gsasl_test "SCRAM-SHA-256" $testuser2 $t2 - do_gsasl_test "SCRAM-SHA-256-PLUS" $testuser2 $t2 - fi - do_smtp_auth_swaks $testuser1 $t1 3 - #echo - do_smtp_auth_qmr_scram "SCRAM-SHA-1" $domain1 $testuser1 $t1 - do_smtp_auth_qmr_scram "SCRAM-SHA-1-PLUS" $domain1 $testuser1 $t1 - do_smtp_auth_qmr_scram "SCRAM-SHA-256" $domain1 $testuser2 $t2 - do_smtp_auth_qmr_scram "SCRAM-SHA-256-PLUS" $domain1 $testuser2 $t2 - echo - do_smtp_auth_qmr_o $domain1 $testuser1 $t1 3 - echo - done - tcount=$(expr $tcount + 1) - delete_user $testuser1 - delete_user $testuser2 - echo - echo " testing SMTP AUTH, IMAP/POP3 login, GSASL tests for hash $hash scram users succeeded" - echo -done -tcount=$(expr $tcount + 3) -printf " testing command tcpserver non-encrypted succeeded\n" -printf " testing command tcpclient non-encrypted succeeded\n" -printf " testing command tcpclient encrypted succeeded\n" -create_scram_user SCRAM-SHA-1 $testuser1 $password1 SHA-512 1 -create_scram_user SCRAM-SHA-256 $testuser2 $password2 SHA-512 1 +create_plain_user $testuser1 $password1 >/dev/null 2>&1 +create_plain_user $testuser2 $password2 >/dev/null 2>&1 +create_plain_user $testuser3 $password3 >/dev/null 2>&1 +do_vfilter echo do_autoresponder $testuser1 $testuser2 echo do_valias $testuser1 $testuser2 +delete_user $testuser1 >/dev/null 2>&1 +delete_user $testuser2 >/dev/null 2>&1 + +$sudo svc -2 $servicedir/inlookup.infifo +check_service inlookup.infifo + +do_plain_user_tests + +do_scram_user_tests + echo echo "Testing domain deletion" delete_domain $domain1 + echo echo "Starting POST Handle tests" do_post_handle $domain1 pass $domain2 $testuser3 $testuser4 $domain3 @@ -2294,6 +2572,12 @@ exit 0 # # $Log: testindimail-virtual,v $ +# Revision 1.8 2023-09-08 11:19:10+05:30 Cprogrammer +# removed duplicate tests +# +# Revision 1.7 2023-09-08 09:31:04+05:30 Cprogrammer +# added vfilter tests +# # Revision 1.6 2023-08-23 13:09:26+05:30 Cprogrammer # formated messages # diff --git a/indimail-x/vadddomain_handle.in b/indimail-x/vadddomain_handle.in index f65177e0b..f67fff240 100644 --- a/indimail-x/vadddomain_handle.in +++ b/indimail-x/vadddomain_handle.in @@ -1,6 +1,6 @@ #!/bin/sh # -# $Id: vadddomain_handle.in,v 2.24 2023-08-07 17:38:12+05:30 Cprogrammer Exp mbhangui $ +# $Id: vadddomain_handle.in,v 2.25 2023-09-05 21:48:01+05:30 Cprogrammer Exp mbhangui $ domaindir=@domaindir@ OPTS=$(getopt -o ateh:T:q:l:bB:E:u:vVRi:g:d:Or:CD:H:U:P:s:p:cfm:S:I: -- "$@") @@ -74,12 +74,12 @@ done # create rule for moving spam, virus emails to folders echo "creating rules for spam, virus detected emails" -@prefix@/bin/vcfilter -i -t spamFilter -c 3 -k "Yes, spamicity=" -f Spam -b 0 -h 32 \ +@prefix@/bin/vcfilter -i -t spamFilter -c "Starts with" -k "Yes, spamicity=" -f Spam -b 0 -h "X-Bogosity" \ prefilt@$domain if [ $? -eq 0 ] ; then echo "Created prefilter to filter SPAM" fi -@prefix@/bin/vcfilter -i -t virusFilter -c 0 -k "virus found" -f Quarantine -b 0 -h 28 \ +@prefix@/bin/vcfilter -i -t virusFilter -c "Equals" -k "virus found" -f Quarantine -b 0 -h "X-QHPSI" \ prefilt@$domain if [ $? -eq 0 ] ; then echo "Created prefilter to filter virus" @@ -124,6 +124,9 @@ vuserinfo postmaster@$domain exit 0 # # $Log: vadddomain_handle.in,v $ +# Revision 2.25 2023-09-05 21:48:01+05:30 Cprogrammer +# allow both textual and numberical values for -c and -h option +# # Revision 2.24 2023-08-07 17:38:12+05:30 Cprogrammer # updated argument list for getopt # diff --git a/indimail-x/variables.c b/indimail-x/variables.c index a35aec648..219c9a829 100644 --- a/indimail-x/variables.c +++ b/indimail-x/variables.c @@ -1,5 +1,8 @@ /* * $Log: variables.c,v $ + * Revision 1.5 2023-09-05 21:48:48+05:30 Cprogrammer + * removed dependency on fnmatch + * * Revision 1.4 2023-03-24 19:05:16+05:30 Cprogrammer * vmoveuser renamed to vmoveuserdir * @@ -24,7 +27,7 @@ #include "dir_control.h" #ifndef lint -static char sccsid[] = "$Id: variables.c,v 1.4 2023-03-24 19:05:16+05:30 Cprogrammer Exp mbhangui $"; +static char sccsid[] = "$Id: variables.c,v 1.5 2023-09-05 21:48:48+05:30 Cprogrammer Exp mbhangui $"; #endif vdir_type vdir; @@ -73,12 +76,9 @@ char *vfilter_comparision[] = { "Does not contain", "Starts with", "Ends with", - "Sender Not in Address Book", "My id not in To, CC, Bcc", "Numerical Logical Expression", -#ifdef HAVE_FNMATCH "RegExp", -#endif 0 }; diff --git a/indimail-x/vcfilter.9 b/indimail-x/vcfilter.9 index 713bae0fa..53eaee4bf 100644 --- a/indimail-x/vcfilter.9 +++ b/indimail-x/vcfilter.9 @@ -20,31 +20,55 @@ has the gid of the domain as a supplementary group. .TP \fB\-v\fR Sets verbose option + .TP \fB\-C\fR Connect to cluster. Allows vcfilter to operate on users belonging to any cluster rather than just the local users. + .TP \fB\-s\fR Show Filters + .TP \fB\-r\fR unformatted display (for -s option) + .TP \fB\-i\fR add filter + .TP \fB\-d\fR \fIfilter_no\fR delete filter(s) + .TP \fB\-u\fR \fIfilter_no\fR update filter + .TP \fB\-t\fR \fIfilter_name\fR Textual name for the filter + +.TP +\fB\-c\fR +Comparison with the headers to make. This could be one of the following +textual name or number. + + 0 - Equals + 1 - Contains + 2 - Does not contain + 3 - Starts with + 4 - Ends with + 5 - Sender not in address book + 6 - My ID not in To, Cc, Bcc + 7 - Numerical or Logical Expression + %p in keyword is replaced with value of data of the Header Field + 8 - RegExp + .TP \fB\-h\fR -header value. A number denoting the following +header value. textual name or number denoting the following -1 - If comparision (-c option) is 5 or 6 0 - Return-Path 1 - From @@ -73,22 +97,6 @@ header value. A number denoting the following You can add your own headers by appending headers to @sysconfdir@/headerlist. -.TP -\fB\-c\fR -Comparison with the headers to make. This could be one of the following -number. - - 0 - Equals - 1 - Contains - 2 - Does not contain - 3 - Starts with - 4 - Ends with - 5 - Sender not in address book - 6 - My ID not in To, Cc, Bcc - 7 - Numerical or Logical Expression - 8 - RegExp - - Note: Mailing List can be specified for Comparison 5 or 6 .TP \fB\-k\fR \fIkeyword\fR @@ -96,6 +104,7 @@ A keyword or string which will be used in comparison with the header value (depending on -c option). The string should be a NULL "" string if -c option is either 5 or 6. The keyword can also be any Regular Expression (i.e. *, ? [], etc) if comparison equals 7.. + .TP \fB\-f\fR \fIFolder\fR Folder to which the mail should be delivered if a filter match occurs. This @@ -110,9 +119,8 @@ completely. 0 - Do not bounce 1 - Bounce mail to sender with the following custom message "Hi. This is the IndiMail MDA for . - I'm afraid I cannot accept your message as my SPAM filter - has decided to reject this email. - Please refrain from sending such mail in future." + "I'm afraid I cannot accept your message as it violates a system policy" + "set by the administrator. Sorry that I cannot accept your email" 2 - Forward mail to address following the number. An ampersand '&' sign must separate the number and the address. i.e. 2&editor@indimail.org will forward all emails diff --git a/indimail-x/vcfilter.c b/indimail-x/vcfilter.c index ef5792f8b..a344b402b 100644 --- a/indimail-x/vcfilter.c +++ b/indimail-x/vcfilter.c @@ -1,30 +1,12 @@ /* - * $Log: vcfilter.c,v $ - * Revision 1.6 2023-01-22 10:40:03+05:30 Cprogrammer - * replaced qprintf with subprintf - * - * Revision 1.5 2021-07-08 11:47:52+05:30 Cprogrammer - * add check for misconfigured assign file - * - * Revision 1.4 2020-06-16 17:56:23+05:30 Cprogrammer - * moved setuserid function to libqmail - * - * Revision 1.3 2019-06-07 15:54:31+05:30 mbhangui - * use sgetopt library for getopt() - * - * Revision 1.2 2019-04-22 23:16:58+05:30 Cprogrammer - * added missing strerr.h - * - * Revision 1.1 2019-04-18 08:38:43+05:30 Cprogrammer - * Initial revision - * + * $Id: vcfilter.c,v 1.7 2023-09-06 18:47:05+05:30 Cprogrammer Exp mbhangui $ */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #ifndef lint -static char sccsid[] = "$Id: vcfilter.c,v 1.6 2023-01-22 10:40:03+05:30 Cprogrammer Exp mbhangui $"; +static char sccsid[] = "$Id: vcfilter.c,v 1.7 2023-09-06 18:47:05+05:30 Cprogrammer Exp mbhangui $"; #endif #ifdef VFILTER @@ -88,19 +70,8 @@ usage() " -i add filter\n" " -d filter_no delete filter(s)\n" " -u filter_no update filter\n" - " -t Filter Name (textual description of filter)\n" - " -h header value\n" - " -1 - If comparision (-c option) is 5 or 6\n"); - for (i = 0; header_list[i];) { - if (header_list[i + 1]) { - subprintfe(subfderr, "vcfilter", "%11s %3d - %-28s %8s %3d - %s\n", - " ", i, header_list[i], " ", i + 1, header_list[i + 1]); - i += 2; - } else { - subprintfe(subfderr, "vcfilter", "%11s %3d - %s\n", " ", i, header_list[i]); - i++; - } - } + " -t Filter Name (textual description of filter)\n"); + subprintfe(subfderr, "vcfilter", " -c comparision\n"); for (i = 0; vfilter_comparision[i];) { if (vfilter_comparision[i + 1]) { @@ -111,8 +82,24 @@ usage() i++; } } + + subprintfe(subfderr, "vcfilter", " -h header value\n" + " -1 - If comparision (-c) option is 5\n"); + if (!(header_list = headerList())) + header_list = vfilter_header; + for (i = 0; header_list[i];) { + if (header_list[i + 1]) { + subprintfe(subfderr, "vcfilter", "%11s %3d - %-28s %8s %3d - %s\n", + " ", i, header_list[i], " ", i + 1, header_list[i + 1]); + i += 2; + } else { + subprintfe(subfderr, "vcfilter", "%11s %3d - %s\n", " ", i, header_list[i]); + i++; + } + } + subprintfe(subfderr, "vcfilter", - " -k keyword [\"\" string if comparision (-c option) is 5 or 6]\n" + " -k keyword [\"\" string if comparision (-c) option is 5]\n" " -f folder [Specify /NoDeliver for delivery to be junked]\n" " -b bounce action\n" " 0 - Do not Bounce to sender\n" @@ -133,23 +120,17 @@ die_nomem() int get_options(int argc, char **argv, char **email, stralloc *faddr, - char **filter_name, char **keyword, stralloc *folder, int *header_name, + char **filter_name, char **keyword, stralloc *folder, int *header_num, int *comparision, int *bounce_action, int *filter_no, int *raw, int *cluster_conn) { - int i, c, max_header, max_comparision; + int i, len, c, max_header_num, max_comparision; char *ptr, *ptr1, *ptr2; char strnum[FMT_ULONG]; - *header_name = *comparision = *bounce_action = *filter_no = -1; + *header_num = *comparision = *bounce_action = *filter_no = -1; *email = *filter_name = *keyword = 0; FilterAction = -1; - if (!(header_list = headerList())) - header_list = vfilter_header; - for (max_header = 0;header_list[max_header];max_header++); - for (max_comparision = 0; vfilter_comparision[max_comparision];max_comparision++); - max_header--; - max_comparision--; *cluster_conn = 0; while ((c = getopt(argc, argv, "vCsird:u:h:c:b:k:f:t:")) != opteof) { switch (c) @@ -186,26 +167,40 @@ get_options(int argc, char **argv, char **email, stralloc *faddr, *filter_no = -1; break; case 'h': + if (!(header_list = headerList())) + header_list = vfilter_header; + for (max_header_num = 0; header_list[max_header_num]; max_header_num++); + max_header_num--; if (isnum(optarg)) { - scan_uint(optarg, (unsigned int *) header_name); - if (*header_name < 0 || *header_name > max_header) { + scan_uint(optarg, (unsigned int *) header_num); + if (*header_num < 0 || *header_num > max_header_num) { strerr_warn3("vcfilter: header value ", optarg, " out of range", 0); usage(); return (1); } } else - *header_name = -1; + *header_num = headerNumber(header_list, optarg); break; case 'c': if (isnum(optarg)) { scan_uint(optarg, (unsigned int *) comparision); - if (*comparision < 0 || *comparision > max_comparision) { - strerr_warn3("vcfilter: comparision value ", optarg, " out of range", 0); - usage(); - return (1); - } - } else + } else { + len = str_len(optarg); *comparision = -1; + for (i = 0; vfilter_comparision[i]; i++) { + if (!str_diffn(optarg, vfilter_comparision[i], len + 1)) { + *comparision = i; + break; + } + } + } + for (max_comparision = 0; vfilter_comparision[max_comparision];max_comparision++); + max_comparision--; + if (*comparision < 0 || *comparision > max_comparision) { + strerr_warn3("vcfilter: comparision value ", optarg, " out of range", 0); + usage(); + return (1); + } break; case 'b': if (isdigit((int) *optarg)) { @@ -233,7 +228,7 @@ get_options(int argc, char **argv, char **email, stralloc *faddr, break; case 'k': *keyword = optarg; - if (*comparision == 7) { + if (*comparision == 6) { for (ptr1 = *keyword, ptr2 = *keyword; *ptr1; ptr1++) { if (!isspace((int) *ptr1)) *ptr2++ = *ptr1; @@ -291,8 +286,8 @@ get_options(int argc, char **argv, char **email, stralloc *faddr, } } } - if (*comparision == 5 || *comparision == 6) { - *header_name = -1; + if (*comparision == 5) { + *header_num = -1; *keyword = 0; } switch(FilterAction) @@ -322,9 +317,9 @@ get_options(int argc, char **argv, char **email, stralloc *faddr, usage(); return (1); } - if (*comparision != 5 && *comparision != 6) { - if (*header_name == -1 || !*keyword) { - if (*header_name == -1) + if (*comparision != 5) { + if (*header_num == -1 || !*keyword) { + if (*header_num == -1) strerr_warn1("vcfilter: -h option not specified", 0); if (!*keyword) strerr_warn1("vcfilter: -k option not specified", 0); @@ -340,7 +335,7 @@ get_options(int argc, char **argv, char **email, stralloc *faddr, int main(int argc, char **argv) { - int i, status = -1, raw = 0, cluster_conn = 0, header_name, + int i, status = -1, raw = 0, cluster_conn = 0, header_num, comparision, bounce_action, filter_no; uid_t uid, uidtmp; gid_t gid, gidtmp; @@ -350,7 +345,7 @@ main(int argc, char **argv) static stralloc user = {0}, domain = {0}, folder = {0}, vfilter_file = {0}, faddr = {0}; if (get_options(argc, argv, &emailid, &faddr, &filter_name, &keyword, &folder, - &header_name, &comparision, &bounce_action, &filter_no, &raw, + &header_num, &comparision, &bounce_action, &filter_no, &raw, &cluster_conn)) return (1); parse_email(emailid, &user, &domain); @@ -412,7 +407,7 @@ main(int argc, char **argv) status = vfilter_display(emailid, raw); break; case FILTER_INSERT: - status = vfilter_insert(emailid, filter_name, header_name, + status = vfilter_insert(emailid, filter_name, header_num, comparision, keyword, folder.s, bounce_action, faddr.s); if (!status && str_diffn(emailid, "prefilt@", 8) && str_diffn(emailid, "postfilt@", 9) && access(vfilter_file.s, F_OK)) { @@ -432,7 +427,7 @@ main(int argc, char **argv) /* * int * vfilter_select(char *emailid, int *filter_no, stralloc *filter_name, - * int *header_name, int *comparision, stralloc *keyword, + * int *header_num, int *comparision, stralloc *keyword, * stralloc *destination, int *bounce_action, stralloc *forward) */ if (!(status = vfilter_delete(emailid, filter_no))) { @@ -441,12 +436,12 @@ main(int argc, char **argv) } break; case FILTER_UPDATE: - status = vfilter_update(emailid, filter_no, header_name, comparision, keyword, folder.s, bounce_action, faddr.s); + status = vfilter_update(emailid, filter_no, header_num, comparision, keyword, folder.s, bounce_action, faddr.s); break; } #ifdef DEBUG printf("action %d, header %d keyword [%s] comparision %d folder [%s] bounce_action %d Forward %s email [%s]\n", - FilterAction, header_name, keyword, comparision, folder, bounce_action, bounce_action == 2 ? faddr.s : "N/A", emailid); + FilterAction, header_num, keyword, comparision, folder, bounce_action, bounce_action == 2 ? faddr.s : "N/A", emailid); #endif if (cluster_conn) iclose(); @@ -461,3 +456,29 @@ main() return (0); } #endif + +/* + * $Log: vcfilter.c,v $ + * Revision 1.7 2023-09-06 18:47:05+05:30 Cprogrammer + * allow both textual and numberical values for -c and -h option + * removed "Sender not in addressbook" + * + * Revision 1.6 2023-01-22 10:40:03+05:30 Cprogrammer + * replaced qprintf with subprintf + * + * Revision 1.5 2021-07-08 11:47:52+05:30 Cprogrammer + * add check for misconfigured assign file + * + * Revision 1.4 2020-06-16 17:56:23+05:30 Cprogrammer + * moved setuserid function to libqmail + * + * Revision 1.3 2019-06-07 15:54:31+05:30 mbhangui + * use sgetopt library for getopt() + * + * Revision 1.2 2019-04-22 23:16:58+05:30 Cprogrammer + * added missing strerr.h + * + * Revision 1.1 2019-04-18 08:38:43+05:30 Cprogrammer + * Initial revision + * + */ diff --git a/indimail-x/vdelivermail.9 b/indimail-x/vdelivermail.9 index 544669d76..426caea92 100644 --- a/indimail-x/vdelivermail.9 +++ b/indimail-x/vdelivermail.9 @@ -1,3 +1,4 @@ +.\" vim: tw=75 .TH vdelivermail 8 .SH NAME vdelivermail \- deliver mails to users in a virtual domain @@ -7,33 +8,39 @@ vdelivermail \- deliver mails to users in a virtual domain .SH DESCRIPTION .PP -\fBvdelivermail\fR delivers mails to users created (by \fBvadddomain(1)\fR) in a virtual domain. -\fBvdelivermail\fR is called by \fBqmail-local\fR through an instruction in the -file .\fIqmail\fR-\fIdefault\fR present in @indimaildir@/domains directory. -\fBvdelivermail\fR is the MDA for IndiMail. Along with a wrapper postdel, \fBvdelivermail\fR -can also be used as the MDA for postfix. \fBqmail-local\fR sets the environment variables +\fBvdelivermail\fR delivers mails to users created (by \fBvadddomain(1)\fR) +in a virtual domain. \fBvdelivermail\fR is called by \fBqmail-local\fR +through an instruction in the file .\fIqmail\fR-\fIdefault\fR present in +@indimaildir@/domains directory. \fBvdelivermail\fR is the MDA for +IndiMail. Along with a wrapper postdel, \fBvdelivermail\fR can also be used +as the MDA for postfix. \fBqmail-local\fR sets the environment variables \fBEXT\fR and \fBHOST\fR. This is used by \fBvdelivermail\fR to set the -user and the domain component of the email address. For postfix, these two environment -variables are set by postdel. If the username is quoted, the quotes are removed. The -user@domain is then searched in the authentication database. If there are any system problems -due to which \fBvdelivermail\fR is unable to locate the user, it exits 111 and the mail gets -deferred. \fBvdelivermail\fR will exit 100 in case the user is not found, locked/overquota, -address is looping, or if vdelivermail is not called correctly. Bounces can be discarded if -you set the environment variable \fBDISCARD_BOUNCE\fR. -If the domain is a clustered domain, \fBvdelivermail\fR attempts -to find the mailstore for the user. If the mailstore is local, it delivers the mail locally. -If the mailstore is a remote server, it invokes \fBqmail-remote(8)\fR to deliver the mail. -If the environment variable QMAIL_EXT is defined, \fBvdelivermail\fR attempts to locate the -username based on qmail Extensions. -.PP -If the user is not found or user is found but is inactive, action taken is as per delivery -instruction (third argument to \fBvdelivermail\fR). If the user is active, \fBvdelivermail\fR -checks for any forward delivery (including aliases) and delivers appropriately. While -delivering, \fBvdelivermail\fR creates the inbox (Maildir format) if the directories do not -exist. \fBvdelivermail\fR defers the mail if stick bit is set on the Maildir to which the mail -is being delivered. -.PP -\fBvdelivermail\fR adds the following headers on delivery of the mail to a Maildir +user and the domain component of the email address. For postfix, these two +environment variables are set by postdel. If the username is quoted, the +quotes are removed. The user@domain is then searched in the authentication +database. If there are any system problems due to which \fBvdelivermail\fR +is unable to locate the user, it exits 111 and the mail gets deferred. +\fBvdelivermail\fR will exit 100 in case the user is not found, +locked/overquota, address is looping, or if vdelivermail is not called +correctly. Bounces can be discarded if you set the environment variable +\fBDISCARD_BOUNCE\fR. If \fBBOUNCE_MAIL\fR is set, vdelivermail bounces the +mail. If the domain is a clustered domain, \fBvdelivermail\fR attempts to +find the mailstore for the user. If the mailstore is local, it delivers the +mail locally. If the mailstore is a remote server, it invokes +\fBqmail-remote(8)\fR to deliver the mail. If the environment variable +QMAIL_EXT is defined, \fBvdelivermail\fR attempts to locate the username +based on qmail Extensions. + +If the user is not found or user is found but is inactive, action taken is +as per delivery instruction (third argument to \fBvdelivermail\fR). If the +user is active, \fBvdelivermail\fR checks for any forward delivery +(including aliases) and delivers appropriately. While delivering, +\fBvdelivermail\fR creates the inbox (Maildir format) if the +directories do not exist. \fBvdelivermail\fR defers the mail if stick bit +is set on the Maildir to which the mail is being delivered. + +\fBvdelivermail\fR adds the following headers on delivery of the mail to a +Maildir .nr step 1 1 .IP \n[step] 3 Delivered-To: specifying the address to which the mail has been delivered @@ -46,15 +53,16 @@ X-Filter: specifying if the mail has been filtered through vfilter. .sp -1 .IP \n+[step] Received: specifying the date and time, the mail was received and delivered. -.PP -\fBvdelivermail\fR looks up the qmail control files blackholedsenders and blackholedpatterns. -If the sender's email address matches an entry in these control files, \fBvdelivermail\fR -discards the mail without bouncing the mail to the sender. A line in these files may be of -the form @host, meaning every address at host. These files are also used by \fBqmail-smtpd\fR -causing SMTP sessions to get blackholed. - -blackholedpatterns gives qmail-smtpd the ability to blackhole E-Mails by comparing the sender -address with a REGEX pattern in blackholedpatterns. + +\fBvdelivermail\fR looks up the qmail control files blackholedsenders and +blackholedpatterns. If the sender's email address matches an entry in +these control files, \fBvdelivermail\fR discards the mail without bouncing +the mail to the sender. A line in these files may be of the form @host, +meaning every address at host. These files are also used by +\fBqmail-smtpd\fR causing SMTP sessions to get blackholed. + +blackholedpatterns gives qmail-smtpd the ability to blackhole E-Mails by +comparing the sender address with a REGEX pattern in blackholedpatterns. Example: *@earthlink.net @@ -63,104 +71,121 @@ Example: answerme@save* *%* -blackholedpatterns file with this contents stops all mail from earthlink except from -fred@earthlink.net. It also stops all mail with addresses like: 12345@123.com and -answerme@savetrees.com. Further, any E-Mail with a sender address containing a percent sign (%) is rejected. +blackholedpatterns file with this contents stops all mail from earthlink +except from fred@earthlink.net. It also stops all mail with addresses +like: 12345@123.com and answerme@savetrees.com. Further, any E-Mail with +a sender address containing a percent sign (%) is rejected. .SH Quota Checking -.PP -\fBvdelivermail\fR uses Maildir++ specification. Maildir++ quota relies on maildirsize file -having correct information, so if your users can modify the file in some way (e.g. shell access), -you're relying on the goodwill of your users for the quota to work. As a trade-off between -accuracy and performance quota recalculation happens when the size of maildirsize file reaches -8192 bytes or update time is more than 43200 seconds. The defaults 8192 and 43200 can be changed -by setting \fBMAILDIRSIZE_MAX_SIZE\fR & \fBMAILDIRSIZE_MAX_AGE\fR environment variales. The -\fBvuserinfo(1)\fR command on a user can also be used to recalculate the quota. - -The maildirsize file in the Maildir root directory contains both the quota limit information -and the current quota status. It contains a header in format: +\fBvdelivermail\fR uses Maildir++ specification. Maildir++ quota relies on +maildirsize file having correct information, so if your users can modify +the file in some way (e.g. shell access), you're relying on the goodwill of +your users for the quota to work. As a trade-off between accuracy and +performance quota recalculation happens when the size of maildirsize file +reaches 8192 bytes or update time is more than 43200 seconds. The defaults +8192 and 43200 can be changed by setting \fBMAILDIRSIZE_MAX_SIZE\fR & +\fBMAILDIRSIZE_MAX_AGE\fR environment variales. The \fBvuserinfo(1)\fR +command on a user can also be used to recalculate the quota. + +The maildirsize file in the Maildir root directory contains both the quota +limit information and the current quota status. It contains a header in +format: + .EX S,C .EE -If the size of the mail is within the quota, or if the size of the mail is less than -OVERQUOTA_MAILSIZE (1000 bytes as defined in indimail.h), but would bring the user -overquota, the mail is delivered and the user's current quota usage updated. Else the mail is -bounced back with Over Quota message. Also if @libexecdir@/overquota.sh exists, the -command is executed with the following arguments +If the size of the mail is within the quota, or if the size of the mail is +less than OVERQUOTA_MAILSIZE (1000 bytes as defined in indimail.h), but +would bring the user overquota, the mail is delivered and the user's +current quota usage updated. Else the mail is bounced back with Over Quota +message. Also if @libexecdir@/overquota.sh exists, the command is executed +with the following arguments + +.EX maildir_path Message_size Current_disk_usage Current_mailcount quota +.EE -.PP -The command overquota.sh can be changed by setting the environment variable \fBOVERQUOTA_CMD\fR. -The default behaviour of bouncing mails on overquota can be changed by setting environment -variable \fBHOLDOVERQUOTA\fR or by having a file \fIholdoverquota\fR in the user's homedir. -In this case, the mail will be deferred till the \fIqueuelifetime\fR gets reached. If -\fBHOLDOVERQUOTA\fR is not defined and neither the file \fIholdoverquota\fR is present -\fBvdelivermail\fR (if the user is already above quota) sets the \fBBOUNCE FLAG\fR for the user. -Subsequent deliveries are bounced without any quota checking. Setting of the \fBBOUNCE_FLAG\fR -reduces the load on the server when multiple mails are being sent to an overquota user. -The \fBBOUNCE FLAG\fR is removed only after the user logs in -and clears the mails to reduce the quota usage. Site administrators can customize -Over Quota Bounce messages, by setting environment variables -\fBQUOTAWARN1\fR, \fBQUOTAWARN2\fR ... upto \fBQUOTAWARN10\fR. These variables should be set to -a percentage quota usage for which warning should be sent. In addition to the \fBEXT\fR and -\fBHOST\fR environment variable, \fBRPLINE\fR and \fBDTLINE\fR variables are also used by -\fBvdelivermail\fR to set the value for \fBReturn-Path\fR, \fBDelivered-To\fR lines in the mail -headers. -.PP -The quota limit for a user can be set by the administrator either in size, number of mails or -combination of both. e.g. 40000,2000S means quota of 40000 Bytes and 2000 mails. Administrator -can use either \fBvsetuserquota\fR or \fBvmoduser\fR programs. -.PP -Additionally per day limit on deliveries per user can be set by specifying the environment -variable \fBMAILCOUNT_LIMIT\fR and \fBMAILSIZE_LIMIT\fR. This can be set in the qmail-send run file -to limit the daily quota of number of emails, size of emails or both. If the number of -deliveries for a user exceeds this number, the mail is bounced back to the sender with over +The command overquota.sh can be changed by setting the environment variable +\fBOVERQUOTA_CMD\fR. The default behaviour of bouncing mails on overquota +can be changed by setting environment variable \fBHOLDOVERQUOTA\fR or by +having a file \fIholdoverquota\fR in the user's homedir. In this case, the +mail will be deferred till the \fIqueuelifetime\fR gets reached. If +\fBHOLDOVERQUOTA\fR is not defined and neither the file \fIholdoverquota\fR +is present \fBvdelivermail\fR (if the user is already above quota) sets the +\fBBOUNCE FLAG\fR for the user. Subsequent deliveries are bounced without +any quota checking. Setting of the \fBBOUNCE_FLAG\fR reduces the load on +the server when multiple mails are being sent to an overquota user. The +\fBBOUNCE FLAG\fR is removed only after the user logs in and clears the +mails to reduce the quota usage. Site administrators can customize Over +Quota Bounce messages, by setting environment variables \fBQUOTAWARN1\fR, +\fBQUOTAWARN2\fR ... upto \fBQUOTAWARN10\fR. These variables should be set +to a percentage quota usage for which warning should be sent. In addition +to the \fBEXT\fR and \fBHOST\fR environment variable, \fBRPLINE\fR and +\fBDTLINE\fR variables are also used by \fBvdelivermail\fR to set the value +for \fBReturn-Path\fR, \fBDelivered-To\fR lines in the mail headers. + +The quota limit for a user can be set by the administrator either in size, +number of mails or combination of both. e.g. 40000,2000S means quota of +40000 Bytes and 2000 mails. Administrator can use either +\fBvsetuserquota\fR or \fBvmoduser\fR programs. + +Additionally per day limit on deliveries per user can be set by specifying +the environment variable \fBMAILCOUNT_LIMIT\fR and \fBMAILSIZE_LIMIT\fR. +This can be set in the qmail-send run file to limit the daily quota of +number of emails, size of emails or both. If the number of deliveries for a +user exceeds this number, the mail is bounced back to the sender with over quota message. .SH Date Folder Delivery -.PP -One can use vmoduser(1) to turn on delivery to a date folder. If this option is turned on, emails -can be delivered to a folder based on the current timestamp. This option is useful if you want -to deliver mails based on the year, month, week, etc. vdelivermail(8) uses strftime(3) to process -the date format for the folder. The file folder.dateformat in user's Maildir is used for storing -the date format for the folder. +One can use vmoduser(1) to turn on delivery to a date folder. If this +option is turned on, emails can be delivered to a folder based on the +current timestamp. This option is useful if you want to deliver mails based +on the year, month, week, etc. vdelivermail(8) uses strftime(3) to process +the date format for the folder. The file folder.dateformat in user's +Maildir is used for storing the date format for the folder. .SH dot-qmail processing - -.PP -Every virtualdomain get's it's own directory under @indimaildir@/domains. qmail's user/assign file -gets an entry for each domain that points qmail-local deliveries into this directory. -Therefore, all normal .qmail file processing works in each virtual domain. .qmail files -just need the user name extension to work, i.e. .qmail-joe for user joe. ezmlm uses .qmail -files for processing, so it will work under IndiMail. -.PP -If no user matches a .qmail file then the .\fIqmail-default\fR file is processed. This file -contains invokation of \fBvdelivermail\fR program with arguments. \fBvdelivermail\fR reads the -authentication database and delivers the mail into the users directory. -The last parameter of \fBvdelivermail\fR determines what \fBvdelivermail\fR does when it does -not find the user. See the section on \fBOptions\fR below. -.PP -In addition to .qmail files, IndiMail has its dot-qmail processing called valias. valias can -be either the file .qmail in the user's home directory or an entry made in MySQL(1) using the -\fBvalias(1)\fR program. You can have multiple delivery lines in .qmail or valias entries in MySQL(1). -vdelivermail will skip processing valias lines, if a line causes exit code of 99 to be returned. +Every virtualdomain get's it's own directory under @indimaildir@/domains. +qmail's user/assign file gets an entry for each domain that points +qmail-local deliveries into this directory. Therefore, all normal .qmail +file processing works in each virtual domain. .qmail files just need the +user name extension to work, i.e. .qmail-joe for user joe. ezmlm uses +.qmail files for processing, so it will work under IndiMail. + +If no user matches a .qmail file then the .\fIqmail-default\fR file is +processed. This file contains invokation of \fBvdelivermail\fR program with +arguments. \fBvdelivermail\fR reads the authentication database and +delivers the mail into the users directory. The last parameter of +\fBvdelivermail\fR determines what \fBvdelivermail\fR does when it does not +find the user. See the section on \fBOptions\fR below. + +In addition to .qmail files, IndiMail has its dot-qmail processing called +valias. valias can be either the file .qmail in the user's home directory +or an entry made in MySQL(1) using the \fBvalias(1)\fR program. You can +have multiple delivery lines in .qmail or valias entries in MySQL(1). +vdelivermail will skip processing valias lines, if a line causes exit code +of 99 to be returned. .SH Mail Alerts -\fBvdelivermail\fR sends alerts in the form of UDP packets to a host and port which can be -specified in the following two ways +\fBvdelivermail\fR sends alerts in the form of UDP packets to a host and +port which can be specified in the following two ways .nr step 1 1 .IP \n[step] 3 By defining environment variables MAILHOST_ALERT and MAILHOST_PORT. .sp -1 .IP \n+[step] -By creating a file mailalert.cfg in the control directory. The first line of this file should have the line host x.x.x.x where x.x.x.x is an IP address. The second line of this file should have the line port port_num where port_num is an integer. +By creating a file mailalert.cfg in the control directory. The first line +of this file should have the line host x.x.x.x where x.x.x.x is an IP +address. The second line of this file should have the line port port_num +where port_num is an integer. .SH Discarding Duplicate Emails -You can discard duplicate emails received within 15 minutes, by setting \fBELIMINATE_DUPS\fR -environment variable. You can change the default time interval of 900 seconds by setting the -\fBDUPLICATE_INTERVAL\fR environment variable in seconds. +You can discard duplicate emails received within 15 minutes, by setting +\fBELIMINATE_DUPS\fR environment variable. You can change the default time +interval of 900 seconds by setting the \fBDUPLICATE_INTERVAL\fR environment +variable in seconds. .SH OPTIONS .TP @@ -168,9 +193,9 @@ environment variable. You can change the default time interval of 900 seconds by Blank double quote for backward compatibility .TP [\fIdefault account for delivery\fR] -If email does not match any virtual domain user (determined by \fBEXT\fR and \fBHOST\fR -environment variable, this is the default delivery instructions. This may be one of the four -values given below. +If email does not match any virtual domain user (determined by \fBEXT\fR +and \fBHOST\fR environment variable, this is the default delivery +instructions. This may be one of the four values given below. .nr step 1 1 .IP \n[step] 3 @@ -193,17 +218,19 @@ the mail. e.g. indimail.org:192.168.1.1:25 .EE -where indimail.org is the local domain, 192.168.1.1 is the IP address of an SMTP server for -indimail.org and 25 is the SMTP port. -.PP -If IndiMail is configured for hard quotas (default is yes with 5 Meg quota), then the size -of the user's current usage Maildir/new and Maildir/cur directories and other folders -(excluding Trash) are counted and added to \fImaildirsize\fR. \fBvdelivermail\fR recalculates once -\fImaildirsize\fR reaches 512 bytes. This ensures that quota is as accurate as possible even if files -are deleted externally. If the user is over quota the email is bounced back to the user with a -bounce message that can be customized (See the section '\fBQuota Checking\fR' above. If the -message is 1Kbytes or smaller the email will always be delivered. This allows system -administration programs to always get a message through to the user. +where indimail.org is the local domain, 192.168.1.1 is the IP address of an +SMTP server for indimail.org and 25 is the SMTP port. + +If IndiMail is configured for hard quotas (default is yes with 5 Mb +quota), then the size of the user's current usage Maildir/new and +Maildir/cur directories and other folders (excluding Trash) are counted and +added to \fImaildirsize\fR. \fBvdelivermail\fR recalculates once +\fImaildirsize\fR reaches 512 bytes. This ensures that quota is as accurate +as possible even if files are deleted externally. If the user is over quota +the email is bounced back to the user with a bounce message that can be +customized (See the section '\fBQuota Checking\fR' above. If the message is +1Kbytes or smaller the email will always be delivered. This allows system +administration programs to always get a message through to the user. .SH RETURN VALUE .TP @@ -213,11 +240,13 @@ if all steps were successful. .TP .IP \[bu] 2 100 -for permanent errors. i.e. if user is over quota or bounce-no-mailbox is set and no matching user is found. +for permanent errors. i.e. if user is over quota or bounce-no-mailbox is +set and no matching user is found. .TP .IP \[bu] 2 111 -for all temporary error occurs during mail delivery and without the error, the mail would have got delivered +for all temporary error occurs during mail delivery and without the error, +the mail would have got delivered .SH "SEE ALSO" vmoduser(1), vsetuserquota(1), vmoddomlimits(1), diff --git a/indimail-x/vdelivermail.c b/indimail-x/vdelivermail.c index c50fa7e8d..82012bd85 100644 --- a/indimail-x/vdelivermail.c +++ b/indimail-x/vdelivermail.c @@ -1,38 +1,5 @@ /* - * $Log: vdelivermail.c,v $ - * Revision 1.11 2023-03-20 10:35:05+05:30 Cprogrammer - * standardize getln handling - * - * Revision 1.10 2023-01-22 10:40:03+05:30 Cprogrammer - * replaced qprintf with subprintf - * - * Revision 1.9 2021-07-27 18:07:23+05:30 Cprogrammer - * set default domain using vset_default_domain - * - * Revision 1.8 2021-06-11 17:01:38+05:30 Cprogrammer - * replaced makeseekable() with mktempfile() from libqmail - * - * Revision 1.7 2020-10-20 13:59:43+05:30 Cprogrammer - * skip creation of maildirfolder file for user's Maildir (INBOX) - * - * Revision 1.6 2020-04-01 18:58:38+05:30 Cprogrammer - * moved authentication functions to libqmail - * - * Revision 1.5 2019-06-17 23:24:18+05:30 Cprogrammer - * fixed SMTPROUTE, QMTPROUTE env variable - * - * Revision 1.4 2019-04-22 23:18:56+05:30 Cprogrammer - * replaced exit with _exit - * - * Revision 1.3 2019-04-21 16:16:04+05:30 Cprogrammer - * fixed directory length returned by prepare_maildir() - * - * Revision 1.2 2019-04-21 11:41:58+05:30 Cprogrammer - * fixed directory lengths - * - * Revision 1.1 2019-04-18 08:15:56+05:30 Cprogrammer - * Initial revision - * + * $Id: vdelivermail.c,v 1.13 2023-09-07 21:09:36+05:30 Cprogrammer Exp mbhangui $ */ #ifdef HAVE_CONFIG_H #include "config.h" @@ -101,7 +68,7 @@ #include "vset_default_domain.h" #ifndef lint -static char sccsid[] = "$Id: vdelivermail.c,v 1.11 2023-03-20 10:35:05+05:30 Cprogrammer Exp mbhangui $"; +static char sccsid[] = "$Id: vdelivermail.c,v 1.13 2023-09-07 21:09:36+05:30 Cprogrammer Exp mbhangui $"; #endif #define FATAL "vdelivermail: fatal: " @@ -229,6 +196,8 @@ prepare_maildir(char *dir, uid_t uid, gid_t gid) die_nomem(); /*- vfilter sets MAILDIRFOLDER to the Maildir where mail needs to be delivered */ if ((maildirfolder = env_get("MAILDIRFOLDER"))) { + if (*maildirfolder != '.' && !stralloc_append(&TheDir, ".")) + die_nomem(); if (!stralloc_cats(&TheDir, maildirfolder) || !stralloc_append(&TheDir, "/")) die_nomem(); @@ -497,6 +466,8 @@ processMail(struct passwd *pw, char *user, char *domain, mdir_t MsgSize) die_nomem(); /*- Call overquota command with 5 arguments */ if ((maildirfolder = env_get("MAILDIRFOLDER"))) { + if (*maildirfolder != '.' && !stralloc_append(&TheDir, ".")) + die_nomem(); if (!stralloc_append(&TheDir, "/") || !stralloc_cats(&TheDir, maildirfolder)) die_nomem(); @@ -618,6 +589,9 @@ reject_mail(char *user, char *domain, int status, mdir_t MsgSize, char *bounce) else if (status == 1) strerr_warn7("no account ", user, "@", domain, " - delivering to ", bounce, ". indimail (#5.1.6) ", 0); + else + if (status == 2) + strerr_warn7("vfilter bounce ", user, "@", domain, " - delivering to ", bounce, ". indimail (#5.1.6) ", 0); if (!stralloc_copys(&_bounce, bounce)) die_nomem(); i = str_chr(bounce, '@'); @@ -954,6 +928,11 @@ main(int argc, char **argv) * in duplicate mails in case * of vset_lastauth() error */ + if (env_get("BOUNCE_MAIL")) { + reject_mail(pw->pw_name, TheDomain, 2, MsgSize, Bounce); + iclose(); + _exit(0); + } #ifdef ENABLE_AUTH_LOGGING if (env_get("ALLOW_INACTIVE")) { processMail(pw, pw->pw_name, TheDomain, MsgSize); @@ -986,3 +965,46 @@ main(int argc, char **argv) iclose(); _exit(0); } + +/* + * $Log: vdelivermail.c,v $ + * Revision 1.13 2023-09-07 21:09:36+05:30 Cprogrammer + * bounce mail if BOUNCE_MAIL environment variable is set + * + * Revision 1.12 2023-09-06 18:49:19+05:30 Cprogrammer + * prepend dot '.' to delivery folder if folder doesn't start with dot + * + * Revision 1.11 2023-03-20 10:35:05+05:30 Cprogrammer + * standardize getln handling + * + * Revision 1.10 2023-01-22 10:40:03+05:30 Cprogrammer + * replaced qprintf with subprintf + * + * Revision 1.9 2021-07-27 18:07:23+05:30 Cprogrammer + * set default domain using vset_default_domain + * + * Revision 1.8 2021-06-11 17:01:38+05:30 Cprogrammer + * replaced makeseekable() with mktempfile() from libqmail + * + * Revision 1.7 2020-10-20 13:59:43+05:30 Cprogrammer + * skip creation of maildirfolder file for user's Maildir (INBOX) + * + * Revision 1.6 2020-04-01 18:58:38+05:30 Cprogrammer + * moved authentication functions to libqmail + * + * Revision 1.5 2019-06-17 23:24:18+05:30 Cprogrammer + * fixed SMTPROUTE, QMTPROUTE env variable + * + * Revision 1.4 2019-04-22 23:18:56+05:30 Cprogrammer + * replaced exit with _exit + * + * Revision 1.3 2019-04-21 16:16:04+05:30 Cprogrammer + * fixed directory length returned by prepare_maildir() + * + * Revision 1.2 2019-04-21 11:41:58+05:30 Cprogrammer + * fixed directory lengths + * + * Revision 1.1 2019-04-18 08:15:56+05:30 Cprogrammer + * Initial revision + * + */ diff --git a/indimail-x/vfilter.8 b/indimail-x/vfilter.8 index 807b820cd..d7d4b80ed 100644 --- a/indimail-x/vfilter.8 +++ b/indimail-x/vfilter.8 @@ -1,3 +1,4 @@ +.\" vim: tw=75 .TH vfilter 8 .SH NAME vfilter \- Filter capable MDA for IndiMail diff --git a/indimail-x/vfilter.c b/indimail-x/vfilter.c index 44dbeb331..c1bfaab2d 100644 --- a/indimail-x/vfilter.c +++ b/indimail-x/vfilter.c @@ -1,51 +1,12 @@ -/*- - * $Log: vfilter.c,v $ - * Revision 1.13 2023-08-31 23:17:40+05:30 Cprogrammer - * run vdelivermail if storeHeader is unsuccessful - * - * Revision 1.12 2023-08-06 15:29:48+05:30 Cprogrammer - * fixed setting emailid from arguments - * - * Revision 1.11 2023-03-26 00:33:30+05:30 Cprogrammer - * fixed code using wait_handler - * - * Revision 1.10 2023-01-22 10:40:03+05:30 Cprogrammer - * replaced qprintf with subprintf - * - * Revision 1.9 2022-12-18 19:28:05+05:30 Cprogrammer - * recoded wait logic - * - * Revision 1.8 2022-05-10 20:01:51+05:30 Cprogrammer - * use headers from include path - * - * Revision 1.7 2021-09-12 20:17:58+05:30 Cprogrammer - * moved replacestr to libqmail - * - * Revision 1.6 2021-07-27 18:07:39+05:30 Cprogrammer - * set default domain using vset_default_domain - * - * Revision 1.5 2021-06-11 17:01:55+05:30 Cprogrammer - * replaced Makeargs(), makeseekable() with makeargs(), mktempfile() from libqmail - * - * Revision 1.4 2020-04-01 18:58:43+05:30 Cprogrammer - * moved authentication functions to libqmail - * - * Revision 1.3 2019-06-07 15:52:44+05:30 mbhangui - * use sgetopt library for getopt() - * - * Revision 1.2 2019-04-22 23:17:07+05:30 Cprogrammer - * added missing strerr.h - * - * Revision 1.1 2019-04-20 08:59:26+05:30 Cprogrammer - * Initial revision - * +/* + * $Id: vfilter.c,v 1.14 2023-09-07 21:09:50+05:30 Cprogrammer Exp mbhangui $ */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #ifndef lint -static char sccsid[] = "$Id: vfilter.c,v 1.13 2023-08-31 23:17:40+05:30 Cprogrammer Exp mbhangui $"; +static char sccsid[] = "$Id: vfilter.c,v 1.14 2023-09-07 21:09:50+05:30 Cprogrammer Exp mbhangui $"; #endif #ifdef VFILTER @@ -61,10 +22,6 @@ static char sccsid[] = "$Id: vfilter.c,v 1.13 2023-08-31 23:17:40+05:30 Cpro #ifdef HAVE_SYS_WAIT_H #include #endif -#ifdef HAVE_FNMATCH_H -#define _GNU_SOURCE -#include -#endif #ifdef HAVE_QMAIL #include #include @@ -80,6 +37,7 @@ static char sccsid[] = "$Id: vfilter.c,v 1.13 2023-08-31 23:17:40+05:30 Cpro #include #include #include +#include #endif #include "common.h" #include "get_real_domain.h" @@ -117,34 +75,6 @@ die_nomem() _exit(111); } -static void -printBounce(char *bounce) -{ - char *ptr, *user, *domain; - - if (str_diffn(bounce, BOUNCE_ALL, str_len(BOUNCE_ALL) + 1)) { - subprintfe(subfdout, "vfilter", "Hi. This is the IndiMail MDA for %s\n", - (ptr = env_get("HOST")) ? ptr : vset_default_domain()); - subprintfe(subfdout, "vfilter", - "I'm afraid I cannot accept your message as a configured filter has decided\n" - "to reject this mail\n" - "Please refrain from sending such mail in future\n"); - } else { - /*- get the last parameter in the .qmail-default file */ - if (!(ptr = env_get("EXT"))) - user = "<>"; - else - user = ptr; - if (!(ptr = env_get("HOST"))) - domain = (ptr = env_get("DEFAULT_DOMAIN")) ? ptr : DEFAULT_DOMAIN; - else - domain = ptr; - subprintfe(subfdout, "vfilter", "No Account %s@%s here by that name. indimail (#5.1.5)", user, domain); - } - flush("vfilter"); - return; -} - int execMda(char **argptr, char **mda) { @@ -181,14 +111,12 @@ static char strnum1[FMT_ULONG], strnum2[FMT_ULONG]; static int myExit(int argc, char **argv, int status, int bounce, char *DestFolder, char *forward) { - char *revision = "$Revision: 1.13 $", *mda; + char *revision = "$Revision: 1.14 $", *mda; static stralloc XFilter = {0}; pid_t pid; int i, werr, wait_status, _status; _status = status; - if (interactive) - _exit(_status ? 1 : 0); if (!stralloc_copyb(&XFilter, "XFILTER=X-Filter: xFilter/IndiMail Revision ", 44) || !stralloc_cats(&XFilter, revision + 11)) die_nomem(); @@ -277,8 +205,14 @@ myExit(int argc, char **argv, int status, int bounce, char *DestFolder, char *fo ; /*- we disregard qutoas */ } if (bounce == 1 || bounce == 3) { - printBounce(argv[2]); - _exit(100); + if (!env_put2("BOUNCE_MAIL", "1")) { + strerr_warn1("vfilter: env_put2: BOUNCE_MAIL=1: ", &strerr_sys); + if (interactive) + return (1); + _exit(111); + } + execMda(argv, &mda); + _exit(111); } } if (DestFolder && *DestFolder && !case_diffb(DestFolder, 10, "/NoDeliver")) { @@ -554,7 +488,7 @@ process_filter(int argc, char **argv, struct header **hptr, char *filterid, int int i, j, email_len, filter_opt, ret = 0, global_filter = 0, max_header_value; char *str, *real_domain; - char **tmp_ptr, **address_list; + char **tmp_ptr; static char **header_list; struct header **ptr; static stralloc tmpUser = {0}, tmpDomain = {0}; @@ -581,32 +515,29 @@ process_filter(int argc, char **argv, struct header **hptr, char *filterid, int if (interactive && verbose && !j++) { if (global_filter) { subprintfe(subfdout, "vfilter", - "No global Filter " - "FilterName Header " - "Comparision " - "Keyword Folder Action\n"); + "No global Filter FilterName" + " Header Comparision " + " Keyword Folder " + "Bounce Forward\n"); } else { subprintfe(subfdout, "vfilter", - "No EmailId " - "FilterName Header " - "Comparision " - "Keyword Folder " - "Action\n"); + "No EmailId FilterName" + " Header Comparision " + " Keyword Folder " + "Bounce Forward\n"); } - print_hyphen(subfdout, "=", 137); + print_hyphen(subfdout, "=", 144); } if (interactive && verbose) format_filter_display(0, *filter_no, filterid, filter_name, *header_name, *comparision, keyword, folder, forward, *bounce_action); flush("vfilter"); /* - * comparision 5 - Sender not in Address Book - * comparision 6 - recipient email not in To, Cc, Bcc + * comparision 5 - recipient email not in To, Cc, Bcc */ - if (!global_filter && (*comparision == 5 || *comparision == 6)) { - address_list = getAddressBook(filterid); + if (!global_filter && *comparision == 5) { if (interactive && verbose) - print_hyphen(subfdout, "=", 137); + print_hyphen(subfdout, "=", 144); for (ret = 0, ptr = hptr; ptr && *ptr && !ret; ptr++) { if (!case_diffb((*ptr)->name, 4, "From") || !case_diffb((*ptr)->name, 11, "Return-Path")) filter_opt = 1; @@ -617,28 +548,8 @@ process_filter(int argc, char **argv, struct header **hptr, char *filterid, int else continue; for (tmp_ptr = (*ptr)->data; tmp_ptr && *tmp_ptr && !ret; tmp_ptr++) { - /*- Sender not in Address Book */ - if (*comparision == 5 && filter_opt == 1) { - for (rewindAddrToken();;) { - if (!(str = addressToken(*tmp_ptr, &email_len))) - break; - if (!case_diffb(str, email_len + 1, filterid)) { - /*- Allow the user to send himself mail */ - ret = 1; - break; - } - for (i = 0; address_list && address_list[i]; i++) { - if (!address_list[i] || !*address_list[i]) - continue; - if (!case_diffb(str, email_len + 1, address_list[i])) { - ret = 1; - break; - } - } - } - } /*- ID not in To, Cc, Bcc */ - if (*comparision == 6 && filter_opt == 2) { + if (filter_opt == 2) { for (rewindAddrToken();;) { if (!(str = addressToken(*tmp_ptr, &email_len))) break; @@ -653,7 +564,7 @@ process_filter(int argc, char **argv, struct header **hptr, char *filterid, int !stralloc_cats(&tmpUser, real_domain) || !stralloc_0(&tmpUser)) die_nomem(); - if (!case_diffb(tmpUser.s, tmpUser.len + 1, filterid)) { + if (!case_diffb(tmpUser.s, tmpUser.len, filterid)) { ret = 1; break; } @@ -664,34 +575,38 @@ process_filter(int argc, char **argv, struct header **hptr, char *filterid, int } /*- for(ret = 0, ptr = hptr;ptr && *ptr && !ret;ptr++) */ if (!ret) { if (interactive && verbose) { - subprintfe(subfdout, "vfilter", "Matched Filter No %d Comparision %s\n", *filter_no, vfilter_comparision[*comparision]); + subprintfe(subfdout, "vfilter", "Matched local Filter No %d Comparision %s Folder %s Bounce %d Forward %s \n", + *filter_no, vfilter_comparision[*comparision], folder->s, *bounce_action, forward->s); flush("vfilter"); } myExit(argc, argv, 1, *bounce_action, folder->s, forward->s); } } else - if (*comparision < 5 || *comparision == 7 || *comparision == 8) { + if (*comparision != 5) { /* * 0 - Equals * 1 - Contains * 2 - Does not contain * 3 - Starts with * 4 - Ends with - * 7 - Numerical logical expression - * 8 - Regular expression + * 5 - Not in To, Cc, Bcc + * 6 - Numerical logical expression + * 7 - Regular expression */ if (*header_name > max_header_value) /*- Invalid header value in vfilter table */ continue; lowerit(keyword->s); for (ptr = hptr; ptr && *ptr; ptr++) { - if (!case_diffb((*ptr)->name, MAX_LINE_LENGTH, header_list[*header_name])) { + if (!case_diffb((*ptr)->name, str_len((*ptr)->name), header_list[*header_name])) { switch (*comparision) { case 0: /*- Equals */ for (tmp_ptr = (*ptr)->data; tmp_ptr && *tmp_ptr; tmp_ptr++) { if (!case_diffb(*tmp_ptr, keyword->len, keyword->s)) { if (interactive && verbose) { - subprintfe(subfdout, "vfilter", "Matched Filter No %d Data %s Keyword %s\n", *filter_no, *tmp_ptr, keyword->s); + subprintfe(subfdout, "vfilter", "Matched %s Filter No %d Type Equals Data %s Keyword %s Bounce %d Folder %s Forward %s\n", + global_filter ? "global" : "local", *filter_no, *tmp_ptr, + keyword->s, *bounce_action, folder->s, forward->s ? forward->s : "noforward"); flush("vfilter"); } myExit(argc, argv, 1, *bounce_action, folder->s, forward->s); @@ -702,7 +617,8 @@ process_filter(int argc, char **argv, struct header **hptr, char *filterid, int for (tmp_ptr = (*ptr)->data; tmp_ptr && *tmp_ptr; tmp_ptr++) { if (str_str(*tmp_ptr, keyword->s)) { if (interactive && verbose) { - subprintfe(subfdout, "vfilter", "Matched Filter No %d Data %s Keyword %s\n", *filter_no, *tmp_ptr, keyword->s); + subprintfe(subfdout, "vfilter", "Matched %s Filter No %d Data %s Keyword %s\n", + global_filter ? "global" : "local", *filter_no, *tmp_ptr, keyword->s); flush("vfilter"); } myExit(argc, argv, 1, *bounce_action, folder->s, forward->s); @@ -718,7 +634,8 @@ process_filter(int argc, char **argv, struct header **hptr, char *filterid, int } if (!ret) { if (interactive && verbose) { - subprintfe(subfdout, "vfilter", "Matched Filter No %d Data %s Keyword %s\n", *filter_no, *tmp_ptr, keyword->s); + subprintfe(subfdout, "vfilter", "Matched %s Filter No %d Data %s Keyword %s\n", + global_filter ? "global" : "local", *filter_no, *tmp_ptr, keyword->s); flush("vfilter"); } myExit(argc, argv, 1, *bounce_action, folder->s, forward->s); @@ -729,7 +646,8 @@ process_filter(int argc, char **argv, struct header **hptr, char *filterid, int if (!str_diffn(*tmp_ptr, keyword->s, keyword->len)) { if (interactive && verbose) { - subprintfe(subfdout, "vfilter", "Matched Filter No %d Data %s Keyword %s\n", *filter_no, *tmp_ptr, keyword->s); + subprintfe(subfdout, "vfilter", "Matched %s Filter No %d Data %s Keyword %s\n", + global_filter ? "global" : "local", *filter_no, *tmp_ptr, keyword->s); flush("vfilter"); } myExit(argc, argv, 1, *bounce_action, folder->s, forward->s); @@ -740,50 +658,43 @@ process_filter(int argc, char **argv, struct header **hptr, char *filterid, int for (tmp_ptr = (*ptr)->data; tmp_ptr && *tmp_ptr; tmp_ptr++) { if ((str = str_str(*tmp_ptr, keyword->s)) && !case_diffb(str, keyword->len, keyword->s)) { if (interactive && verbose) { - subprintfe(subfdout, "vfilter", "Matched Filter No %d Comparision %s Data %s Keyword %s\n", - *filter_no, vfilter_comparision[*comparision], *tmp_ptr, keyword->s); + subprintfe(subfdout, "vfilter", "Matched %s Filter No %d Comparision %s Data %s Keyword %s\n", + global_filter ? "global" : "local", *filter_no, vfilter_comparision[*comparision], *tmp_ptr, keyword->s); flush("vfilter"); } myExit(argc, argv, 1, *bounce_action, folder->s, forward->s); } } break; - case 7: /*- Float */ + case 6: /*- Float */ /*- e.g. tmp_ptr = 0.7, keyword = %p < 0.4 */ for (tmp_ptr = (*ptr)->data; tmp_ptr && *tmp_ptr; tmp_ptr++) { - if (numerical_compare(*tmp_ptr, keyword->s)) { + if (numerical_compare(*tmp_ptr, keyword->s) > 0) { if (interactive && verbose) { - subprintfe(subfdout, "vfilter", "Matched Filter No %d Data %s Keyword %s Folder %s\n", - *filter_no, *tmp_ptr, keyword->s, folder->s); + subprintfe(subfdout, "vfilter", "Matched %s Filter No %d Data %s Keyword %s Folder %s\n", + global_filter ? "global" : "local", *filter_no, *tmp_ptr, keyword->s, folder->s); flush("vfilter"); } myExit(argc, argv, 1, *bounce_action, folder->s, forward->s); } } break; -#ifdef HAVE_FNMATCH - case 8: /*- Regular Expressions */ + case 7: /*- Regular Expressions */ for (tmp_ptr = (*ptr)->data; tmp_ptr && *tmp_ptr; tmp_ptr++) { -#ifdef FNM_CASEFOLD - if (!fnmatch(keyword->s, *tmp_ptr, FNM_PATHNAME | FNM_CASEFOLD)) -#else - if (!fnmatch(keyword->s, *tmp_ptr, FNM_PATHNAME)) -#endif - { + if (matchregex(*tmp_ptr, keyword->s, 0) == 1) { if (interactive && verbose) { - subprintfe(subfdout, "vfilter", "Matched Filter No %d Comparision %s Keyword %s\n", - *filter_no, vfilter_comparision[*comparision], keyword->s); + subprintfe(subfdout, "vfilter", "Matched %s Filter No %d Comparision %s Keyword %s\n", + global_filter ? "global" : "local", *filter_no, vfilter_comparision[*comparision], keyword->s); flush("vfilter"); } myExit(argc, argv, 1, *bounce_action, folder->s, forward->s); } } break; -#endif } /*- switch(comparision) */ - } /*- if (!case_diffb((*ptr)->name, MAX_LINE_LENGTH, header_list[header_name])) */ + } /*- if (!case_diffb((*ptr)->name, str_len((*ptr)->name), header_list[header_name])) */ } /*- for(ptr = hptr;ptr && *ptr;ptr++) */ - } /*- if (comparision < 5 || comparision == 7 || comparision == 8) */ + } /* if (*comparision != 5) */ } /*- for (j = 0;;) */ return; } @@ -957,3 +868,51 @@ main(int argc, char **argv) return (1); } #endif /*- #ifdef VFILTER */ + +/*- + * $Log: vfilter.c,v $ + * Revision 1.14 2023-09-07 21:09:50+05:30 Cprogrammer + * replace fnmatch with matchregex from libqmail + * removed "sender not in addressbook" + * when bouncing email set BOUNCE_MAIL to have vdelivermail bounce + * + * Revision 1.13 2023-08-31 23:17:40+05:30 Cprogrammer + * run vdelivermail if storeHeader is unsuccessful + * + * Revision 1.12 2023-08-06 15:29:48+05:30 Cprogrammer + * fixed setting emailid from arguments + * + * Revision 1.11 2023-03-26 00:33:30+05:30 Cprogrammer + * fixed code using wait_handler + * + * Revision 1.10 2023-01-22 10:40:03+05:30 Cprogrammer + * replaced qprintf with subprintf + * + * Revision 1.9 2022-12-18 19:28:05+05:30 Cprogrammer + * recoded wait logic + * + * Revision 1.8 2022-05-10 20:01:51+05:30 Cprogrammer + * use headers from include path + * + * Revision 1.7 2021-09-12 20:17:58+05:30 Cprogrammer + * moved replacestr to libqmail + * + * Revision 1.6 2021-07-27 18:07:39+05:30 Cprogrammer + * set default domain using vset_default_domain + * + * Revision 1.5 2021-06-11 17:01:55+05:30 Cprogrammer + * replaced Makeargs(), makeseekable() with makeargs(), mktempfile() from libqmail + * + * Revision 1.4 2020-04-01 18:58:43+05:30 Cprogrammer + * moved authentication functions to libqmail + * + * Revision 1.3 2019-06-07 15:52:44+05:30 mbhangui + * use sgetopt library for getopt() + * + * Revision 1.2 2019-04-22 23:17:07+05:30 Cprogrammer + * added missing strerr.h + * + * Revision 1.1 2019-04-20 08:59:26+05:30 Cprogrammer + * Initial revision + * + */ diff --git a/indimail-x/vfilter_filterNo.c b/indimail-x/vfilter_filterNo.c index 69c160f8c..73617dd68 100644 --- a/indimail-x/vfilter_filterNo.c +++ b/indimail-x/vfilter_filterNo.c @@ -1,5 +1,8 @@ /* * $Log: vfilter_filterNo.c,v $ + * Revision 1.2 2023-09-06 18:50:58+05:30 Cprogrammer + * start with filter no 1 for filter not matching 'My ID not in To, Cc, Bcc' + * * Revision 1.1 2019-04-15 10:35:01+05:30 Cprogrammer * Initial revision * @@ -9,7 +12,7 @@ #endif #ifndef lint -static char sccsid[] = "$Id: vfilter_filterNo.c,v 1.1 2019-04-15 10:35:01+05:30 Cprogrammer Exp mbhangui $"; +static char sccsid[] = "$Id: vfilter_filterNo.c,v 1.2 2023-09-06 18:50:58+05:30 Cprogrammer Exp mbhangui $"; #endif #ifdef VFILTER @@ -46,14 +49,14 @@ vfilter_filterNo(char *emailid) return (-1); if (!stralloc_copyb(&SqlBuf, "select high_priority filter_no from vfilter where emailid=\"", 59) || !stralloc_cats(&SqlBuf, emailid) || - !stralloc_catb(&SqlBuf, "\" and filter_no > 1 order by filter_no", 38) || + !stralloc_catb(&SqlBuf, "\" and filter_no > 0 order by filter_no", 38) || !stralloc_0(&SqlBuf)) die_nomem(); if (mysql_query(&mysql[1], SqlBuf.s)) { if (in_mysql_errno(&mysql[1]) == ER_NO_SUCH_TABLE) { if (create_table(ON_LOCAL, "vfilter", FILTER_TABLE_LAYOUT)) return (-1); - return (2); + return (1); } strerr_warn4("vfilter_filterNo: ", SqlBuf.s, ": ", (char *) in_mysql_error(&mysql[1]), 0); return (-1); @@ -62,9 +65,9 @@ vfilter_filterNo(char *emailid) return (-1); if (!in_mysql_num_rows(res)) { in_mysql_free_result(res); - return (2); + return (1); } - for(i = 2; (row = in_mysql_fetch_row(res)); i++) { + for(i = 1; (row = in_mysql_fetch_row(res)); i++) { scan_uint(row[0], (unsigned int *) &filter_no); if (i != filter_no) { in_mysql_free_result(res); diff --git a/indimail-x/vfilter_header.c b/indimail-x/vfilter_header.c index 8df89de80..ddcb34cf3 100644 --- a/indimail-x/vfilter_header.c +++ b/indimail-x/vfilter_header.c @@ -1,5 +1,8 @@ /* * $Log: vfilter_header.c,v $ + * Revision 1.4 2023-09-05 21:50:44+05:30 Cprogrammer + * added headerNumber function to convert textual header name to number + * * Revision 1.3 2023-03-20 10:36:29+05:30 Cprogrammer * standardize getln handling * @@ -15,7 +18,7 @@ #endif #ifndef lint -static char sccsid[] = "$Id: vfilter_header.c,v 1.3 2023-03-20 10:36:29+05:30 Cprogrammer Exp mbhangui $"; +static char sccsid[] = "$Id: vfilter_header.c,v 1.4 2023-09-05 21:50:44+05:30 Cprogrammer Exp mbhangui $"; #endif #ifdef VFILTER @@ -48,6 +51,18 @@ die_nomem() _exit(111); } +int +headerNumber(char **hlist, char *headerName) +{ + int i, len; + + len = str_len(headerName); + for (i = 0; hlist[i]; i++) + if (!str_diffn(headerName, hlist[i], len + 1)) + return i; + return -1; +} + char ** headerList() { diff --git a/indimail-x/vfilter_header.h b/indimail-x/vfilter_header.h index dfaef1736..7b664cc93 100644 --- a/indimail-x/vfilter_header.h +++ b/indimail-x/vfilter_header.h @@ -1,5 +1,8 @@ /* * $Log: vfilter_header.h,v $ + * Revision 1.2 2023-09-05 21:51:05+05:30 Cprogrammer + * added prototype for headerNumber function + * * Revision 1.1 2019-04-13 23:39:28+05:30 Cprogrammer * vfilter_header.h * @@ -12,6 +15,7 @@ #ifdef VFILTER char **headerList(); +int headerNumber(char **, char *); #endif #endif diff --git a/indimail-x/vfilter_insert.c b/indimail-x/vfilter_insert.c index c167ed676..1f4a37c45 100644 --- a/indimail-x/vfilter_insert.c +++ b/indimail-x/vfilter_insert.c @@ -1,5 +1,11 @@ /* * $Log: vfilter_insert.c,v $ + * Revision 1.4 2023-09-06 18:52:25+05:30 Cprogrammer + * handle negative header_num, empty keyword for 'My ID not in To, Cc, Bcc' + * + * Revision 1.3 2023-09-05 21:51:14+05:30 Cprogrammer + * removed "sender not in address book" + * * Revision 1.2 2023-01-22 10:40:03+05:30 Cprogrammer * replaced qprintf with subprintf * @@ -12,7 +18,7 @@ #endif #ifndef lint -static char sccsid[] = "$Id: vfilter_insert.c,v 1.2 2023-01-22 10:40:03+05:30 Cprogrammer Exp mbhangui $"; +static char sccsid[] = "$Id: vfilter_insert.c,v 1.4 2023-09-06 18:52:25+05:30 Cprogrammer Exp mbhangui $"; #endif #ifdef VFILTER @@ -42,7 +48,8 @@ die_nomem() } int -vfilter_insert(char *emailid, char *filter_name, int header_name, int comparision, char *keyword, char *folder, int bounce_action, +vfilter_insert(char *emailid, char *filter_name, int header_num, + int comparision, char *keyword, char *folder, int bounce_action, char *faddr) { int err, filter_no; @@ -51,8 +58,8 @@ vfilter_insert(char *emailid, char *filter_name, int header_name, int comparisio if (iopen((char *) 0)) return (-1); - if(comparision == 5 || comparision == 6) - filter_no = comparision - 5; + if(comparision == 5) + filter_no = 0; else if((filter_no = vfilter_filterNo(emailid)) == -1) { strerr_warn1("vfilter_insert: failed to obtain filter No", 0); @@ -67,11 +74,11 @@ vfilter_insert(char *emailid, char *filter_name, int header_name, int comparisio !stralloc_catb(&SqlBuf, ", \"", 3) || !stralloc_cats(&SqlBuf, filter_name) || !stralloc_catb(&SqlBuf, "\", ", 3) || - !stralloc_catb(&SqlBuf, strnum, fmt_uint(strnum, (unsigned int) header_name)) || + !stralloc_catb(&SqlBuf, strnum, fmt_int(strnum, header_num)) || !stralloc_catb(&SqlBuf, ", ", 2) || !stralloc_catb(&SqlBuf, strnum, fmt_uint(strnum, (unsigned int) comparision)) || !stralloc_catb(&SqlBuf, ", \"", 3) || - !stralloc_cats(&SqlBuf, keyword) || + !stralloc_cats(&SqlBuf, keyword ? keyword : "") || !stralloc_catb(&SqlBuf, "\", \"", 4) || !stralloc_cats(&SqlBuf, folder) || !stralloc_catb(&SqlBuf, "\", \"", 4) ||