From e1ed5775fd16a5e47257964e7d8ae333576a3e8c Mon Sep 17 00:00:00 2001 From: Art Cancro Date: Fri, 14 Jun 2002 20:37:04 +0000 Subject: [PATCH] * 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. --- citadel/ChangeLog | 7 +++ citadel/clientsocket.h | 4 +- citadel/serv_inetcfg.c | 8 +++ citadel/serv_spam.c | 112 +++++++++++++++++++++++++++++++++++++++++ 4 files changed, 130 insertions(+), 1 deletion(-) diff --git a/citadel/ChangeLog b/citadel/ChangeLog index 9d27c96ed..a1b007e70 100644 --- a/citadel/ChangeLog +++ b/citadel/ChangeLog @@ -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 Fri Jul 10 1998 Art Cancro * Initial CVS import + diff --git a/citadel/clientsocket.h b/citadel/clientsocket.h index ead4c907d..21d414c3b 100644 --- a/citadel/clientsocket.h +++ b/citadel/clientsocket.h @@ -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 diff --git a/citadel/serv_inetcfg.c b/citadel/serv_inetcfg.c index cb11d8322..73fddcb0d 100644 --- a/citadel/serv_inetcfg.c +++ b/citadel/serv_inetcfg.c @@ -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); + */ } diff --git a/citadel/serv_spam.c b/citadel/serv_spam.c index 21dfb6068..17074b46c 100644 --- a/citadel/serv_spam.c +++ b/citadel/serv_spam.c @@ -31,6 +31,7 @@ #include #include #include +#include #include "citadel.h" #include "server.h" #include "sysdep_decls.h" @@ -46,8 +47,11 @@ #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$"; } -- 2.39.2