/*
**    spasm - The spasm anti-spam milter
**    Copyright (C) 2002-2004 Sean Hanson <aradia@theasylum.org>
**
**    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
*/

#ifndef _FILTERS_H
#define _FILTERS_H

/* temp macros...they will be deleted */
#define __HOST_DNSBL         0
#define __IP_DNSBL           1
#define __NOT_ADHOC          0
#define __IS_BH_FILTER       1
#define __NOT_BH_FILTER      0

/* misc */
#define SPASM_PARAM_UINT     0

/* adhoc filter markers */
#define SPASM_HELO           1
#define SPASM_RDNS           2
#define SPASM_SPAMTRAP       3
#define SPASM_MAIL_HOST      4
#define SPASM_SPAMASSASSIN   5
#define SPASM_VIRUS_SCAN     6
#define SPASM_LOCALFILTER    7
#define SPASM_PERSONAL_BL    8     /* personal blacklist */
#define SPASM_WL_ONLY        9     /* whitelist only     */
#define SPASM_MAX_UNK_USERS 10

#ifdef SPASM_USER_INTERFACE
typedef struct spasm_filter_parameter_info_struct
{
    char *db_name;     /* db filter parameter name                   */
    int  param_type;   /* possible value(s):
                        * 
                        *  SPASM_PARAM_UINT -> unsigned int
                        */
    char *ui_name;     /* user interface name (human readable), length 
                        * of string should not exceed much more than 30
                        * characters (assuming 80-character screen).
                        */
    char *help;        /* Help text describing this parameter.  Text may 
                        * include newline characters to force line breaks.
                        * Tabs are _not_ supported.
                        */
} SPASM_FILTER_PARAMETER;

typedef struct spasm_filter_option_info_struct
{
    char *db_name;     /* db filter option name                      */
    char *ui_name;     /* user interface name (human readable), length 
                        * of string should not exceed much more than 30
                        * characters (assuming 80-character screen).
                        */
    char *help;        /* Help text describing this option.  Text may 
                        * include newline characters to force line breaks.
                        * Tabs are _not_ supported.
                        */
} SPASM_FILTER_OPTION;
#endif

typedef struct spasm_filter_info_struct
{
    char *db_name;     /* db filter name                             */
#ifdef SPASM_USER_INTERFACE
    char *ui_name;     /* user interface name (human readable), length 
                        * of string should not exceed much more than 30
                        * characters (assuming 80-character screen).
                        */
    int  is_blackholes_filter;
                       /* boolean, T -> is a blackholes filter and implies
                        * that the following string will be prepended to
                        * the ui help field:
                        *
                        *   "This list is meant to contain all known
                        *   networks assigned to "
                        *
                        * In addition, the following suffix will be
                        * appended to the ui help field:
                        *
                        *   "\n\nNote that a \"blackhole.us\" filter does
                        *   not imply that the affected ISP/country is a
                        *   source of spam or prone to abuse. This filter
                        *   simply encompasses the network address space of
                        *   target entity."
                        */
    char *help;        /* Help text describing this filter.  Text may 
                        * include newline characters to force line breaks.
                        * Tabs are _not_ supported.
                        */
#endif
#ifdef SPASM_DAEMON
    /*
     * --NB-- some filters don't use all of these fields....
     */
    int  adhoc_id;     /* adhoc identifier.  If nonzero, this field
                        * signifies that the filter cannot be processed
                        * 100% via table lookup.  adhoc_id's must be
                        * unique (i.e., are used in a switch statement).
                        */
    char *smtp_rc;     /* smtp return code (if filter is triggered) */
    char *smtp_xrc;    /* smtp xtended return code (if filter is
                        * triggered)
                        */
    char *dnsbl;       /* how to access dns block list              */
    int  uses_ip_addr; /* boolean, T -> dnsbl requires raw IP lookup,
                        *          F -> host-based lookup (e.g.,
                        *          rfc ignorant blocklists)
                        */
    char *smtp_rmsg;   /* smtp rejection message.  If smtp_rmsg includes
                        * the token "%s", it will be replaced by the
                        * value of this structure's dnsbl field.  Up to
                        * 3 replacement instances (of %s) are supported.
                        */
#endif
} SPASM_FILTER;


#ifdef SPASM_USER_INTERFACE
const SPASM_FILTER_PARAMETER spasm_filter_params[] =
{
    {
        "SA_REQUIRED_HITS", SPASM_PARAM_UINT,
        "SpamAssassin Required Hits",
        "SpamAssassin works by assigning a \"spam score\" to each email "
        "message that it scans. The higher the score, the more likely "
        "the email is spam. Messages scored 5 and up are very likely "
        "spam. Messages scored 2 and under are probably legitimate. "
        "Between 2 and 5, expect to find a mixture of spam and real "
        "mail.\n\n"
        "The Required Hits parameter lets the end user change "
        "SpamAssassin's "
        "scoring threshold (i.e., the "
        "score at which a message is flagged as spam).\n\n"
        "A good, moderate (nonagressive) value is 5.\n\n"
        "Note 1: Setting this parameter to 0 (zero), causes spasm to "
        "ignore SpamAssassin filtering, even when SpamAssassin is "
        "enabled.\n\n"
        "Note 2: Consult www.spamassassin.org for further information."
    },
    /* ---------- */
    { NULL }  /* end of list marker */
};

const SPASM_FILTER_OPTION spasm_filter_opts[] =
{
    {
        "USE_DOMAIN_LOGGING",
        "Domain Logging",
        "If the Domain Logging option is enabled, spasm extracts "
        "the domain name from an email message's recipient address "
        "and uses that name as the basis for recording quarantine "
        "and rejection log information.\n\n"
        "This feature is useful for virtual domain administrators who "
        "wish to centralize their logs."
    },
    /* ---------- */
    {
        "USE_LOGGING",
        "Logging",
        "This spasm option configures which email messages are logged. "
        "Assuming that logging is enabled, the possible option values "
        "are:\n\n"
        "T[ag] -> enables logging for all messages flagged by "
        "filters at level \"Tag\" and higher. That is to say, _all_ "
        "messages flagged by spasm's filters are logged.\n\n"
        "Q[uarantine] -> enables logging for all messages flagged at "
        "level \"Quarantine\" and higher.\n\n"
        "R[eject] -> enables logging for _only_ those messages "
        "flagged at the \"Reject\" level."
    },
    /* ---------- */
    {
        "USE_SUBJECT_TAGGING",
        "Subject Tagging",
        "When enabled, the Subject Tagging option "
        "causes spasm to prepend the string \"**** X-spasm ****\" "
        "to the Subject: header of a Quarantined or "
        "Tagged email message.\n\n"
        "Subject Tagging is useful for email clients (notably Outlook "
        "Express) which do not support "
        "spam filtering via the custom headers that spasm is capable of "
        "generating when an anti-spam filter is triggered."
    },
    /* ---------- */
    { NULL }  /* end of list marker */
};
#endif

const SPASM_FILTER spasm_filters[] =
{
    {
        "SF_VIRUS_SCAN",
     #ifdef SPASM_USER_INTERFACE
        "Virus Scan", __NOT_BH_FILTER,
        "This filter runs an email message through a virus scanner, "
        "assuming such facility exists and has been enabled by the "
        "system administrator.\n\n"
        "Note:  Unlike almost all other supported spasm filters, "
        "the virus scanner necessarily performs its analysis _after_ "
        "an entire email message has been received by the local mail "
        "server. I.E., unlike other filters, the scanner cannot make a "
        "go/no-go decision during the initial connection phase "
        "between sending and receiving mail servers."
     #else
        SPASM_VIRUS_SCAN, "550", "5.7.1", "", __IP_DNSBL, "N/A"
     #endif
    },
    /* ---------- */
    {
        "SF_WHITELIST_ONLY",
     #ifdef SPASM_USER_INTERFACE
        "Whitelist Only", __NOT_BH_FILTER,
        "Before describing this filter, it's necessary to explain "
        "the mechanics of whitelisting.\n\n"
        "Each user has the option, via spasm's Whitelist menu, "
        "of creating a list of email addresses, "
        "domains, or network addresses that are "
        "_unconditionally_ accepted as valid message senders. "
        "Spasm always consults this list _before_ testing any other "
        "spam filter.  If the sending entity is found in the user's "
        "whitelist, the message is delivered.\n\n"
        "With that explanation out of the way, it's important to "
        "note that the Whitelist Only filter operates independently "
        "of spasm's core whitelisting capability and that "
        "it's filtering mechanism is dead simple. To wit:\n\n"
        "The Whitelist Only filter is triggered for all "
        "message senders _not_ found in the affected user's whitelist.\n\n"
        "For example, if the Whitelist Only filter is configured to Reject "
        "messages, then only mail from authorized senders will _ever_ "
        "land in your inbox."
     #else
        SPASM_WL_ONLY, "550", "5.7.1", "", __IP_DNSBL, "Rejected by spasm"
     #endif
    },
    /* ---------- */
    {
        "SF_PERSONAL_BLACKLIST",
     #ifdef SPASM_USER_INTERFACE
        "Personal Blacklist", __NOT_BH_FILTER,
        "Enabling this filter turns on your personal blacklist, which "
        "is created via spasm's \"Blacklist\" menu.\n\n"
        "Remember:  your filter, your rules :-) "
     #else
        SPASM_PERSONAL_BL, "550", "5.7.1", "", __IP_DNSBL,
        "Rejected by local filters"
     #endif
    },
    /* ---------- */
    {
        "SF_SPAMTRAP",
     #ifdef SPASM_USER_INTERFACE
        "Spamtrap", __NOT_BH_FILTER,
        "A cunning system administrator will seed the Internet with "
        "\"spamtrap\" email address(es) that are:\n\n"
        "a) not advertised openly, and\n"
        "b) not configured to receive email.\n\n"
        "Thus, any host that sends email to such an address is "
        "considered to be a spam source and is added to a spasm spamtrap "
        "database for future reference.\n\n"
        "This filter, then, is triggered when the sending mail server "
        "is found in the spamtrap database."
     #else
        SPASM_SPAMTRAP, "550", "5.7.1", "", __IP_DNSBL, "Rejected by spasm"
     #endif
    },
    /* ---------- */
    {
        "SF_MAX_UNKNOWN_USERS",
     #ifdef SPASM_USER_INTERFACE
        "Max Unknown Users", __NOT_BH_FILTER,
        "\"Dictionary attack\" might be a more descriptive name for this "
        "filter.  Webopedia.com defines an email "
        "dictionary attack as follows:\n\n"
        "An email spamming technique in which the spammer sends out "
        "thousands of emails with randomly generated addresses "
        "added to known domain names in the "
        "hopes of reaching a percentage of actual email addresses. For "
        "example, a dictionary attack list might begin with "
        "john@webopedia.com, john1@webopedia.com, john2@webopedia.com, "
        "and so on until all possible combinations of letters and numbers "
        "has been exhausted.\n\n"
        "The Max Unknown Users filter is triggered when spasm receives "
        "email from a sending entity that has, in the past, sent messages "
        "to a large number of unknown users."
     #else
        SPASM_MAX_UNK_USERS, "550", "5.7.1", "", __IP_DNSBL, "Rejected by spasm"
     #endif
    },
    /* ---------- */
    {
        "SF_LOCALFILTER",
     #ifdef SPASM_USER_INTERFACE
        "Local Filter", __NOT_BH_FILTER,
        "This is a blacklist created and maintained by the system "
        "administrator.  Consequently, this list strictly reflects "
        "the opinions of said administrator.\n\n"
        "For example, if the administrator detects the receipt of copious "
        "spam from an ISP in, say, Hungary, that ISP's entire network "
        "address space could wind up in Local Filter."
     #else
        SPASM_LOCALFILTER, "550", "5.7.1", "", __IP_DNSBL,
        "Rejected by local filters"
     #endif
    },
    /* ---------- */
    {
        "SF_RDNS",
     #ifdef SPASM_USER_INTERFACE
        "Reverse DNS (rDNS)", __NOT_BH_FILTER,
        "This filter tests the IP address of the server "
        "sending a message to ascertain if that address resolves to a "
        "hostname (i.e., is configured with a proper DNS entry).  If "
        "not, this filter is triggered. "
        "A large percentage of spammers "
        "send mail from IP addresses that have no "
        "DNS entry, but likewise, there are many legitimate mail servers "
        "whose systems administrators have not set up proper DNS.\n\n"
        "Consequently, this is a very aggressive filter, and will often "
        "flag legitimate email--use with caution."
     #else
        SPASM_RDNS, "550", "5.7.1", "", __IP_DNSBL, "Rejected: No Reverse DNS"
     #endif
    },
    /* ---------- */
    {
        "SF_HELO",
     #ifdef SPASM_USER_INTERFACE
        "HELO", __NOT_BH_FILTER,
        "When one mail server connects to another, it should "
        "(but is not always required to) send what is called an "
        "\"HELO/EHLO\" command. This command allows the first mail server "
        "to identify itself to the second mail server by sending "
        "its hostname. The HELO filter verifies the transmitted hostname "
        "against the server's actual hostname (which is available "
        "via IP adddress lookup). "
        "If the two hostnames do not match at the "
        "the top- and second-level domain names, this filter is "
        "triggered. As an example: given the hostname "
        "\"mail.domain.com\", the HELO filter only tests the existence "
        "of \"domain.com\".\n\n"
        "Additionally, this filter also triggers when no HELO/EHLO "
        "command is given.\n\n"
        "This filter stops a considerable amount of forged spam, "
        "but is moderately aggressive and may catch legitimate email."
     #else
        SPASM_HELO, "550", "5.7.1", "", __IP_DNSBL, ""
     #endif
    },
    /* ---------- */
    {
        "SF_MAIL_HOST",
     #ifdef SPASM_USER_INTERFACE
        "Mail Host", __NOT_BH_FILTER,
        "The Mail Host filter checks the second-level domain of the "
        "sender's email address against the second-level domain "
        "of the sending server's hostname. If they do not match, "
        "the filter is triggered. This comparison stops messages that "
        "are relayed through multiple hosts, a technique often used "
        "by spammers to take advantage of an insecure "
        "mail server (aka \"open relay\"). However, this implies "
        "that the Mail Host filter also stops legitimately relayed "
        "messages (e.g., virtual domain email, smarthosted email).\n\n"
        "Consequently, this is a very aggressive filter and will often "
        "flag legitimate email."
     #else
        SPASM_MAIL_HOST, "550", "5.7.1", "", __IP_DNSBL,
        "Rejected: Sender's domain does not match server's domain"
     #endif
    },
    /* ---------- */
    {
        "SF_SPAMASSASSIN",
     #ifdef SPASM_USER_INTERFACE
        "SpamAssassin", __NOT_BH_FILTER,
        "SpamAssassin (hereafter SA) identifies spam via a wide "
        "range of heuristic tests "
        "performed against an email's headers and message body. "
        "For a complete list of heuristics, refer to the SA "
        "home page at www.spamassassin.org.\n\n"
        "Note 1:  Unlike almost all other supported spasm filters, "
        "SA necessarily performs its analysis _after_ an entire "
        "email message has been received by the local mail "
        "server. I.E., unlike other filters, SA cannot make a "
        "go/no-go decision during the initial connection phase "
        "between sending and receiving mail servers.\n\n"
        "Note 2:  If SA is enabled, be sure to set the "
        "\"SpamAssassin Required Hits\" parameter (accessible from this "
        "menu) to a value > 0 (zero).  If required hits is not elevated "
        "above 0, spasm does not run the SA filter."
     #else
        SPASM_SPAMASSASSIN, "550", "5.7.1", "", __IP_DNSBL, "N/A"
     #endif
    },
    /* ---------- */
    {
        "SF_ORDB",
     #ifdef SPASM_USER_INTERFACE
        "Open Relay DataBase (ORDB)", __NOT_BH_FILTER,
        "ORDB stores a list of IP-addresses of verified open SMTP relays. "
        "These relays are, or are likely to be, used as conduits for sending "
        "spam."
     #else
        __NOT_ADHOC, "550", "5.7.1", "relays.ordb.org", __IP_DNSBL,
        "Rejected by ORDB: see http://www.ordb.org"
     #endif
    },
    /* ---------- */
    { 
        "SF_DSBL",
     #ifdef SPASM_USER_INTERFACE
        "DSBL", __NOT_BH_FILTER,
        "The Distributed Server Boycott List (DSBL) contains the IP "
        "addresses of servers which have relayed "
        "special test messages to listme@listme.dsbl.org; this can "
        "happen if the server is an open relay, an open proxy or has "
        "another vulnerability that allows anybody to deliver email to "
        "anywhere, through that server.\n\n"
        "The DSBL is comprised of 3 lists, but spasm only tests "
        "against list.dsbl.org, which is a collection of "
        "single-stage relays tested by trusted users."
     #else
        __NOT_ADHOC, "550", "5.7.1", "list.dsbl.org", __IP_DNSBL,
        "Rejected by %s"
     #endif
    },
    /* ---------- */
    { 
        "SF_SPAMCOP",
     #ifdef SPASM_USER_INTERFACE
        "SpamCop", __NOT_BH_FILTER,
        "Instead of trying to test, categorize, and block the plethora of "
        "different systems at risk for sending unsolicited bulk email "
        "(UBE), SpamCop blocks whichever systems _actually_ send UBE. "
        "As a result, sites which have no technical problems but send a "
        "lot of UBE will be listed.\n\n"
        "SpamCop is fairly agressive. That is, it flags lots of spam, but "
        "is also known for accidentally flagging legitimate mail, "
        "particularly mailing-lists.\n\n"
        "See www.spamcop.net/bl.shtml for more details."
     #else
        __NOT_ADHOC, "550", "5.7.1", "bl.spamcop.net", __IP_DNSBL,
        "Rejected by SpamCop: see http://spamcop.net/bl.shtml"
     #endif
    },
    /* ---------- */
    { 
        "SF_SBL",
     #ifdef SPASM_USER_INTERFACE
        "Spamhaus Block List (SBL)", __NOT_BH_FILTER,
        "The Spamhaus Block List (SBL) is a realtime database of IP "
        "addresses of verified spam sources (including spammers, spam "
        "gangs and spam support services).\n\n"
        "See www.spamhaus.org/sbl/index.lasso for more info."
     #else
        __NOT_ADHOC, "550", "5.7.1", "sbl.spamhaus.org", __IP_DNSBL,
        "Rejected by %s"
     #endif
    },
    /* ---------- */
    { 
        "SF_SORBS",
     #ifdef SPASM_USER_INTERFACE
        "SORBS", __NOT_BH_FILTER,
        "SORBS is an acronym for Spam and Open Relay Blocking System. This "
        "is not strictly accurate as a description though, as it stops open "
        "proxy servers and machines that appear to be hacked sources of spam, "
        "as well as open relays.\n\n"
        "SORBS scans a host for vulnerabilities when it attempts to "
        "send mail to one of the SORBS 'feeder' servers.\n\n"
        "See www.dnsbl.us.sorbs.net/FAQ.html for more info."
     #else
        __NOT_ADHOC, "550", "5.7.1", "dnsbl.sorbs.net", __IP_DNSBL,
        "Rejected by %s"
     #endif
    },
    /* ---------- */
    { 
        "SF_POSTMASTERRFC",
    #ifdef SPASM_USER_INTERFACE
        "postmaster.rfc-ignorant.org", __NOT_BH_FILTER,
        "RFC2821 specifies that any system that includes an SMTP server "
        "supporting mail relaying or delivery _must_ support the reserved "
        "address postmaster@<domain>.\n\n"
        "Domains are listed in postmaster.rfc-ignorant.org on the basis "
        "of _not_ supporting a postmaster role account. "
        "NB: this filter currently includes aol.com.\n\n"
        "See rfc-ignorant.org/policy-postmaster.php for more info."
    #else
        __NOT_ADHOC, "550", "5.7.1", "postmaster.rfc-ignorant.org", __HOST_DNSBL,
        "Rejected by %s: see http://www.rfc-ignorant.org"
    #endif
    },
    /* ---------- */
    { 
        "SF_DSNRFC",
    #ifdef SPASM_USER_INTERFACE
        "dsn.rfc-ignorant.org", __NOT_BH_FILTER,
        "RFC1123 specifies that it must be possible to send a message "
        "with a null return path (<>), which is used to prevent looping of "
        "error notifications.\n\n"
        "Domains are listed in dsn.rfc-ignorant.org on the basis "
        "of _not_ supporting the null return path.\n\n"
        "See rfc-ignorant.org/policy-dsn.php for more info."
    #else
        __NOT_ADHOC, "550", "5.7.1", "dsn.rfc-ignorant.org", __HOST_DNSBL,
        "Rejected by %s: see http://www.rfc-ignorant.org"
    #endif
    },
    /* ---------- */
    { 
        "SF_ABUSERFC",
    #ifdef SPASM_USER_INTERFACE
        "abuse.rfc-ignorant.org", __NOT_BH_FILTER,
        "RFC2142 codifies the longstanding practice that abuse@<domain> "
        "must work for any organization for which "
        "email (or other abusable Internet) service(s) exist.\n\n"
        "Domains are listed in abuse.rfc-ignorant.org on the basis "
        "of _not_ supporting an abuse role account. "
        "NB: this filter currently includes aol.com.\n\n"
        "See rfc-ignorant.org/policy-abuse.php for more info."
    #else
        __NOT_ADHOC, "550", "5.7.1", "abuse.rfc-ignorant.org", __HOST_DNSBL,
        "Rejected by %s: see http://www.rfc-ignorant.org"
    #endif
    },
    /* ---------- */
    { 
        "SF_WHOISRFC",
    #ifdef SPASM_USER_INTERFACE
        "whois.rfc-ignorant.org", __NOT_BH_FILTER,
        "RFC954 specifies that all hosts that can connect to the "
        "Internet and are capable of passing traffic should be listed "
        "in a whois server complete with contact information, including "
        "network email addresses.\n\n"
        "Domains or TLDs (top level domains) are listed in "
        "whois.rfc-ignorant.org on the basis of "
        "either _not_ providing contact information or providing "
        "demonstrably inaccurate data.\n\n"
        "Note that this filter tests "
        "against domain-based RFC violators (e.g., example.com) rather "
        "than IP-based violators (e.g., 10.198.7.7). "
        "NB: this filter currently includes the .ch (Switzerland) and .uk "
        "(Great Britain) TLDs.\n\n"
        "See rfc-ignorant.org/policy-whois.php for more info."
    #else
        __NOT_ADHOC, "550", "5.7.1", "whois.rfc-ignorant.org", __HOST_DNSBL,
        "Rejected by %s: see http://www.rfc-ignorant.org"
    #endif
    },
    /* ---------- */
    { 
        "SF_IPWHOISRFC",
    #ifdef SPASM_USER_INTERFACE
        "ipwhois.rfc-ignorant.org", __NOT_BH_FILTER,
        "RFC954 specifies that all hosts that can connect to the "
        "Internet and are capable of passing traffic should be listed "
        "in a whois server complete with contact information, including "
        "network email addresses.\n\n"
        "Networks are listed in ipwhois.rfc-ignorant.org on the basis "
        "of either _not_ providing contact information or providing "
        "demonstrably inaccurate data.\n\n"
        "Note that this filter tests "
        "against IP-based RFC violators (e.g., 10.198.7.7) rather "
        "than domain-based violators (e.g., example.com).\n\n"
        "See rfc-ignorant.org/policy-ipwhois.php for more info."
    #else
        __NOT_ADHOC, "550", "5.7.1", "ipwhois.rfc-ignorant.org", __IP_DNSBL,
        "Rejected by %s: see http://www.rfc-ignorant.org"
    #endif
    },
    /* ---------- */
    { 
        "SF_KOREABLACKHOLES",
    #ifdef SPASM_USER_INTERFACE
        "korea.blackholes.us", __IS_BH_FILTER, "Korea"
    #else
        __NOT_ADHOC, "550", "5.7.1", "korea.blackholes.us", __IP_DNSBL,
        "Rejected by %s"
    #endif
    },
    /* ---------- */
    { 
        "SF_CHINABLACKHOLES",
    #ifdef SPASM_USER_INTERFACE
        "china.blackholes.us", __IS_BH_FILTER, "China"
    #else
        __NOT_ADHOC, "550", "5.7.1", "china.blackholes.us", __IP_DNSBL,
        "Rejected by %s"
    #endif
    },
    /* ---------- */
    { 
        "SF_BRAZILBLACKHOLES",
    #ifdef SPASM_USER_INTERFACE
        "brazil.blackholes.us", __IS_BH_FILTER, "Brazil"
    #else
        __NOT_ADHOC, "550", "5.7.1", "brazil.blackholes.us", __IP_DNSBL,
        "Rejected by %s"
    #endif
    },
    /* ---------- */
    { 
        "SF_JAPANBLACKHOLES",
    #ifdef SPASM_USER_INTERFACE
        "japan.blackholes.us", __IS_BH_FILTER, "Japan"
    #else
        __NOT_ADHOC, "550", "5.7.1", "japan.blackholes.us", __IP_DNSBL,
        "Rejected by %s"
    #endif
    },
    /* ---------- */
    { 
        "SF_TAIWANBLACKHOLES",
    #ifdef SPASM_USER_INTERFACE
        "taiwan.blackholes.us", __IS_BH_FILTER, "Taiwan"
    #else
        __NOT_ADHOC, "550", "5.7.1", "taiwan.blackholes.us", __IP_DNSBL,
        "Rejected by %s"
    #endif
    },
    /* ---------- */
    {
        "SF_VERIOBLACKHOLES",
    #ifdef SPASM_USER_INTERFACE
        "verio.blackholes.us", __IS_BH_FILTER, "the Verio ISP (www.verio.com)"
    #else
        __NOT_ADHOC, "550", "5.7.1", "verio.blackholes.us", __IP_DNSBL,
        "Rejected by %s"
    #endif
    },
    /* ---------- */
    {
        "SF_VALUEWEBBLACKHOLES",
    #ifdef SPASM_USER_INTERFACE
        "valueweb.blackholes.us", __IS_BH_FILTER,
        "the ValueWeb ISP (www.valueweb.com)"
    #else
        __NOT_ADHOC, "550", "5.7.1", "valueweb.blackholes.us", __IP_DNSBL,
        "Rejected by %s"
    #endif
    },
    /* ---------- */
    {
        "SF_RACKSPACEBLACKHOLES",
    #ifdef SPASM_USER_INTERFACE
        "rackspace.blackholes.us", __IS_BH_FILTER,
        "the Rackspace ISP (www.rackspace.com)"
    #else
        __NOT_ADHOC, "550", "5.7.1", "rackspace.blackholes.us", __IP_DNSBL,
        "Rejected by %s"
    #endif
    },
    /* ---------- */
    {
        "SF_INFLOWBLACKHOLES",
    #ifdef SPASM_USER_INTERFACE
        "inflow.blackholes.us", __IS_BH_FILTER,
        "the Inflow ISP (www.inflow.com)"
    #else
        __NOT_ADHOC, "550", "5.7.1", "inflow.blackholes.us", __IP_DNSBL,
        "Rejected by %s"
    #endif
    },
    /* ---------- */
    {
        "SF_BROADWINGBLACKHOLES",
    #ifdef SPASM_USER_INTERFACE
        "broadwing.blackholes.us", __IS_BH_FILTER,
        "the Broadwing ISP (www.broadwing.com)"
    #else
        __NOT_ADHOC, "550", "5.7.1", "broadwing.blackholes.us", __IP_DNSBL,
        "Rejected by %s"
    #endif
    },
    /* ---------- */
    {
        "SF_XOBLACKHOLES",
    #ifdef SPASM_USER_INTERFACE
        "xo.blackholes.us", __IS_BH_FILTER,
        "the XO Communications ISP (www.xo.com)"
    #else
        __NOT_ADHOC, "550", "5.7.1", "xo.blackholes.us", __IP_DNSBL,
        "Rejected by %s"
    #endif
    },
    /* ---------- */
    {
        "SF_ELIBLACKHOLES",
    #ifdef SPASM_USER_INTERFACE
        "eli.blackholes.us", __IS_BH_FILTER,
        "the Electric Lightwave ISP (www.eli.net)"
    #else
        __NOT_ADHOC, "550", "5.7.1", "eli.blackholes.us", __IP_DNSBL,
        "Rejected by %s"
    #endif
    },
    /* ---------- */
    {
        "SF_ARGENTINABLACKHOLES",
    #ifdef SPASM_USER_INTERFACE
        "argentina.blackholes.us", __IS_BH_FILTER, "Argentina"
    #else
        __NOT_ADHOC, "550", "5.7.1", "argentina.blackholes.us", __IP_DNSBL,
        "Rejected by %s"
    #endif
    },
    /* ---------- */
    {
        "SF_NIGERIABLACKHOLES",
    #ifdef SPASM_USER_INTERFACE
        "nigeria.blackholes.us", __IS_BH_FILTER, "Nigeria"
    #else
        __NOT_ADHOC, "550", "5.7.1", "nigeria.blackholes.us", __IP_DNSBL,
        "Rejected by %s"
    #endif
    },
    /* ---------- */
    {
        "SF_RUSSIABLACKHOLES",
    #ifdef SPASM_USER_INTERFACE
        "russia.blackholes.us", __IS_BH_FILTER, "Russia"
    #else
        __NOT_ADHOC, "550", "5.7.1", "russia.blackholes.us", __IP_DNSBL,
        "Rejected by %s"
    #endif
    },
    /* ---------- */
    {
        "SF_SINGAPOREBLACKHOLES",
    #ifdef SPASM_USER_INTERFACE
        "singapore.blackholes.us", __IS_BH_FILTER, "Singapore"
    #else
        __NOT_ADHOC, "550", "5.7.1", "singapore.blackholes.us", __IP_DNSBL,
        "Rejected by %s"
    #endif
    },
    /* ---------- */
    {
        "SF_THAILANDBLACKHOLES",
    #ifdef SPASM_USER_INTERFACE
        "thailand.blackholes.us", __IS_BH_FILTER, "Thailand"
    #else
        __NOT_ADHOC, "550", "5.7.1", "thailand.blackholes.us", __IP_DNSBL,
        "Rejected by %s"
    #endif
    },
    /* ---------- */
    {
        "SF_CIBERLYNXBLACKHOLES",
    #ifdef SPASM_USER_INTERFACE
        "ciberlynx.blackholes.us", __IS_BH_FILTER,
        "the Ciberlynx ISP (www.ciberlynx.com)"
    #else
        __NOT_ADHOC, "550", "5.7.1", "ciberlynx.blackholes.us", __IP_DNSBL,
        "Rejected by %s"
    #endif
    },
    /* ---------- */
    {
        "SF_CWBLACKHOLES",
    #ifdef SPASM_USER_INTERFACE
        "cw.blackholes.us", __IS_BH_FILTER,
        "the Cable & Wirelss ISP (www.cw.com)"
    #else
        __NOT_ADHOC, "550", "5.7.1", "cw.blackholes.us", __IP_DNSBL,
        "Rejected by %s"
    #endif
    },
    /* ---------- */
    {
        "SF_EPOCHBLACKHOLES",
    #ifdef SPASM_USER_INTERFACE
        "epoch.blackholes.us", __IS_BH_FILTER, "the Epoch ISP (www.epoch.net)"
    #else
        __NOT_ADHOC, "550", "5.7.1", "epoch.blackholes.us", __IP_DNSBL,
        "Rejected by %s"
    #endif
    },
    /* ---------- */
    {
        "SF_HEBLACKHOLES",
    #ifdef SPASM_USER_INTERFACE
        "he.blackholes.us", __IS_BH_FILTER,
        "the Hurricane Electric ISP (www.he.com)"
    #else
        __NOT_ADHOC, "550", "5.7.1", "he.blackholes.us", __IP_DNSBL,
        "Rejected by %s"
    #endif
    },
    /* ---------- */
    {
        "SF_INTERNAPBLACKHOLES",
    #ifdef SPASM_USER_INTERFACE
        "internap.blackholes.us", __IS_BH_FILTER,
        "the Internap ISP (www.internap.com)"
    #else
        __NOT_ADHOC, "550", "5.7.1", "internap.blackholes.us", __IP_DNSBL,
        "Rejected by %s"
    #endif
    },
    /* ---------- */
    {
        "SF_LEVEL3BLACKHOLES",
    #ifdef SPASM_USER_INTERFACE
        "level3.blackholes.us", __IS_BH_FILTER,
        "the Level3 ISP (www.level3.com)"
    #else
        __NOT_ADHOC, "550", "5.7.1", "level3.blackholes.us", __IP_DNSBL,
        "Rejected by %s"
    #endif
    },
    /* ---------- */
    {
        "SF_RRBLACKHOLES",
    #ifdef SPASM_USER_INTERFACE
        "rr.blackholes.us", __IS_BH_FILTER, "the RoadRunner ISP (www.rr.com)"
    #else
        __NOT_ADHOC, "550", "5.7.1", "rr.blackholes.us", __IP_DNSBL,
        "Rejected by %s"
    #endif
    },
    /* ---------- */
    {
        "SF_SKYNETWEBBLACKHOLES",
    #ifdef SPASM_USER_INTERFACE
        "skynetweb.blackholes.us", __IS_BH_FILTER,
        "the SkyNetWEB ISP (www.skynetweb.com)"
    #else
        __NOT_ADHOC, "550", "5.7.1", "skynetweb.blackholes.us", __IP_DNSBL,
        "Rejected by %s"
    #endif
    },
    /* ---------- */
    {
        "SF_WANADOOFRBLACKHOLES",
    #ifdef SPASM_USER_INTERFACE
        "wanadoo-fr.blackholes.us", __IS_BH_FILTER,
        "the French ISP 'wanadoo' (www.wanadoo.fr)"
    #else
        __NOT_ADHOC, "550", "5.7.1", "wanadoo-fr.blackholes.us", __IP_DNSBL,
        "Rejected by %s"
    #endif
    },
    /* ---------- */
    { NULL }  /* end of list marker */
};


#undef __NOT_ADHOC
#undef __IP_DNSBL
#undef __HOST_DNSBL
#undef __IS_BH_FILTER
#undef __NOT_BH_FILTER

#endif /* _FILTERS_H */
