$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"
Fri Jul 10 1998 Art Cancro <ajc@uncensored.citadel.org>
* Initial CVS import
+
<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
<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><A>dd <D>elete <S>ave <Q>uit -> <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>
+<A>dd <D>elete <S>ave <Q>uit -> <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>
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>
n = get_hosts(mxbuf, "smarthost");
if (n > 0) return(n);
-
/*
* No smart-host? Look up the best MX for a site.
*/
/*
* 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 */
*
*/
-#ifdef DLL_EXPORT
-#define IN_LIBCIT
-#endif
-
#include "sysdep.h"
#include <stdlib.h>
#include <unistd.h>
#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)
{
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);
+}
/* $Id$ */
void locate_host(char *tbuf, size_t n, const struct in_addr *addr);
+int rbl_check(char *message_to_spammer);
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;
return;
case 5: strcpy(buf, "spamassassin");
return;
+ case 6: strcpy(buf, "rbl");
+ return;
}
}
#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"
#include "genstamp.h"
#include "domain.h"
#include "clientsocket.h"
+#include "locate_host.h"
#ifndef HAVE_SNPRINTF
*/
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");
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);