diff -uNr simscan-1.4.0.ORG/config.h simscan-1.4.0/config.h --- simscan-1.4.0.ORG/config.h Thu Jan 1 09:00:00 1970 +++ simscan-1.4.0/config.h Tue Oct 30 17:20:46 2007 @@ -0,0 +1,191 @@ +/* config.h. Generated by configure. */ +/* config.h.in. Generated from configure.in by autoheader. */ + +/* Path to the clamav databases binary */ +/* #undef CLAMAVDBPATH */ + +/* "clamdscan program" */ +#define CLAMDSCAN "/usr/local/bin/clamdscan" + +/* "working directory" */ +#define CONTROLDIR "/var/qmail/control" + +/* run ripmime program */ +#define DO_RIPMIME 1 + +/* enable bogofilter scanning */ +#define ENABLE_BOGOFILTER 1 + +/* "bogofilter program" */ +#define BOGOFILTER "/usr/local/bin/bogofilter" + +/* "bogofilter user" */ +#define BOGOFILTER_DB "/home/qscand/.bogofilter" + +/* "bogofilter user" */ +#define BOGOFILTER_MAXSIZE 600000 + +/* "dspam program" */ +#define DSPAM "/usr/local/bin/dspamc" + +/* "dspam arguments" */ +#define DSPAM_ARGS "" + +/* enable attachment scanning */ +#define ENABLE_ATTACH 1 + +/* enable clamav scanning */ +#define ENABLE_CLAMAV + +/* enable custom smtp reject message with virus name */ +/* #undef ENABLE_CUSTOM_SMTP_REJECT */ + +/* enable drop message */ +/* #undef ENABLE_DROPMSG */ + +/* enable dspam scanning */ +#define ENABLE_DSPAM 1 + +/* dspam --user user@domain option. */ +/* #undef ENABLE_DSPAM_USER */ + +/* dspam default user. */ +#define DSPAM_DEFAULT_USER "qscand" + +/* enable per domain checking */ +#define ENABLE_PER_DOMAIN + +/* enable received header */ +/* #undef ENABLE_RECEIVED */ + +/* enable regex scanner */ +/* #undef ENABLE_REGEX */ + +/* enable spam scanning */ +#define ENABLE_SPAM 1 + +/* spamc -u user@domain option. */ +/* #undef ENABLE_SPAMC_USER */ + +/* scan authenticated users for spam. */ +/* #undef ENABLE_SPAM_AUTH_USER */ + +/* pass spam through to user */ +/* #undef ENABLE_SPAM_PASSTHRU */ + +/* enable trophie scanning */ +/* #undef ENABLE_TROPHIE */ + +/* "system supports nproc ulimit" */ +#define HAS_ULIMIT_NPROC 1 + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_INTTYPES_H */ + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_MEMORY_H */ + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_STDINT_H */ + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_STDLIB_H */ + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_STRINGS_H */ + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_STRING_H */ + +/* Define to 1 if you have the `strsep' function. */ +#define HAVE_STRSEP 1 + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_SYS_STAT_H */ + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_SYS_TYPES_H */ + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_UNISTD_H */ + +/* Name of package */ +#define PACKAGE "simscan" + +/* Define to the address where bug reports for this package should be sent. */ +#define PACKAGE_BUGREPORT "" + +/* Define to the full name of this package. */ +#define PACKAGE_NAME "" + +/* Define to the full name and version of this package. */ +#define PACKAGE_STRING "" + +/* Define to the one symbol short name of this package. */ +#define PACKAGE_TARNAME "" + +/* Define to the version of this package. */ +#define PACKAGE_VERSION "" + +/* "qmail directory" */ +#define QMAILDIR "/var/qmail" + +/* "qmail-queue program" */ +#define QMAILQUEUE "/var/qmail/bin/qmail-queue" + +/* "quarantine directory" */ +#define QUARANTINEDIR "/var/qmail/quarantine" + +/* key for attachment scanner */ +/* #undef RCVD_ATTACH_KEY */ + +/* key for clamav */ +/* #undef RCVD_CLAM_KEY */ + +/* key for dspam */ +/* #undef RCVD_DSPAM_KEY */ + +/* key for regex scanner */ +/* #undef RCVD_REGEX_KEY */ + +/* key for spamassassin */ +/* #undef RCVD_SPAM_KEY */ + +/* key for clamav */ +/* #undef RCVD_TROPHIE_KEY */ + +/* "ripmime program" */ +#define RIPMIME "/usr/local/bin/ripmime" + +/* Path to the sigtool binary. */ +/* #undef SIGTOOLPATH */ + +/* Path to the spamassassin binary */ +/* #undef SPAMASSASSINPATH */ + +/* "spamc program" */ +#define SPAMC "/usr/local/bin/spamc" + +/* "spamc arguments" */ +#define SPAMC_ARGS "" + +/* "spam hits" */ +#define SPAM_HITS 10.0 + +/* Define to 1 if you have the ANSI C header files. */ +/* #undef STDC_HEADERS */ + +/* "path to trophie binary" */ +/* #undef TROPHIEBINARY */ + +/* "path to trophie socket" */ +/* #undef TROPHIESOCKET */ + +/* Version number of package */ +#define VERSION "1.4.0" + +/* one or more virusscanners are active */ +#define VIRUSSCANNER 1 + +/* "working directory" */ +#define WORKDIR "/var/qmail/simscan" diff -uNr simscan-1.4.0.ORG/config.h.in simscan-1.4.0/config.h.in --- simscan-1.4.0.ORG/config.h.in Mon Oct 29 23:14:32 2007 +++ simscan-1.4.0/config.h.in Tue Oct 30 17:20:46 2007 @@ -12,6 +12,18 @@ /* run ripmime program */ #undef DO_RIPMIME +/* enable bogofilter scanning */ +#undef ENABLE_BOGOFILTER + +/* "bogofilter program" */ +#undef BOGOFILTER + +/* "bogofilter user" */ +#undef BOGOFILTER_DB + +/* "bogofilter user" */ +#undef BOGOFILTER_MAXSIZE + /* "dspam program" */ #undef DSPAM @@ -35,6 +47,9 @@ /* dspam --user user@domain option. */ #undef ENABLE_DSPAM_USER + +/* dspam default user. */ +#define DSPAM_DEFAULT_USER "vpopmail" /* enable per domain checking */ #undef ENABLE_PER_DOMAIN diff -uNr simscan-1.4.0.ORG/configure simscan-1.4.0/configure --- simscan-1.4.0.ORG/configure Mon Oct 29 23:14:25 2007 +++ simscan-1.4.0/configure Tue Oct 30 17:20:46 2007 @@ -860,9 +860,13 @@ --enable-dropmsg=y|n Drop message in case of virus/spam found. Don't return error to sender. --enable-dspam=y|n Turn on dspam scanning. default no. --enable-spam-passthru=y|n Pass spam email thru or reject (default disable, reject). - --enable-dspam-user=y|n Set user option to spamc. + --enable-dspam-user=y|n Set user option to dspam. --enable-dspam-path=PATH Full path to spamc program. --enable-dspam-args="args" Override the default dspam arguments. + --enable-dspam-default-user= dspam default user default vpopmail. + --enable-bogofilter=y|n Turn on bogofilter scanning. default no. + --enable-bogofilter-db=PATH Path to DB directory Set option to bogofilter -d default /home/vpopmail/.bogofilter. + --enable-bogofilter-maxsize=SIZE Maximum size to scan by bogofilter. --enable-spam=y|n Turn on spam scanning. default no. --enable-spamc-user=y|n Set user option to spamc. --enable-spam-auth-user=y|n Turn on spam scanning for authenticated users (default no). @@ -872,7 +876,8 @@ --enable-qmaildir=DIR Base qmail directory /var/qmail. --enable-workdir=DIR Directory to unpack emails /var/qmail/simscan. --enable-controldir=DIR Directory to place control files /var/qmail/control. - --enable-quarantinedir=DIR Directory to keep spam and/or infected emails /var/qmail/quarantine. + --enable-quarantine=y|n Turn on to keep spam infected emails into quarantinedir. default no. + --enable-quarantinedir=DIR Directory to keep spam and/or infected emails default /var/qmail/quarantine. --enable-qmail-queue=PATH Full path to qmail-queue program. --enable-trophie-socket=PATH Full path to the trophie socket. --enable-trophie-path=PATH Full path to the trophie binary. @@ -4130,6 +4135,136 @@ #define DSPAM_ARGS "$ENABLE_DSPAM_ARGS" _ACEOF + + # Check whether --enable-dspam-default-user or --disable-dspam-default-user was given. +if test "${enable_dspam_default_user+set}" = set; then + enableval="$enable_dspam_default_user" + DSPAM_DEFAULT_USER="$enableval" +else + + if test "$DSPAM_DEFAULT_USER" = "" + then + DSPAM_DEFAULT_USER="vpopmail" + fi + + +fi; + +cat >>confdefs.h <<_ACEOF +#define DSPAM_DEFAULT_USER "$DSPAM_DEFAULT_USER" +_ACEOF + + + ;; + +esac + +#---------------------------------------------------------------------- + +# Check whether --enable-bogofilter or --disable-bogofilter was given. +if test "${enable_bogofilter+set}" = set; then + enableval="$enable_bogofilter" + ENABLE_BOGOFILTER="$enableval" +else + + ENABLE_BOGOFILTER=no + +fi; +case $ENABLE_BOGOFILTER in +1*|y*|Y*) + ENABLE_BOGOFILTER=1 + +cat >>confdefs.h <<_ACEOF +#define ENABLE_BOGOFILTER $ENABLE_BOGOFILTER +_ACEOF + + ;; +*) + ENABLE_BOGOFILTER=0 + ;; +esac + +case $ENABLE_BOGOFILTER in +1*|y*|Y*) + + # Check whether --enable-spam-passthru or --disable-spam-passthru was given. +if test "${enable_spam_passthru+set}" = set; then + enableval="$enable_spam_passthru" + ENABLE_SPAM_PASSTHRU="$enableval" +else + + ENABLE_SPAM_PASSTHRU=no + +fi; + case $ENABLE_SPAM_PASSTHRU in + 1*|y*|Y*) + ENABLE_SPAM_PASSTHRU=1 + +cat >>confdefs.h <<\_ACEOF +#define ENABLE_SPAM_PASSTHRU +_ACEOF + + ;; + *) + ENABLE_SPAM_PASSTHRU=0 + ;; + esac + ;; +esac + +#---------------------------------------------------------------------- + +case $ENABLE_BOGOFILTER in +1*|y*|Y*) + + echo "$as_me:$LINENO: checking whether we can locate the bogofilter program" >&5 +echo $ECHO_N "checking whether we can locate the bogofilter program... $ECHO_C" >&6 + bogofilter="" + for f in /usr/bin/bogofilter /usr/local/bin/bogofilter + do + if test -f $f + then + bogofilter=$f + break + fi + done + + # Check whether --enable-bogofilter-db or --disable-bogofilter-db was given. +if test "${enable_bogofilter_db+set}" = set; then + enableval="$enable_bogofilter_db" + ENABLE_BOGOFILTER_DB="$enableval" +else + + ENABLE_BOGOFILTER_DB="/home/vpopmail/.bogofilter" + +fi; + +cat >>confdefs.h <<_ACEOF +#define BOGOFILTER_DB "$ENABLE_BOGOFILTER_DB" +_ACEOF + + echo "$as_me:$LINENO: result: yes" >&5 +echo "${ECHO_T}yes" >&6 + +cat >>confdefs.h <<_ACEOF +#define BOGOFILTER "$bogofilter" +_ACEOF + + + # Check whether --enable-bogofilter-maxsize or --disable-bogofilter-maxsize was given. +if test "${enable_bogofilter_maxsize+set}" = set; then + enableval="$enable_bogofilter_maxsize" + ENABLE_BOGOFILTER_MAXSIZE="$enableval" +else + + ENABLE_BOGOFILTER_MAXSIZE=600000 + +fi; + +cat >>confdefs.h <<_ACEOF +#define BOGOFILTER_MAXSIZE $ENABLE_BOGOFILTER_MAXSIZE +_ACEOF + ;; esac @@ -4420,41 +4555,59 @@ #---------------------------------------------------------------------- -# Check whether --enable-quarantinedir or --disable-quarantinedir was given. -if test "${enable_quarantinedir+set}" = set; then - enableval="$enable_quarantinedir" +# Check whether --enable-quarantine or --disable-quarantine was given. +if test "${enable_quarantine+set}" = set; then + enableval="$enable_quarantine" ENABLE_QUARANTINE="$enableval" else ENABLE_QUARANTINE=no fi; +case $ENABLE_QUARANTINE in +1*|y*|Y*) + ENABLE_QUARANTINE=1 + ;; +*) + ENABLE_QUARANTINE=0 + ;; +esac - case $ENABLE_QUARANTINE in - 0*|n*|N*) - ;; - *) - echo "$as_me:$LINENO: checking setting the quarantine directory" >&5 +#---------------------------------------------------------------------- + +case $ENABLE_QUARANTINE in +1*|y*|Y*) + ENABLE_QUARANTINEDIR="" + # Check whether --enable-quarantinedir or --disable-quarantinedir was given. +if test "${enable_quarantinedir+set}" = set; then + enableval="$enable_quarantinedir" + ENABLE_QUARANTINEDIR="$enableval" +else + + ENABLE_QUARANTINEDIR="" + +fi; + + echo "$as_me:$LINENO: checking setting the quarantine directory" >&5 echo $ECHO_N "checking setting the quarantine directory... $ECHO_C" >&6 - quarantinedir="$qmaildir/quarantine" - if test "$quarantinedir" = "" - then - echo "$as_me:$LINENO: result: no" >&5 -echo "${ECHO_T}no" >&6 - { { echo "$as_me:$LINENO: error: Unable to find your quarantinedir directory, specify --enable-quarantinedir." >&5 -echo "$as_me: error: Unable to find your quarantinedir directory, specify --enable-quarantinedir." >&2;} - { (exit 1); exit 1; }; } - fi + if test "$ENABLE_QUARANTINEDIR" = "" + then + quarantinedir="$qmaildir/quarantine" + else + quarantinedir="$ENABLE_QUARANTINEDIR" + fi cat >>confdefs.h <<_ACEOF #define QUARANTINEDIR "$quarantinedir" _ACEOF - echo "$as_me:$LINENO: result: done" >&5 + echo "$as_me:$LINENO: result: done" >&5 echo "${ECHO_T}done" >&6 - ;; - esac + ;; +*) + ;; +esac #---------------------------------------------------------------------- @@ -7118,6 +7271,7 @@ echo " dspam scanning = ON" echo " dspam program = $dspam" echo " dspam arguments = $ENABLE_DSPAM_ARGS" + echo " dspam default user = $DSPAM_DEFAULT_USER" case $ENABLE_SPAM_PASSTHRU in 0*|n*|N*) echo " spam passthru = OFF" @@ -7139,6 +7293,28 @@ *) echo " dspam scanning = OFF" + ;; +esac + +case $ENABLE_BOGOFILTER in + 1*|y*|Y*) + echo " bogofilter scanning = ON" + echo " bogofilter program = $bogofilter" + echo " bogofilter db = $ENABLE_BOGOFILTER_DB" + echo " bogofilter maxsize = $ENABLE_BOGOFILTER_MAXSIZE" + case $ENABLE_SPAM_PASSTHRU in + 0*|n*|N*) + echo " spam passthru = OFF" + ;; + *) + echo " spam passthru = ON" + ;; + esac + + ;; + + *) + echo " bogofilter scanning = OFF" ;; esac diff -uNr simscan-1.4.0.ORG/configure.in simscan-1.4.0/configure.in --- simscan-1.4.0.ORG/configure.in Mon Oct 29 23:13:40 2007 +++ simscan-1.4.0/configure.in Tue Oct 30 17:20:46 2007 @@ -214,7 +214,7 @@ fi done - AC_ARG_ENABLE(dspam-user, [ --enable-dspam-user=y|n Set user option to spamc.], + AC_ARG_ENABLE(dspam-user, [ --enable-dspam-user=y|n Set user option to dspam.], ENABLE_DSPAM_USER="$enableval", [ ENABLE_DSPAM_USER=no @@ -249,6 +249,91 @@ ENABLE_DSPAM_ARGS="" ]) AC_DEFINE_UNQUOTED(DSPAM_ARGS,"$ENABLE_DSPAM_ARGS","dspam arguments") + + AC_ARG_ENABLE(dspam-default-user, + [ --enable-dspam-default-user= dspam default user default vpopmail.], + DSPAM_DEFAULT_USER="$enableval", + [ + if test "$DSPAM_DEFAULT_USER" = "" + then + DSPAM_DEFAULT_USER="vpopmail" + fi + ] + ) + AC_DEFINE_UNQUOTED(DSPAM_DEFAULT_USER,"$DSPAM_DEFAULT_USER","dspam default user") + + ;; + +esac + +#---------------------------------------------------------------------- + +AC_ARG_ENABLE(bogofilter, [ --enable-bogofilter=y|n Turn on bogofilter scanning. default no.], + ENABLE_BOGOFILTER="$enableval", + [ + ENABLE_BOGOFILTER=no + ] ) +case $ENABLE_BOGOFILTER in +1*|y*|Y*) + ENABLE_BOGOFILTER=1 + AC_DEFINE_UNQUOTED([ENABLE_BOGOFILTER], $ENABLE_BOGOFILTER, [enable bogofilter scanning]) + ;; +*) + ENABLE_BOGOFILTER=0 + ;; +esac + +case $ENABLE_BOGOFILTER in +1*|y*|Y*) + + AC_ARG_ENABLE(spam-passthru, [ --enable-spam-passthru=y|n Pass spam email thru or reject (default disable, reject).], + ENABLE_SPAM_PASSTHRU="$enableval", + [ + ENABLE_SPAM_PASSTHRU=no + ] ) + case $ENABLE_SPAM_PASSTHRU in + 1*|y*|Y*) + ENABLE_SPAM_PASSTHRU=1 + AC_DEFINE([ENABLE_SPAM_PASSTHRU], [], [pass spam through to user]) + ;; + *) + ENABLE_SPAM_PASSTHRU=0 + ;; + esac + ;; +esac + +#---------------------------------------------------------------------- + +case $ENABLE_BOGOFILTER in +1*|y*|Y*) + + AC_MSG_CHECKING(whether we can locate the bogofilter program) + bogofilter="" + for f in /usr/bin/bogofilter /usr/local/bin/bogofilter + do + if test -f $f + then + bogofilter=$f + break + fi + done + + AC_ARG_ENABLE(bogofilter-db, [ --enable-bogofilter-db=PATH Path to DB directory Set option to bogofilter -d default /home/vpopmail/.bogofilter.], + ENABLE_BOGOFILTER_DB="$enableval", + [ + ENABLE_BOGOFILTER_DB="/home/vpopmail/.bogofilter" + ] ) + AC_DEFINE_UNQUOTED(BOGOFILTER_DB,"$ENABLE_BOGOFILTER_DB","bogofilter db directory") + AC_MSG_RESULT(yes) + AC_DEFINE_UNQUOTED(BOGOFILTER,"$bogofilter","bogofilter program") + + AC_ARG_ENABLE(bogofilter-maxsize, [ --enable-bogofilter-maxsize=SIZE Maximum size to scan by bogofilter.], + ENABLE_BOGOFILTER_MAXSIZE="$enableval", + [ + ENABLE_BOGOFILTER_MAXSIZE=600000 + ] ) + AC_DEFINE_UNQUOTED(BOGOFILTER_MAXSIZE,$ENABLE_BOGOFILTER_MAXSIZE,"bogofilter maximum scan size") ;; esac @@ -443,30 +528,47 @@ #---------------------------------------------------------------------- -AC_ARG_ENABLE(quarantinedir, - [ --enable-quarantinedir=DIR Directory to keep spam and/or infected emails [/var/qmail/quarantine].], - ENABLE_QUARANTINE="$enableval", - [ +AC_ARG_ENABLE(quarantine, [ --enable-quarantine=y|n Turn on to keep spam infected emails into quarantinedir. default no.], + ENABLE_QUARANTINE="$enableval", + [ ENABLE_QUARANTINE=no - ]) + ] ) +case $ENABLE_QUARANTINE in +1*|y*|Y*) + ENABLE_QUARANTINE=1 + ;; +*) + ENABLE_QUARANTINE=0 + ;; +esac + +#---------------------------------------------------------------------- + +case $ENABLE_QUARANTINE in +1*|y*|Y*) + ENABLE_QUARANTINEDIR="" + AC_ARG_ENABLE(quarantinedir, + [ --enable-quarantinedir=DIR Directory to keep spam and/or infected emails default /var/qmail/quarantine.], + ENABLE_QUARANTINEDIR="$enableval", + [ + ENABLE_QUARANTINEDIR="" + ]) + + AC_MSG_CHECKING(setting the quarantine directory) + if test "$ENABLE_QUARANTINEDIR" = "" + then + quarantinedir="$qmaildir/quarantine" + else + quarantinedir="$ENABLE_QUARANTINEDIR" + fi + AC_DEFINE_UNQUOTED(QUARANTINEDIR,"$quarantinedir","quarantine directory") + AC_SUBST(quarantinedir) + AC_MSG_RESULT(done) + ;; +*) + ;; +esac - case $ENABLE_QUARANTINE in - 0*|n*|N*) - ;; - *) - AC_MSG_CHECKING(setting the quarantine directory) - quarantinedir="$qmaildir/quarantine" - if test "$quarantinedir" = "" - then - AC_MSG_RESULT(no) - AC_MSG_ERROR([Unable to find your quarantinedir directory, specify --enable-quarantinedir.]) - fi - AC_DEFINE_UNQUOTED(QUARANTINEDIR,"$quarantinedir","quarantine directory") - AC_SUBST(quarantinedir) - AC_MSG_RESULT(done) - ;; - esac - #---------------------------------------------------------------------- @@ -894,6 +996,7 @@ echo " dspam scanning = ON" echo " dspam program = $dspam" echo " dspam arguments = $ENABLE_DSPAM_ARGS" + echo " dspam default user = $DSPAM_DEFAULT_USER" case $ENABLE_SPAM_PASSTHRU in 0*|n*|N*) echo " spam passthru = OFF" @@ -915,6 +1018,28 @@ *) echo " dspam scanning = OFF" + ;; +esac + +case $ENABLE_BOGOFILTER in + 1*|y*|Y*) + echo " bogofilter scanning = ON" + echo " bogofilter program = $bogofilter" + echo " bogofilter db = $ENABLE_BOGOFILTER_DB" + echo " bogofilter maxsize = $ENABLE_BOGOFILTER_MAXSIZE" + case $ENABLE_SPAM_PASSTHRU in + 0*|n*|N*) + echo " spam passthru = OFF" + ;; + *) + echo " spam passthru = ON" + ;; + esac + + ;; + + *) + echo " bogofilter scanning = OFF" ;; esac diff -uNr simscan-1.4.0.ORG/simscan.c simscan-1.4.0/simscan.c --- simscan-1.4.0.ORG/simscan.c Mon Oct 29 23:15:05 2007 +++ simscan-1.4.0/simscan.c Tue Oct 30 17:20:46 2007 @@ -38,6 +38,10 @@ #ifdef ENABLE_REGEX #include #endif +/* For Solaris 8 */ +#ifndef INADDR_NONE +#define INADDR_NONE INADDR_BROADCAST +#endif /* qmail-queue error codes */ #define EXIT_0 0 /* Success */ #define EXIT_11 11 /* address too long */ @@ -81,6 +85,9 @@ #define MAX_DSPAM_ARGS 20 char *dspam_args[MAX_DSPAM_ARGS]; +#define MAX_BOGOFILTER_ARGS 20 +char *bogofilter_args[MAX_BOGOFILTER_ARGS]; + #define MAX_SPAMC_ARGS 20 char *spamc_args[MAX_SPAMC_ARGS]; @@ -103,6 +110,8 @@ char *replace(char *string, char *oldpiece, char *newpiece); int DebugFlag = 0; +long _msg_size = 0; + /* To/From address processing globals */ #define MAX_RCPT_TO 255 #define MAX_EMAIL 500 @@ -194,6 +203,15 @@ int is_dspam(char *spambuf); #endif +/* BOGOFILTER scanning globals */ +#if defined(ENABLE_BOGOFILTER) +int InHeaders; +int IsSpam; +char spam_message_name[BUFFER_SIZE]; +int check_bogofilter(); +int is_bogofilter(char *spambuf); +#endif + float SpamHits; float ReqHits; @@ -312,7 +330,9 @@ } /* read the email into the new file */ + _msg_size = 0; while( (ret = read(0, buffer, sizeof(buffer))) > 0 ) { + _msg_size += ret; if ( write(fd, buffer,ret) == -1 ) { if ( DebugFlag > 0 ) { fprintf(stderr, "simscan: error writing msg error: %d\n", errno); @@ -416,6 +436,85 @@ exit_clean(EXIT_400); } +#if defined(ENABLE_BOGOFILTER) +/* The following code is copied from the Spamassassin check below, with the proper adjustments */ + + /* re-open the file read only */ + if ( (fd = open(message_name, O_RDONLY)) == -1 ) { + if ( DebugFlag > 0 ) { + fprintf(stderr, "simscan: spam can not open file: %s\n", message_name); + } + exit_clean(EXIT_400); + } + + /* set the standard input to be the new file */ + if ( fd_move(0,fd) == -1 ) { + if ( DebugFlag > 0 ) { + fprintf(stderr, "simscan: spam could not fd_move\n"); + } + exit_clean(EXIT_400); + } + + /* optionally check for spam with BOGOFILTER */ + snprintf(spam_message_name, sizeof(spam_message_name), "bogo.msg.%s", unique_ext); + IsSpam = 0; + ret = check_bogofilter(); + switch ( ret ) { + /* bogofilter not enabled for this domain */ + case 2: + /* re-open the message file file read only */ + /* do nothing, message_name gets openend in any case*/ + break; + + /* spam detected, refuse message */ + case 1: + if ( DebugFlag > 0 ) { + fprintf(stderr, "simscan: BOGOFILETR reported message as being SPAM\n"); + } + close(fd); + +#ifdef QUARANTINEDIR + quarantine_msg(spam_message_name); + /* put message in quarantine */ +#endif + +#ifdef ENABLE_DROPMSG + if ( DebugFlag > 0 ) { + fprintf(stderr, "simscan: droping the message\n"); + } + exit_clean(EXIT_0); + /* Drop the message, returning success to sender. */ +#else + #ifdef ENABLE_CUSTOM_SMTP_REJECT + snprintf(RejectMsg,sizeof(RejectMsg), "DYour email is considered spam (%.4f probability)", SpamProbability ); + write(4,RejectMsg, strlen(RejectMsg)); + exit_clean(EXIT_MSG); + #else + exit_clean(EXIT_500); + #endif +#endif + break; + + /* bogofilter processed message and no spam detected */ + case 0: + if ( DebugFlag > 0 ) { + fprintf(stderr, "simscan: BOGOFILTER reported message as NOT being SPAM\n"); + } + /* open the spam file read only */ + strncpy(message_name,spam_message_name,BUFFER_SIZE); + break; + /* errors , return temporary error */ + default: + if ( DebugFlag > 0 ) { + fprintf(stderr, "simscan: check_bogofilter had an error ret: %d\n", ret); + } + close(fd); + exit_clean(EXIT_400); + } + +#endif + + #if defined(ENABLE_DSPAM) if (getenv("RELAYCLIENT")==0) { for (i =0; i BOGOFILTER_MAXSIZE ) return(2); + +#ifdef ENABLE_PER_DOMAIN + if ( PerDomainSpam == 0 ) return(2); +#endif + +#ifndef ENABLE_SPAM_AUTH_USER + /* don't scan email from authenticated senders */ + if (getenv("RELAYCLIENT")) { + log_message("RELAYCLIENT", "-", 0); + return 2; + } +#endif + + if ( (spam_fd=open(spam_message_name, O_RDWR|O_CREAT|O_TRUNC,0644)) ==- 1) { + if ( DebugFlag > 0 ) { + fprintf(stderr, "simscan: check_spam could not open spam file: %s\n", + spam_message_name); + } + return(-1); + } + + if ( DebugFlag > 0 ) { + fprintf(stderr, "simscan: calling bogofilter\n"); + } + + /* setup the bogofilter args + */ + + i = 0; + bogofilter_args[i++] = "bogofilter"; + bogofilter_args[i++] = "-e"; + bogofilter_args[i++] = "-p"; + + bogofilter_args[i++] = "-d"; +#ifdef BOGOFILTER_DB + bogofilter_args[i++] = BOGOFILTER_DB; +#else + bogofilter_args[i++] = "/home/vpopmail/.bogofilter"; +#endif + + bogofilter_args[i++] = NULL; + + if ( DebugFlag > 0 ) { + fprintf(stderr, "simscan: calling %s ", BOGOFILTER); + i=0; + while(bogofilter_args[i] != NULL){ + fprintf(stderr, " %s", bogofilter_args[i]); + ++i; + } + fprintf(stderr, "\n"); + } + if ( pipe(pim) == 0 ) { + /* fork bogofilter */ + switch(pid = vfork()) { + case -1: + close(pim[0]); + close(pim[1]); + close(spam_fd); + return(-1); + case 0: + close(pim[0]); + dup2(pim[1],1); + close(pim[1]); + i = execve(BOGOFILTER, bogofilter_args, 0); + fprintf(stderr, "execve returned %d/%d\n", i, errno); + _exit(-1); + } + close(pim[1]); + dup2(pim[0],0); + close(pim[0]); + } else { + close(spam_fd); + return(0); + } + + InHeaders=1; + SpamProbability = 0; + memset(buffer,0,sizeof(buffer)); + + spamfs = fdopen(0,"r"); + IsSpam = 0; + while(fgets(buffer,sizeof(buffer)-1,spamfs) != NULL ) { + if ( InHeaders == 1 ) { + is_bogofilter(buffer); + } + write(spam_fd, buffer,strlen(buffer)); + memset(buffer,0,sizeof(buffer)); + } + + close(spam_fd); + /* wait for bogofilter to finish */ + if (waitpid(pid,&rmstat, 0) == -1) { + return(-1); + } + + /* check if the child died on a signal */ + if ( WIFSIGNALED(rmstat) ) return(-1); + + /* check exit code != 0 */ + if ( WEXITSTATUS(rmstat) ) return(-1); + + #ifdef ENABLE_SPAM_PASSTHRU + #ifdef ENABLE_PER_DOMAIN + if ( PerDomainSpamPassthru == 1) { + if ( IsSpam == 1 ) { + if (DebugFlag > 0) { + fprintf(stderr, + "simscan: delivering spam because spam-passthru is defined in this +domain\n"); + } + log_message("PASSTHRU", Subject,1); + } else { + log_message("CLEAN", Subject,1); + } + return(0); + } else { + if ( IsSpam == 1 ) { +#ifdef ENABLE_DROPMSG + log_message("SPAM DROPPED", Subject, 1); +#else + log_message("SPAM REJECT", Subject,1); +#endif + return(1); + } else { + log_message("CLEAN", Subject,1); + } + } + #else + if ( IsSpam == 1 ) { + log_message("PASSTHRU", Subject,1); + } else { + log_message("CLEAN", Subject,1); + } + return(0); + #endif +#else + if ( IsSpam == 1 ) { +#ifdef ENABLE_DROPMSG + log_message("SPAM DROPPED", Subject, 1); +#else + log_message("SPAM REJECT", Subject,1); +#endif + return(1); + } else { + log_message("CLEAN", Subject,1); + } +#endif + + return(0); + +} +#endif + /* * optionally check for spam @@ -1953,6 +2227,49 @@ #endif +#if defined(ENABLE_BOGOFILTER) +/* Check for a spam message + * This is done by checking for a matching line + * in the email headers for X-DSPAM-Result: which + * we put in each spam email + * + * Return 1 if spam + * Return 0 if not spam + * Return -1 on error + */ +int is_bogofilter(char *spambuf) +{ + int l; + + if ( spambuf[0] == '\n' || spambuf[1] == '\n' ) { + InHeaders = 0; + return(0); + } + + if (strstr(spambuf, "X-Bogosity:")) { + if ( strstr(spambuf, "X-Bogosity: Spam")) { + IsSpam=1; + } + } else if ( strncmp(spambuf, "Subject:", 8 ) == 0 ) { + strncpy(Subject, &spambuf[9], sizeof(Subject)-1); + + /* replace : char with _ and null terminate on + * newline or carrage return + */ + for(l=0;Subject[l]!=0 && l