* Added support for any standard RBL
authorArt Cancro <ajc@citadel.org>
Fri, 14 Feb 2003 16:12:05 +0000 (16:12 +0000)
committerArt Cancro <ajc@citadel.org>
Fri, 14 Feb 2003 16:12:05 +0000 (16:12 +0000)
citadel/ChangeLog
citadel/docs/citadel.html
citadel/domain.c
citadel/locate_host.c
citadel/locate_host.h
citadel/routines2.c
citadel/serv_smtp.c

index eb725e5400d1f051b4fa7391aa0649fafe8e12ed..208ebfcd22312b19e61c14e8f298d4f79a0c3e3a 100644 (file)
@@ -1,4 +1,7 @@
  $Log$
+ Revision 601.133  2003/02/14 16:12:04  ajc
+ * Added support for any standard RBL
+
  Revision 601.132  2003/02/13 22:33:41  ajc
  * Fixed algorithm for reporting "last login"
 
@@ -4469,3 +4472,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 23c1c1b389a06f8ed2d6d0dbda124087a3047190..babd1dc8e03b711cfed1e5aeebf7d07c0ae4ecc0 100644 (file)
@@ -1776,8 +1776,11 @@ installed   separately)</li>
        <li>Global address book (Users with addresses in a domain may be spread 
   out across many servers on a Citadel network)</li>
        <li>Easy-to-configure integration with <a
- href="http://www.spamassassin.org/">SpamAssassin</a> can block spam <i>before</i> 
+ href="http://www.spamassassin.org/">SpamAssassin</a> can block
+spam <i>before</i> 
   it enters the mail system</li>
+       <li>Easy-to-configuration integration with most Realtime Blackhole
+Lists (RBL) provide further defense against spammers</li>
          
 </ul>
      This section of the documentation will demonstrate how to configure
@@ -1794,7 +1797,19 @@ the <tt><b>.A</b>ide <b>S</b>ystem configuration <b>I</b>nternet</tt> command:</
 <p>This is a "clean" setup.  For a simple, standalone e-mail system you simply
   have to enter the <tt><b>A</b>dd</tt> command:</p>
           
-<pre>&lt;A&gt;dd &lt;D&gt;elete &lt;S&gt;ave &lt;Q&gt;uit  -&gt; <b>A</b>dd<br><br>Enter host name: schmeep.splorph.com<br> (1) localhost       (Alias for this computer)<br> (2) gateway domain  (Domain for all Citadel systems)<br> (3) smart-host      (Forward all outbound mail to this host)<br> (4) directory       (Consult the Global Address Book)<br> (5) SpamAssassin    (Address of SpamAssassin server)<br><br>Which one [1]:<br></pre>
+<pre>
+&lt;A&gt;dd &lt;D&gt;elete &lt;S&gt;ave &lt;Q&gt;uit  -&gt; <b>A</b>dd
+
+Enter host name: schmeep.splorph.com
+ (1) localhost       (Alias for this computer)
+ (2) gateway domain  (Domain for all Citadel systems)
+ (3) smart-host      (Forward all outbound mail to this host)
+ (4) directory       (Consult the Global Address Book)
+ (5) SpamAssassin    (Address of SpamAssassin server)
+ (6) RBL             (domain suffix of spam hunting RBL)
+
+Which one [1]:
+</pre>
           
 <p><b>localhost:</b> Basically what you're doing here is telling Citadel
 what any aliases for your machine are. If your machine were <tt>schmeep.splorph.com</tt>
@@ -1859,6 +1874,22 @@ host.    This is superior to software which files away spam in a separate
 folder,   because delivery failures will cause some spammers to assume the
 address  is invalid and remove it from their mailing lists.</p>
           
+<p><b>RBL:</b> Realtime Blackhole Lists (RBL's) provide defense against
+spammers based on their source IP address.  There are many such lists available
+on the Internet, some of which may be utilized free of charge.  Since they
+are DNS based, the lists do not require storage on your server -- they are
+queried during the SMTP conversation.</p>
+
+<p>Citadel can utilize any RBL that uses the
+<tt>z.y.x.w.nameoflist.org</tt> syntax, where <tt>w.x.y.z</tt> is the
+source IP address which is attempting to deliver mail to your server.  For
+example, <a href="http://www.spamcop.net">SpamCop</a> would use the query
+<tt>2.0.0.127.bl.spamcop.net</tt> to determine whether the host at
+<tt>127.0.0.2</tt> is a known spammer or open relay.  In this case, you
+simply select option '6' to add an RBL entry, and provide it with the
+domain suffix of <tt>bl.spamcop.net</tt> (the IP address and extra dot will
+be automatically prepended for each query).</p>
+
 <p>Now select <tt><b>S</b>ave</tt> and you are just about ready for Internet
   e-mail.</p>
           
index ac47dcb7eaf6cbea3553a2507ee4c04001c84d3b..1c43ef513671818696968547ef0b003d64763cc0 100644 (file)
@@ -142,7 +142,6 @@ int getmx(char *mxbuf, char *dest) {
        n = get_hosts(mxbuf, "smarthost");
        if (n > 0) return(n);
 
-
        /*
         * No smart-host?  Look up the best MX for a site.
         */
@@ -152,16 +151,12 @@ int getmx(char *mxbuf, char *dest) {
        /*
         * On systems with b0rken or non-standard resolver libraries, learn
         * the MX records by calling "nslookup" from the command line.
+        *
+        * Someday.
+        *
         */
-       sprintf(buf, "nslookup -query=mx %s", dest);
-       fp = popen(buf, "r");
-       if (fp == NULL) return(0);
-       while (fgets(buf, sizeof buf, fp) != NULL) {
-               buf[strlen(buf) - 1] = 0;
-               lprintf(9, "RESOLV: %s\n", buf);
-       }
-       pclose(fp);
-       return(0);      /* FIXME */
+
+       return(0);
 
 #else /* HAVE_RESOLV_H */
 
index 3f50fe60a714d1882116e25e3b1c91a97359cfaf..de88d33f70d09a7096097026ef65f04837b64e90 100644 (file)
@@ -5,10 +5,6 @@
  *
  */
 
-#ifdef DLL_EXPORT
-#define IN_LIBCIT
-#endif
-
 #include "sysdep.h"
 #include <stdlib.h>
 #include <unistd.h>
@@ -27,6 +23,7 @@
 #include "sysdep_decls.h"
 #include "config.h"
 #include "tools.h"
+#include "domain.h"
 
 void locate_host(char *tbuf, size_t n, const struct in_addr *addr)
 {
@@ -79,3 +76,63 @@ void locate_host(char *tbuf, size_t n, const struct in_addr *addr)
        tbuf[63] = 0;
        lprintf(9, "locate_host() exiting\n");
 }
+
+
+/*
+ * Check to see if a host is on some sort of spam list (RBL)
+ * If spammer, returns nonzero and places reason in 'message_to_spammer'
+ */
+int rbl_check_addr(struct in_addr *addr, char *message_to_spammer)
+{
+       const char *i;
+       int a1, a2, a3, a4;
+       char tbuf[SIZ];
+       int rbl;
+       int num_rbl;
+       char rbl_domains[SIZ];
+
+       strcpy(message_to_spammer, "ok");
+
+       i = (const char *) addr;
+       a1 = ((*i++) & 0xff);
+       a2 = ((*i++) & 0xff);
+       a3 = ((*i++) & 0xff);
+       a4 = ((*i++) & 0xff);
+
+       /* See if we have any RBL domains configured */
+       num_rbl = get_hosts(rbl_domains, "rbl");
+       if (num_rbl < 1) return(0);
+
+       /* Try all configured RBL */
+        for (rbl=0; rbl<num_rbl; ++rbl) {
+               snprintf(tbuf, sizeof tbuf,
+                       "%d.%d.%d.%d.",
+                       a4, a3, a2, a1);
+                extract(&tbuf[strlen(tbuf)], rbl_domains, rbl);
+
+               if (gethostbyname(tbuf) != NULL) {
+                       strcpy(message_to_spammer,
+                               "Message rejected due to "
+                               "known spammer source IP address"
+                       );
+                       return(1);
+               }
+       }
+
+       return(0);
+}
+                       
+
+/*
+ * Check to see if the client host is on some sort of spam list (RBL)
+ * If spammer, returns nonzero and places reason in 'message_to_spammer'
+ */
+int rbl_check(char *message_to_spammer) {
+       struct sockaddr_in sin;
+       socklen_t len;
+
+       if (!getpeername(CC->client_socket, (struct sockaddr *) &sin, &len)) {
+               return(rbl_check_addr(&sin.sin_addr, message_to_spammer));
+       }
+       return(0);
+}
index 229805363447c4c217af56329dacd1c0bd5623a2..3c271102e83c34fd05aa1acb4ccbae8851f41da1 100644 (file)
@@ -1,2 +1,3 @@
 /* $Id$ */
 void locate_host(char *tbuf, size_t n, const struct in_addr *addr);
+int rbl_check(char *message_to_spammer);
index 10f852340f411e088b31ad8dedf4f9eef26981b1..fbfeb4e6a8ad7af6c8cd44f76b79daa01868c585 100644 (file)
@@ -775,7 +775,8 @@ void get_inet_rec_type(CtdlIPC *ipc, char *buf) {
        keyopt(" <3> smart-host     (Forward all outbound mail to this host)\n");
        keyopt(" <4> directory      (Consult the Global Address Book)\n");
        keyopt(" <5> SpamAssassin   (Address of SpamAssassin server)\n");
-       sel = intprompt("Which one", 1, 1, 5);
+       keyopt(" <6> RBL            (domain suffix of spam hunting RBL)\n");
+       sel = intprompt("Which one", 1, 1, 6);
        switch(sel) {
                case 1: strcpy(buf, "localhost");
                        return;
@@ -787,6 +788,8 @@ void get_inet_rec_type(CtdlIPC *ipc, char *buf) {
                        return;
                case 5: strcpy(buf, "spamassassin");
                        return;
+               case 6: strcpy(buf, "rbl");
+                       return;
        }
 }
 
index c0147df1155c2096ef9ce95f1cbb09323bfd1ca1..2cb0ed4aa7fbb3869b29ac950e41b1cce31c6546 100644 (file)
@@ -31,6 +31,9 @@
 #include <ctype.h>
 #include <string.h>
 #include <limits.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
 #include "citadel.h"
 #include "server.h"
 #include "sysdep_decls.h"
@@ -49,6 +52,7 @@
 #include "genstamp.h"
 #include "domain.h"
 #include "clientsocket.h"
+#include "locate_host.h"
 
 
 #ifndef HAVE_SNPRINTF
@@ -401,7 +405,8 @@ void smtp_mail(char *argbuf) {
  */
 void smtp_rcpt(char *argbuf) {
        char recp[SIZ];
-       struct recptypes *valid;
+       char message_to_spammer[SIZ];
+       struct recptypes *valid = NULL;
 
        if (strlen(SMTP->from) == 0) {
                cprintf("503 Need MAIL before RCPT\r\n");
@@ -422,6 +427,15 @@ void smtp_rcpt(char *argbuf) {
                return;
        }
 
+       /* RBL check */
+       if ( (!CC->logged_in) && (!CC->is_local_socket) ) {
+               if (rbl_check(message_to_spammer)) {
+                       cprintf("552 %s\r\n", message_to_spammer);
+                       /* no need to phree(valid), it's not allocated yet */
+                       return;
+               }
+       }
+
        valid = validate_recipients(recp);
        if (valid->num_error > 0) {
                cprintf("599 Error: %s\r\n", valid->errormsg);