* Disabled the spam strings checker I wrote a few days ago.
authorArt Cancro <ajc@citadel.org>
Fri, 14 Jun 2002 20:37:04 +0000 (20:37 +0000)
committerArt Cancro <ajc@citadel.org>
Fri, 14 Jun 2002 20:37:04 +0000 (20:37 +0000)
* When receiving SMTP, check to see if spamd (the SpamAssassin daemon) is
  running on the local machine.  If yes, run the message through it and
  reject if spam.

citadel/ChangeLog
citadel/clientsocket.h
citadel/serv_inetcfg.c
citadel/serv_spam.c

index 9d27c96ed96db1c82db2d3798136cccab8091c40..a1b007e7016458747216fc099e073bfe1ff12d75 100644 (file)
@@ -1,4 +1,10 @@
  $Log$
+ Revision 591.40  2002/06/14 20:37:03  ajc
+ * Disabled the spam strings checker I wrote a few days ago.
+ * When receiving SMTP, check to see if spamd (the SpamAssassin daemon) is
+   running on the local machine.  If yes, run the message through it and
+   reject if spam.
+
  Revision 591.39  2002/06/12 03:42:21  ajc
  * "Suppress message prompts" has been changed to "Prompt after each message"
    and of course the effect has been reversed.
@@ -3710,3 +3716,4 @@ Sat Jul 11 00:20:48 EDT 1998 Nathan Bryant <bryant@cs.usm.maine.edu>
 
 Fri Jul 10 1998 Art Cancro <ajc@uncensored.citadel.org>
        * Initial CVS import
+
index ead4c907d9d642d3596de3964f1612e68e3f3b9a..21d414c3b52d1160981a060f8fc80f1bf695c1d4 100644 (file)
@@ -12,10 +12,12 @@ int ml_sock_gets(int sock, char *buf);
 int sock_gets(int sock, char *buf);
 int sock_puts(int sock, char *buf);
 
+
 /* 
  * This looks dumb, but it's being done for future portability
  */
-#define sock_close(sock)       close(sock)
+#define sock_close(sock)               close(sock)
+#define sock_shutdown(sock, how)       shutdown(sock, how)
 
 /* 
  * Default timeout for client sessions
index cb11d8322eebccab53d153eb6282a3dc666b532e..73fddcb0dd487102b13a05791bf4755c143b52f8 100644 (file)
@@ -71,6 +71,7 @@ void inetcfg_setTo(struct CtdlMessage *msg) {
 }
 
 
+#ifdef ___NOT_CURRENTLY_IN_USE___
 void spamstrings_setTo(struct CtdlMessage *msg) {
        char buf[SIZ];
        char *conf;
@@ -100,6 +101,7 @@ void spamstrings_setTo(struct CtdlMessage *msg) {
        }
 
 }
+#endif
 
 
 /*
@@ -127,10 +129,12 @@ int inetcfg_aftersave(struct CtdlMessage *msg) {
                           strlen(INTERNETCFG))) {
                                inetcfg_setTo(msg);     /* changing configs */
                        }
+#ifdef ___NOT_CURRENTLY_IN_USE___
                        if (!strncasecmp(&ptr[14], SPAMSTRINGS,
                           strlen(INTERNETCFG))) {
                                spamstrings_setTo(msg); /* changing configs */
                        }
+#endif
                }
 
                ptr = strchr((char *)ptr, '\n');
@@ -152,6 +156,7 @@ void inetcfg_init_backend(long msgnum, void *userdata) {
 }
 
 
+#ifdef ___NOT_CURRENTLY_IN_USE___
 void spamstrings_init_backend(long msgnum, void *userdata) {
        struct CtdlMessage *msg;
 
@@ -161,14 +166,17 @@ void spamstrings_init_backend(long msgnum, void *userdata) {
                        CtdlFreeMessage(msg);
        }
 }
+#endif
 
 
 void inetcfg_init(void) {
        if (getroom(&CC->quickroom, SYSCONFIGROOM) != 0) return;
        CtdlForEachMessage(MSGS_LAST, 1, INTERNETCFG, NULL,
                inetcfg_init_backend, NULL);
+/*
        CtdlForEachMessage(MSGS_LAST, 1, SPAMSTRINGS, NULL,
                spamstrings_init_backend, NULL);
+ */
 }
 
 
index 21dfb6068d84d0928ae083d7e6530ff95513a568..17074b46c5668d612197a755d1d6f7be614cc973 100644 (file)
@@ -31,6 +31,7 @@
 #include <sys/wait.h>
 #include <string.h>
 #include <limits.h>
+#include <sys/socket.h>
 #include "citadel.h"
 #include "server.h"
 #include "sysdep_decls.h"
 #include "msgbase.h"
 #include "tools.h"
 #include "internet_addressing.h"
+#include "clientsocket.h"
 
 
+
+#ifdef ___NOT_CURRENTLY_IN_USE___
 /* Scan a message for spam */
 int spam_filter(struct CtdlMessage *msg) {
        int spam_strings_found = 0;
@@ -79,11 +83,119 @@ int spam_filter(struct CtdlMessage *msg) {
 
        return(0);
 }
+#endif
+
+
+
+/*
+ * Connect to the SpamAssassin server and scan a message.
+ */
+int spam_assassin(struct CtdlMessage *msg) {
+       int sock = (-1);
+       char buf[SIZ];
+       FILE *msg_fp;
+       long content_length;
+       long block_length;
+       int is_spam = 0;
+
+#define SPAMASSASSIN_HOST      "127.0.0.1"
+#define SPAMASSASSIN_PORT      "783"
+
+       msg_fp = tmpfile();
+       if (msg_fp == NULL) return(0);
+
+       /* Connect to the SpamAssassin server */
+       lprintf(9, "Connecting to SpamAssassin\n");
+       sock = sock_connect(SPAMASSASSIN_HOST, SPAMASSASSIN_PORT, "tcp");
+       if (sock < 0) {
+               /* If the service isn't running, just pass the mail
+                * through.  Potentially throwing away mails isn't good.
+                */
+               return(0);
+       }
+
+       /* Measure the message (I don't like doing this with a tempfile
+          but right now it's the only way)
+        */
+       lprintf(9, "Measuring message\n");
+       CtdlRedirectOutput(msg_fp, -1);
+       CtdlOutputPreLoadedMsg(msg, 0L, MT_RFC822, 0, 0, 1);
+       CtdlRedirectOutput(NULL, -1);
+       fseek(msg_fp, 0L, SEEK_END);
+       content_length = ftell(msg_fp);
+       rewind(msg_fp);
+       lprintf(9, "Content-length is %ld\n", content_length);
+
+       /* Command */
+       lprintf(9, "Transmitting command\n");
+       sprintf(buf, "CHECK SPAMC/1.2\r\nContent-length: %ld\r\n\r\n",
+               content_length);
+       lprintf(9, buf);
+       lprintf(9, "sock_write() returned %d\n",
+               sock_write(sock, buf, strlen(buf))
+       );
+       while (content_length > 0) {
+               block_length = sizeof(buf);
+               if (block_length > content_length) {
+                       block_length = content_length;
+               }
+               fread(buf, block_length, 1, msg_fp);
+               sock_write(sock, buf, block_length);
+               content_length -= block_length;
+               lprintf(9, "Wrote %ld bytes (%ld remaining)\n",
+                       block_length, content_length);
+       }
+       fclose(msg_fp); /* this also deletes the file */
+
+       /* Close one end of the socket connection; this tells SpamAssassin
+        * that we're done.
+        */
+       lprintf(9, "sock_shutdown() returned %d\n", 
+               sock_shutdown(sock, SHUT_WR)
+       );
+       
+       /* Response */
+       lprintf(9, "Awaiting response\n");
+        if (sock_gets(sock, buf) < 0) {
+                goto bail;
+        }
+        lprintf(9, "<%s\n", buf);
+       if (strncasecmp(buf, "SPAMD", 5)) {
+               goto bail;
+       }
+        if (sock_gets(sock, buf) < 0) {
+                goto bail;
+        }
+        lprintf(9, "<%s\n", buf);
+       if (!strncasecmp(buf, "Spam: True", 10)) {
+               is_spam = 1;
+       }
+
+       if (is_spam) {
+               if (msg->cm_fields['0'] != NULL) {
+                       phree(msg->cm_fields['0']);
+               }
+               msg->cm_fields['0'] = strdoop(
+                       "Message rejected by SpamAssassin");
+       }
+
+bail:  close(sock);
+       return(is_spam);
+}
 
 
 
 char *Dynamic_Module_Init(void)
 {
+
+/* ** This one isn't in use.  It's a spam filter I wrote, but we're going to
+      try the SpamAssassin stuff instead.
        CtdlRegisterMessageHook(spam_filter, EVT_SMTPSCAN);
+ */
+
+
+       CtdlRegisterMessageHook(spam_assassin, EVT_SMTPSCAN);
+
+
         return "$Id$";
 }