/* * Copyright (C) 2003-2004 Perolo Silantico * Copyright (C) 2006 Roberto Alsina * Copyright (C) 2007 Sebastian Werner * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later * version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software Foundation, * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * */ #include #include #include #include #include "bstrlib.h" #include #include int check_rbl (bstring lookup_addr, const char *rbl) { struct addrinfo *ai = NULL; bstring lookupname = bformat ("%s.%s", lookup_addr->data, rbl); if (getaddrinfo (lookupname->data, NULL, NULL, &ai)) { if (ai) freeaddrinfo (ai); return 0; } freeaddrinfo (ai); return 1; } int check_rwl (bstring lookup_addr, const char *rbl) { bstring lookupname = bformat ("%s.%s", lookup_addr->data, rbl); if (gethostbyname (lookupname->data)) { return 1; } return 0; } bstring envtostr (char *vname) { bstring retval; retval = bfromcstr (getenv (vname)); if (!retval) retval = bfromcstr (""); return retval; } int main (int argc, char *argv[]) { bstring ip = bfromcstr (getenv ("TCPREMOTEIP")); unsigned long address; int i; int ppid = getppid (); if (!ip) //Somehow we are running in a bad situation { printf ("D\n"); fprintf (stderr, "rblchecks: pid %d - no TCPREMOTEIP\n", ppid); exit (0); } /* User disabled plugin via tcp.smtp - so exit */ if (getenv ("SKIP_RBL")) { fprintf (stderr, "rblchecks: pid %d - rblchecks skipped.\n", ppid); exit (0); } // be IPv6 safe and just exit if PROTO = TCP6 if (strcmp(getenv ("PROTO"),"TCP6")) { fprintf (stderr, "rblchecks: pid %d - IPv6 not subject to RBL! Accepted %s\n", ppid, ip->data); exit (0); } // Lets convert address to the RBL lookup format - reverse it! address = inet_addr (ip->data); bstring addr = bformat ("%lu.%lu.%lu.%lu", (address & 0xff000000) >> 24, (address & 0x00ff0000) >> 16, (address & 0x0000ff00) >> 8, (address & 0x000000ff) >> 0); //Check, if host is in white list bstring rwl = bfromcstr (getenv ("RWLSERVERS")); if (rwl) { struct bstrList *wlist = bsplit (rwl, ':'); for (i = 0; i < wlist->qty; i++) { bstring serv = wlist->entry[i]; if (serv->slen == 0) continue; if (check_rwl (addr, serv->data)) { printf ("A\n"); fprintf (stderr, "rblchecks: pid %d - No checks performed, because %s whitelists %s\n", ppid, serv->data, ip->data); exit (0); } } } //Check for occurence in blacklist bstring rbl = bfromcstr (getenv ("RBLSERVERS")); if (!rbl) rbl = bfromcstr ("bl.spamcop.net"); struct bstrList *blist = bsplit (rbl, ':'); for (i = 0; i < blist->qty; i++) { bstring serv = blist->entry[i]; if (serv->slen == 0) continue; if (check_rbl (addr, serv->data)) { printf ("E541 Your IP (%s) is blocked, more information at http://%s\n", ip->data, serv->data); fprintf (stderr, "rblchecks: pid %d - 541 Blocked by %s (%s)\n", ppid, serv->data, ip->data); exit (0); } } // No RBL issues fprintf (stderr, "rblchecks: pid %d - Accepted %s\n", ppid, ip->data); exit (0); }