ports/58805: [Update Feature] SpamAssassin and vpopmail

Alex Dupre sysadmin at alexdupre.com
Sat Nov 1 14:10:30 UTC 2003


>Number:         58805
>Category:       ports
>Synopsis:       [Update Feature] SpamAssassin and vpopmail
>Confidential:   no
>Severity:       serious
>Priority:       medium
>Responsible:    freebsd-ports-bugs
>State:          open
>Quarter:        
>Keywords:       
>Date-Required:
>Class:          update
>Submitter-Id:   current-users
>Arrival-Date:   Sat Nov 01 06:10:24 PST 2003
>Closed-Date:
>Last-Modified:
>Originator:     Alex Dupre
>Release:        FreeBSD 5.1-CURRENT i386
>Organization:
>Environment:
System: FreeBSD armada.alexdupre.com 5.1-CURRENT FreeBSD 5.1-CURRENT #0: Sat Oct 25 14:49:52 CEST 2003 alex at armada.alexdupre.com:/usr/obj/usr/src/sys/ARMADA i386


	
>Description:
Update the spamassassin support for vpopmail.
Add SPAM_THRESHOLD as minimum score required to
automatically delete spam messages.
	
>How-To-Repeat:
	
>Fix:

	

--- vpopmail.diff begins here ---
diff -ruN vpopmail.orig/Makefile vpopmail/Makefile
--- vpopmail.orig/Makefile	Sat Nov  1 14:38:25 2003
+++ vpopmail/Makefile	Sat Nov  1 11:26:14 2003
@@ -61,6 +61,7 @@
 #
 # HARDQUOTA     - size of hard quota, or 'n' for no hard quota
 # RELAYCLEAR    - time in minutes before clearing relay hole (requires roaming)
+# SPAM_THRESHOLD - minimum score required to delete spam messages (requires spamassassin)
 # DEFAULT_DOMAIN - default domain for non-vhost lookups
 # WITH_SINGLE_DOMAIN - optimize for a site with many users in a single domain
 # LOGLEVEL	- n - no logging, y - log all,
@@ -115,6 +116,7 @@
 
 HARDQUOTA?=	10000000
 RELAYCLEAR?=	30
+SPAM_THRESHOLD?=15
 LOGLEVEL?=	y
 
 .if defined(WITH_MYSQL)
@@ -243,7 +245,8 @@
 
 .if defined(WITH_SPAMASSASSIN)
 BUILD_DEPENDS=	spamc:${PORTSDIR}/mail/p5-Mail-SpamAssassin
-CONFIGURE_ARGS+=	--enable-spamassassin=${LOCALBASE}/bin/spamc
+CONFIGURE_ARGS+=	--enable-spamassassin=${LOCALBASE}/bin/spamc \
+			--enable-spam-threshold=${SPAM_THRESHOLD}
 .endif
 
 # autoconf and automake can remove our patches to the configure scripts.
diff -ruN vpopmail.orig/files/patch-config.h.in vpopmail/files/patch-config.h.in
--- vpopmail.orig/files/patch-config.h.in	Fri Oct 31 18:24:01 2003
+++ vpopmail/files/patch-config.h.in	Sat Nov  1 10:59:51 2003
@@ -1,10 +1,13 @@
---- config.h.in.orig	Fri Oct 24 18:43:20 2003
-+++ config.h.in	Fri Oct 24 18:43:45 2003
-@@ -89,6 +89,9 @@
+--- config.h.in.orig	Tue Oct  7 03:25:53 2003
++++ config.h.in	Sat Nov  1 10:59:26 2003
+@@ -89,6 +89,12 @@
  #undef QMAILNEWU
  
  /*  */
 +#undef SPAMC
++
++/*  */
++#undef SPAM_THRESHOLD
 +
 +/*  */
  #undef QMAILINJECT
diff -ruN vpopmail.orig/files/patch-configure vpopmail/files/patch-configure
--- vpopmail.orig/files/patch-configure	Fri Oct 31 18:24:01 2003
+++ vpopmail/files/patch-configure	Sat Nov  1 14:01:44 2003
@@ -1,15 +1,17 @@
 --- configure.orig	Fri Oct 17 01:12:22 2003
-+++ configure	Sat Oct 25 01:18:27 2003
-@@ -20,6 +20,8 @@
++++ configure	Sat Nov  1 14:01:27 2003
+@@ -20,6 +20,10 @@
  ac_help="$ac_help
    --enable-qmail-newmrh=path Full path to qmail-newmrh program"
  ac_help="$ac_help
 +  --enable-spamassassin=path Enable SpamAssassin. Full path to spamc program. default /usr/local/bin/spamc"
 +ac_help="$ac_help
++  --enable-spam-threshold=# or n Automatically delete messages that score more than # spam hits"
++ac_help="$ac_help
    --enable-vpopuser=vpopmail   user vchkpw was installed as."
  ac_help="$ac_help
    --enable-vpopgroup=vchkpw   group vchkpw was installed as."
-@@ -1317,7 +1319,7 @@
+@@ -1317,7 +1321,7 @@
    ;;
  esac
  
@@ -18,7 +20,7 @@
  then
      echo "configure: warning: === vpopmail must be configured as root. ===" 1>&2
      echo "configure: warning: === please switch to the root user and  ===" 1>&2
-@@ -1446,6 +1448,27 @@
+@@ -1446,6 +1450,49 @@
  EOF
  
  
@@ -41,12 +43,34 @@
 +  cat >> confdefs.h <<EOF
 +#define SPAMC "$spamc"
 +EOF
++
++# Check whether --enable-spam-threshold or --disable-spam-threshold was given.
++if test "${enable_spam_threshold+set}" = set; then
++  enableval="$enable_spam_threshold"
++  ENABLE_SPAM_THRESHOLD=$enableval
++else
++
++                        ENABLE_SPAM_THRESHOLD=0
++
++fi
++
++
++case $ENABLE_SPAM_THRESHOLD in
++0*|n*|N*)
++      ;;
++*)
++          cat >> confdefs.h <<EOF
++#define SPAM_THRESHOLD $ENABLE_SPAM_THRESHOLD
++EOF
++
++          ;;
++esac
 +fi
 +
  
  vpopuser="vpopmail"
  # Check whether --enable-vpopuser or --disable-vpopuser was given.
-@@ -1601,15 +1624,6 @@
+@@ -1601,15 +1648,6 @@
  EOF
  
  
@@ -62,7 +86,7 @@
  # Check whether --enable-roaming-users or --disable-roaming-users was given.
  if test "${enable_roaming_users+set}" = set; then
    enableval="$enable_roaming_users"
-@@ -1671,17 +1685,7 @@
+@@ -1671,17 +1709,7 @@
  if test "${enable_tcpserver_file+set}" = set; then
    enableval="$enable_tcpserver_file"
    tcpserver_file="$enableval"
diff -ruN vpopmail.orig/files/patch-vdelivermail.c vpopmail/files/patch-vdelivermail.c
--- vpopmail.orig/files/patch-vdelivermail.c	Fri Oct 31 18:24:01 2003
+++ vpopmail/files/patch-vdelivermail.c	Sat Nov  1 11:23:37 2003
@@ -1,6 +1,25 @@
 --- vdelivermail.c.orig	Mon Oct 20 20:59:57 2003
-+++ vdelivermail.c	Fri Oct 24 18:31:45 2003
-@@ -257,7 +257,7 @@
++++ vdelivermail.c	Sat Nov  1 11:21:15 2003
+@@ -62,6 +62,7 @@
+ #define FILE_SIZE 156
+ char hostname[FILE_SIZE];
+ char loop_buf[FILE_SIZE];
++char spam_buf[FILE_SIZE];
+ 
+ #define MSG_BUF_SIZE 5000
+ char msgbuf[MSG_BUF_SIZE];
+@@ -90,6 +91,10 @@
+ void usernotfound(void);
+ int is_loop_match( char *dt, char *address);
+ int deliver_quota_warning(const char *dir, const char *q);
++#ifdef SPAM_THRESHOLD
++int is_spam(int threshold);
++int is_spam_match(char *xsl, int threshold);
++#endif
+ 
+ static char local_file[156];
+ static char local_file_new[156];
+@@ -257,7 +262,7 @@
  
      /* check for wildcard if there's no match */
      if(tmpstr == NULL) {
@@ -9,7 +28,7 @@
              if(TheUser[i-1]=='-') {
                  tmpuser[0] = '\0';
                  strncat(tmpuser,TheUser,i); 
-@@ -444,6 +444,7 @@
+@@ -444,6 +449,7 @@
   int inject = 0;
   FILE *fs;
   char tmp_file[256];
@@ -17,7 +36,7 @@
  
      /* check if the email is looping to this user */
      if ( is_looping( address ) == 1 ) {
-@@ -631,6 +632,30 @@
+@@ -631,6 +637,51 @@
          }
      }
  
@@ -35,7 +54,7 @@
 +                dup2(pim[1], 1);
 +                close(pim[1]);
 +                if (execl(SPAMC, SPAMC, "-u", maildir_to_email(address), 0) == -1) {
-+                    while ((file_count=read(0, msgbuf, MSG_BUF_SIZE)) > 0)
++                    while ((file_count = read(0, msgbuf, MSG_BUF_SIZE)) > 0)
 +                        write(1, msgbuf, file_count);
 +                    _exit(0);
 +                }
@@ -44,7 +63,144 @@
 +        dup2(pim[0], 0);
 +        close(pim[0]);
 +    }
++#ifdef SPAM_THRESHOLD
++    /* silently delete message if spam level > SPAM_THRESHOLD */
++    if (is_spam(SPAM_THRESHOLD) == 1) {
++        close(write_fd);
++        if (unlink(local_file) != 0) {
++            printf("unlink failed %s errno = %d\n", local_file, errno);
++            return(errno);
++        }
++        return(0);
++    }
++
++#ifdef MAKE_SEEKABLE
++    if (!Seekable(0))
++        MakeSeekable(stdin);
++#endif
++
++    if (lseek(0, 0L, SEEK_SET) < 0) {
++        printf("lseek errno=%d\n", errno);
++        return(errno);
++    }
++#endif
 +#endif
  
      /* read it in chunks and write it to the new file */
      while((file_count=read(0,msgbuf,MSG_BUF_SIZE))>0) {
+@@ -881,6 +932,9 @@
+         if (strncmp(loop_buf, "Delivered-To: ", 14) == 0 &&
+             is_loop_match(loop_buf, address)==1 ) {
+ 
++            /* seek to the end of stdin */
++            fseek(stdin, 0L, SEEK_END);
++
+             /* return the loop found */
+             return(1);
+ 
+@@ -919,6 +973,8 @@
+              * looping not found value
+             */
+             if ( found == 0 ) {
++                /* seek to the end of stdin */
++                fseek(stdin, 0L, SEEK_END);
+                 /* return not found looping message value */
+                 return(0);
+             }
+@@ -1335,3 +1391,96 @@
+    return(1);
+ }
+ 
++#ifdef SPAM_THRESHOLD
++/* Check for a spam message
++ * This is done by checking for a matching line
++ * in the email headers for X-Spam-Level: which
++ * we put in each spam email
++ *
++ * Return 1 if spam
++ * Return 0 if not spam
++ * Return -1 on error
++ */
++int is_spam(int threshold)
++{
++ int i;
++ int found;
++
++#ifdef MAKE_SEEKABLE
++    if (!Seekable(0))
++        MakeSeekable(stdin);
++#endif
++
++    if ( lseek(0, 0L, SEEK_SET) < 0 ) {
++        printf("lseek errno=%d\n", errno);
++        return(errno);
++    }
++
++    while (fgets(spam_buf, sizeof(spam_buf), stdin) != NULL){
++
++        /* if we find the line, return error (looping) */
++        if (strncmp(spam_buf, "X-Spam-Level: ", 14) == 0 &&
++            is_spam_match(spam_buf, threshold) ==1) {
++
++            /* seek to the end of stdin */
++            fseek(stdin, 0L, SEEK_END);
++
++            /* return the spam found */
++            return(1);
++
++            /* check for the start of the body, we only need
++            * to check the headers.
++            */
++        } else {
++
++            /* walk through the charaters in the body */
++            for (i = 0, found = 0; spam_buf[i] != 0 && found == 0; ++i) {
++                switch(spam_buf[i]) {
++
++                    /* skip blank spaces and new lines */
++                    case ' ':
++                    case '\n':
++                    case '\t':
++                    case '\r':
++                        break;
++
++                    /* found a non blank, so we are still
++                    * in the headers
++                    */
++                    default:
++
++                        /* set the found non blank char flag */
++                        found = 1;
++                        break;
++                }
++            }
++
++            /* if the line only had blanks, then it is the
++             * delimiting line between the headers and the
++             * body. We don't need to check the body for
++             * the X-Spam-Level: line. Hence, we
++             * are done with our search and can return the
++             * spam not found value
++            */
++            if (found == 0) {
++                /* seek to the end of stdin */
++                fseek(stdin, 0L, SEEK_END);
++                /* return not found spam message value */
++                return(0);
++            }
++        }
++    }
++
++    /* if we get here then the there is either no body
++     * or the logic above failed and we scanned
++     * the whole email, headers and body.
++     */
++    return(0);
++}
++
++int is_spam_match(char *xsl, int threshold)
++{
++    if (strlen(xsl) - strlen("X-Spam-Level: ") > threshold) return(1);
++    else return(0);
++}
++#endif
--- vpopmail.diff ends here ---



>Release-Note:
>Audit-Trail:
>Unformatted:



More information about the freebsd-ports-bugs mailing list