Просмотр исходного кода

Merge branch 'rbl-lookup'

* rbl-lookup: (24 commits)
  * Fix set 'realname' ordering
  * Don't check RBL until all m->userip[]'s are populated from the dns lookup, or else the KICKs wont occur
  * Remove flush overload from do_mask
  * Show RBL in kick/ban reason
  * Cleanup memory leaks in rbl/+r code
  * Optimize lookups more, apply the ban to the botnet/chan right away on matching result and kick all matching users based on cached m->userip
  * Fix memory leak in RBL checking: Free up r->servers after a successful lookup
  * Move debugging notice
  * Optimize RBL checking slightly
  * Only send the +b if opped, otherwise add it temporarily to the botnet
  * Fix RBL lookup ignoring clients with userips
  * Update doc/UPDATES about new rbl features
  * No need to do RBL lookups on self or users
  * Add +rbl to help::chaninfo
  * Support multiple servers for RBL lookups
  src/mod/irc.mod/chan.c
  * Add set 'rbl-servers' with defaults
  * Only need to lookup the A record when checking RBL lists
  * Remove unused 'ps'
  * Fix user matching in resolve/rbl callbacks
  ...
Bryan Drewery 16 лет назад
Родитель
Сommit
ecaad589df

+ 1 - 0
doc/UPDATES

@@ -43,6 +43,7 @@
 * Cleanup all string parsing to trim excess whitespaces (fixes #268)
 * No longer bundling Openssl code; It is now required to be installed to compile.
 * Cleanup cmd_botcmd restrictions.
+* Add 'chanset +rbl' which uses list of servers from 'set rbl-servers'. Only +r bots will enforce this.
 
 1.2.16 - http://wraith.botpack.net/milestone/1.2.16
 * Add 'set altchars' so that alternative characters used for nicks can be changed. (fixes #418)

+ 8 - 4
doc/help.txt

@@ -467,6 +467,8 @@ See also: link
                        Users who lose access to a channel because of this setting
                        will see no reference to it over the botnet in any place.
                        The +o restriction goes for +v as well.
+        $brbl$b             Do RBL lookups on clients and ban on matches.
+                       Uses 'rbl-servers'. See also '%dhelp set'
         $btake$b           Once a bot is opped, it will mass op all other bots
                        in the channel. After that, they will all attempt to 
                        mass deop in hopes 'taking' the channel. :)
@@ -1530,12 +1532,12 @@ See also: reload, backup
    $uB$u:    Boolean (0/1/true/on/false/off)
    $uS$u:    String
    $uN$u:    Number
-   $uL$u:    List capable
+   $uL$u:    List
    $uR$u:    Rate. Set as 'number:interval', ie, '1:5'
    $uD$u:    Detected vars have the folloing options: $bignore$b/0, $bwarn$b/1, $breject$b/2, 
                                                       $bdie$b/3, $bsuicide$b/4
  
-[SL] $balias$b           List of dcc aliases in format '<alias> <cmd> [parms]'. First
+[L] $balias$b            List of dcc aliases in format '<alias> <cmd> [parms]'. First
                           matching alias is used. Normal flag checking is done
                           after the alias is expanded. 
                           $bAliases may not reference other aliases.$b
@@ -1571,8 +1573,10 @@ See also: reload, backup
 [D]  $bpromisc$b         How to handle when an interface is set to promiscuous mode.
 [D]  $bhijack$b          How to handle when a commonly used hijack method attempt is detected. 
  
-[SL] $bservers$b         Comma-separated list of servers the bot will use.
-[SL] $bservers6$b        Comma-separated list of servers the bot will use (FOR IPv6).
+[L]  $bservers$b         Comma-separated list of servers the bot will use.
+[L]  $bservers6$b        Comma-separated list of servers the bot will use (FOR IPv6).
+
+[L]  $brbl-servers$b     Servers to use for RBL checking in channels that are +rbl.
  
 [S]  $brealname$b        The bot's "real name" when connecting. (supports '$n' expansion)
 [S]  $busermode$b        The bot's usermode on IRC. (Set on connect/rehash)

+ 10 - 0
doc/settings.txt

@@ -62,4 +62,14 @@ irc.ipv6.homelien.no
 irc.ipv6.inter.net.il
 irc.paraphysics.net
 
+:rbl
+cbl.abuseat.org
+dnsbl.ahbl.org
+dnsbl.proxybl.org
+rbl.efnetrbl.org
+tor.efnet.org
+dnsbl.swiftbl.net
+xbl.spamhaus.org
+rbl.efnetpro.com
+
 :end

+ 27 - 22
src/adns.c

@@ -166,7 +166,6 @@ const char *dns_ip = NULL;
 
 static int make_header(char *buf, int id);
 static int cut_host(const char *host, char *query);
-static int reverse_ip(const char *host, char *reverse);
 static int read_resolv(char *fname);
 static void read_hosts(char *fname);
 static int get_dns_idx();
@@ -394,33 +393,39 @@ dns_query_t *find_query(const char *host)
   return NULL;
 }
 
-void dns_send_query(dns_query_t *q)
+static void dns_send_query(dns_query_t *q, int type = (DNS_LOOKUP_A|DNS_LOOKUP_AAAA))
 {
   char buf[512] = "";
   int len;
 
-  if (!q->ip) {
-    /* Send the ipv4 query. */
-    q->remaining = 1;
-    len = make_header(buf, q->id);
-    len += cut_host(q->query, buf + len);
-    buf[len] = 0; len++; buf[len] = DNS_A; len++;
-    buf[len] = 0; len++; buf[len] = 1; len++;
+  q->remaining = 0;
 
-    egg_dns_send(buf, len);
+  if (!q->ip) {
+    if (type & DNS_LOOKUP_A) {
+      /* Send the ipv4 query. */
+      q->remaining++;
+      len = make_header(buf, q->id);
+      len += cut_host(q->query, buf + len);
+      buf[len] = 0; len++; buf[len] = DNS_A; len++;
+      buf[len] = 0; len++; buf[len] = 1; len++;
+
+      egg_dns_send(buf, len);
+    }
 
 #ifdef USE_IPV6
-    /* Now send the ipv6 query. */
-    q->remaining++;
-    len = make_header(buf, q->id);
-    len += cut_host(q->query, buf + len);
-    buf[len] = 0; len++; buf[len] = DNS_AAAA; len++;
-    buf[len] = 0; len++; buf[len] = 1; len++;
-
-    egg_dns_send(buf, len);
+    if (type & DNS_LOOKUP_AAAA) {
+      /* Now send the ipv6 query. */
+      q->remaining++;
+      len = make_header(buf, q->id);
+      len += cut_host(q->query, buf + len);
+      buf[len] = 0; len++; buf[len] = DNS_AAAA; len++;
+      buf[len] = 0; len++; buf[len] = 1; len++;
+
+      egg_dns_send(buf, len);
+    }
 #endif
   } else if (q->ip) {
-    q->remaining = 1;
+    q->remaining++;
     len = make_header(buf, q->id);
     len += cut_host(q->ip, buf + len);
     buf[len] = 0; len++; buf[len] = DNS_PTR; len++;
@@ -460,7 +465,7 @@ void dns_create_timeout_timer(dns_query_t **qm, const char *query, int timeout)
 /* Perform an async dns lookup. This is host -> ip. For ip -> host, use
  * egg_dns_reverse(). We return a dns id that you can use to cancel the
  * lookup. */
-int egg_dns_lookup(const char *host, interval_t timeout, dns_callback_t callback, void *client_data)
+int egg_dns_lookup(const char *host, interval_t timeout, dns_callback_t callback, void *client_data, int type)
 {
 	dns_query_t *q = NULL;
 	int i, cache_id;
@@ -509,7 +514,7 @@ int egg_dns_lookup(const char *host, interval_t timeout, dns_callback_t callback
         q = alloc_query(client_data, callback, host);
 
 	sdprintf("egg_dns_lookup(%s, %d) -> %d", host, timeout, q->id);
-        dns_send_query(q);
+        dns_send_query(q, type);
 
 //        /* setup a timer to detect dead ns */
 //	dns_create_timeout_timer(&q, host, timeout);
@@ -821,7 +826,7 @@ static int cut_host(const char *host, char *query)
 	return(query-orig);
 }
 
-static int reverse_ip(const char *host, char *reverse)
+int reverse_ip(const char *host, char *reverse)
 {
 	const char *period = NULL;
 	int offset, len;

+ 5 - 1
src/adns.h

@@ -30,6 +30,9 @@ TXT             16 text strings
 #define DNS_PTR		12
 #define DNS_AAAA	28
 
+#define DNS_LOOKUP_A    1
+#define DNS_LOOKUP_AAAA 2
+
 
 #define DNS_IPV4	1
 #define DNS_IPV6	2
@@ -43,12 +46,13 @@ int egg_dns_init(void);
 //int egg_dns_shutdown(void);
 
 void egg_dns_send(char *query, int len);
-int egg_dns_lookup(const char *host, interval_t timeout, dns_callback_t callback, void *client_data);
+int egg_dns_lookup(const char *host, interval_t timeout, dns_callback_t callback, void *client_data, int type = (DNS_LOOKUP_A|DNS_LOOKUP_AAAA));
 int egg_dns_reverse(const char *ip, interval_t timeout, dns_callback_t callback, void *client_data);
 int egg_dns_cancel(int id, int issue_callback);
 void tell_dnsdebug(int);
 void dns_cache_flush();
 bool valid_dns_id(int, int);
+int reverse_ip(const char *host, char *reverse);
 
 extern int		dns_sock, dns_idx;
 extern const char	*dns_ip;

+ 2 - 1
src/chan.h

@@ -231,7 +231,7 @@ struct chanset_t {
 #define CHAN_BOTBITCH       BIT7        /* only let bots be opped? */
 #define CHAN_BACKUP         BIT8	/* Join the BOT_BACKUP bots when set */
 #define CHAN_SECRET         BIT9	/* don't advertise channel on botnet  */
-#undef  CHAN_10		    /* BIT10        not used */
+#define CHAN_RBL            BIT10	/* Lookup users in RBL (requires +r) */
 #define CHAN_CYCLE          BIT11	/* cycle the channel if possible      */
 #define CHAN_INACTIVE       BIT12	/* no irc support for this channel */
 #define CHAN_VOICE          BIT13	/* a bot +y|y will voice *, except +q */
@@ -302,6 +302,7 @@ struct chanset_t *findchan_by_dname(const char *name);
 #define channel_nomassjoin(chan) (chan->status & CHAN_NOMASSJOIN)
 #define channel_knock(chan) (chan->status & CHAN_KNOCK)
 #define channel_meankicks(chan) (chan->status & CHAN_MEANKICKS)
+#define channel_rbl(chan) (chan->status & CHAN_RBL)
 /* Chanflag template
  *#define channel_temp(chan) (chan->status & CHAN_PRIVATE)
  */

+ 2 - 0
src/mod/channels.mod/channels.c

@@ -886,6 +886,8 @@ void channels_report(int idx, int details)
           i += my_strcpy(s + i, "knock ");
         if (channel_meankicks(chan))
           i += my_strcpy(s + i, "meankicks ");
+        if (channel_rbl(chan))
+          i += my_strcpy(s + i, "rbl ");
 /* Chanflag template
  *	if (channel_temp(chan))
  *	  i += my_strcpy(s + i, "temp ");

+ 1 - 1
src/mod/channels.mod/channels.h

@@ -43,7 +43,7 @@ void write_invites(bd::Stream&, int);
 bool expired_mask(struct chanset_t *, char *);
 void set_handle_laston(char *, struct userrec *, time_t);
 int u_delmask(char type, struct chanset_t *c, char *who, int doit);
-bool u_addmask(char type, struct chanset_t *, char *, char *, char *, time_t, int);
+bool u_addmask(char type, struct chanset_t *, char *, const char *, const char *, time_t, int);
 int u_sticky_mask(maskrec *, char *);
 int u_setsticky_mask(struct chanset_t *, maskrec *, char *, int, const char);
 int SplitList(char *, const char *, int *, const char ***);

+ 3 - 2
src/mod/channels.mod/cmdschan.c

@@ -1242,13 +1242,14 @@ static void cmd_chaninfo(int idx, char *par)
     SHOW_FLAG("enforcebans", 	channel_enforcebans(chan));
     SHOW_FLAG("fastop",		channel_fastop(chan));
     SHOW_FLAG("inactive",	channel_inactive(chan));
+    SHOW_FLAG("knock",          channel_knock(chan));
     SHOW_FLAG("meankicks",	channel_meankicks(chan));
     SHOW_FLAG("nodesynch",	channel_nodesynch(chan));
     SHOW_FLAG("nomassjoin",	channel_nomassjoin(chan));
     SHOW_FLAG("private",	channel_privchan(chan));
-    SHOW_FLAG("knock",          channel_knock(chan));
-//    SHOW_FLAG("revenge",	channel_revenge(chan));
+    SHOW_FLAG("rbl",		channel_rbl(chan));
 //    SHOW_FLAG("revengebot",	channel_revengebot(chan));
+//    SHOW_FLAG("revenge",	channel_revenge(chan));
     if (HAVE_TAKE)
       SHOW_FLAG("take",		channel_take(chan));
     SHOW_FLAG("voice",		channel_voice(chan));

+ 4 - 0
src/mod/channels.mod/tclchan.c

@@ -607,6 +607,10 @@ int channel_modify(char *result, struct chanset_t *chan, int items, char **item,
       chan->status |= CHAN_MEANKICKS;
     else if (!strcmp(item[i], "-meankicks"))
       chan->status &= ~CHAN_MEANKICKS;
+    else if (!strcmp(item[i], "+rbl"))
+      chan->status |= CHAN_RBL;
+    else if (!strcmp(item[i], "-rbl"))
+      chan->status &= ~CHAN_RBL;
 /* Chanflag template
  *  else if (!strcmp(item[i], "+temp"))
  *    chan->status |= CHAN_TEMP;

+ 3 - 2
src/mod/channels.mod/userchan.c

@@ -309,7 +309,7 @@ int u_delmask(char type, struct chanset_t *c, char *who, int doit)
 
 /* Note: If first char of note is '*' it's a sticky mask.
  */
-bool u_addmask(char type, struct chanset_t *chan, char *who, char *from, char *note, time_t expire_time, int flags)
+bool u_addmask(char type, struct chanset_t *chan, char *who, const char *from, const char *note, time_t expire_time, int flags)
 {
   char host[UHOSTLEN] = "", s[UHOSTLEN] = "";
   maskrec *p = NULL, *l = NULL, **u = NULL;
@@ -735,7 +735,7 @@ flood-exempt %d flood-lock-time %d \
 %cmeankicks %cenforcebans %cdynamicbans %cuserbans %cbitch \
 %cprivate %ccycle %cinactive %cdynamicexempts %cuserexempts \
 %cdynamicinvites %cuserinvites %cnodesynch %cclosed %cvoice \
-%cfastop %cautoop %cbotbitch %cbackup %cnomassjoin %cknock %c%s}\n",
+%cfastop %cautoop %cbotbitch %cbackup %cnomassjoin %cknock %crbl %c%s}\n",
 	chan->dname,
 	w,
         chan->added_by,
@@ -791,6 +791,7 @@ flood-exempt %d flood-lock-time %d \
         PLSMNS(channel_backup(chan)),
         PLSMNS(channel_nomassjoin(chan)),
         PLSMNS(channel_knock(chan)),
+        PLSMNS(channel_rbl(chan)),
 	HAVE_TAKE ? PLSMNS(channel_take(chan)) : ' ',
         HAVE_TAKE ? "take " : " "
 /* Chanflag template

+ 131 - 31
src/mod/irc.mod/chan.c

@@ -29,6 +29,7 @@
  *
  */
 
+#include <bdlib/src/String.h>
 
 static time_t last_ctcp = (time_t) 0L;
 static int    count_ctcp = 0;
@@ -37,49 +38,50 @@ static char   last_invchan[300] = "";
 
 typedef struct resolvstruct {
   struct chanset_t *chan;
-  char *nick;
+  char *host;
+  bd::String* servers;
+  bd::String* server;
 } resolv_member;
 
 static void resolv_member_callback(int id, void *client_data, const char *host, char **ips)
 {
   resolv_member *r = (resolv_member *) client_data;
 
-  if (!r || !r->chan || !r->nick) {
-    if (r->nick) free(r->nick);
+  if (!r || !r->chan || !r->host || !ips || !ips[0]) {
+    if (r) {
+      if (r->host) free(r->host);
+      free(r);
+    }
     return;
   }
 
   memberlist *m = NULL;
-  char *ps = NULL, *pe = NULL, s[UHOSTLEN + 1];
-
-  if (ips && ips[0]) {
-    for (m = r->chan->channel.member; m && m->nick[0]; m = m->next) {
-      if (!rfc_casecmp(m->nick, r->nick)) {
-        if (!m->userip[0] && m->userhost[0]) {
-          ps = m->userhost;
-          pe = strchr(ps, '@');
-          if (pe) {
-            char user[15] = "";
-
-            strlcpy(user, m->userhost, pe - ps + 1);
-            simple_snprintf(m->userip, sizeof(m->userip), "%s@%s", user, ips[0]);
-            if (!m->user) {
-              simple_snprintf(s, sizeof(s), "%s!%s", m->nick, m->userip);
-              m->user = get_user_by_host(s);
-
-              /* Act on this lookup */
-              if (m->user)
-                check_this_user(m->user->handle, 0, NULL);
-            }
-            free(r->nick);
-            return;
-          }
+  char *pe = NULL, s[UHOSTLEN + 1], user[15] = "";
+
+  /* Apply lookup results to all matching members by host */
+  for (m = r->chan->channel.member; m && m->nick[0]; m = m->next) {
+    if (!m->userip[0] && m->userhost[0]) {
+      pe = strchr(m->userhost, '@');
+      if (pe && !strcmp(pe + 1, r->host)) {
+        strlcpy(user, m->userhost, pe - m->userhost + 1);
+        simple_snprintf(m->userip, sizeof(m->userip), "%s@%s", user, ips[0]);
+        if (!m->user) {
+          simple_snprintf(s, sizeof(s), "%s!%s", m->nick, m->userip);
+          m->user = get_user_by_host(s);
+
+          /* Act on this lookup */
+          if (m->user)
+            check_this_user(m->user->handle, 0, NULL);
         }
       }
     }
   }
 
-  free(r->nick);
+  if (channel_rbl(r->chan))
+    resolve_to_rbl(r->chan, ips[0]);
+
+  free(r->host);
+  free(r);
   return;
 }
 
@@ -89,11 +91,102 @@ void resolve_to_member(struct chanset_t *chan, char *nick, char *host)
   resolv_member *r = (resolv_member *) my_calloc(1, sizeof(resolv_member));
 
   r->chan = chan;
-  r->nick = strdup(nick);
+  r->host = strdup(host);
 
   egg_dns_lookup(host, 20, resolv_member_callback, (void *) r);
 }
 
+/* RBL */
+static void resolve_rbl_callback(int id, void *client_data, const char *host, char **ips)
+{
+  resolv_member *r = (resolv_member *) client_data;
+
+  if (!r || !r->chan || !r->host || !ips || (ips && !ips[0])) {
+    if (r && r->chan && r->host) {
+      // Lookup from the next RBL
+      resolve_to_rbl(r->chan, r->host, r);
+    }
+    return;
+  }
+
+  sdprintf("RBL match for %s:%s: %s", r->chan->dname, r->host, ips[0]);
+
+  char s1[UHOSTLEN] = "";
+  simple_snprintf(s1, sizeof(s1), "*!*@%s", r->host);
+
+  bd::String reason = "Listed in RBL: " + *(r->server);
+
+  u_addmask('b', r->chan, s1, conf.bot->nick, reason.c_str(), now + (60 * (r->chan->ban_time ? r->chan->ban_time : 300)), 0);
+
+  if (me_op(r->chan)) {
+    do_mask(r->chan, r->chan->channel.ban, s1, 'b');
+
+    memberlist *m = NULL;
+    char *pe = NULL;
+
+    /* Apply lookup results to all matching members by host */
+    for (m = r->chan->channel.member; m && m->nick[0]; m = m->next) {
+      if (!m->user && !chan_sentkick(m) && m->userip[0]) {
+        pe = strchr(m->userip, '@');
+        if (pe && !strcmp(pe + 1, r->host)) {
+          m->flags |= SENTKICK;
+          dprintf(DP_MODE, "KICK %s %s :%s%s\n", r->chan->name, m->nick, bankickprefix, reason.c_str());
+        }
+      }
+    }
+  }
+
+  sdprintf("Done checking rbl (matched) for %s:%s", r->chan->dname, r->host);
+  delete r->servers;
+  delete r->server;
+  free(r->host);
+  free(r);
+  return;
+}
+
+
+void resolve_to_rbl(struct chanset_t *chan, char *host, resolv_member *r)
+{
+  if (!r) {
+    r = (resolv_member *) my_calloc(1, sizeof(resolv_member));
+
+    r->chan = chan;
+    r->host = strdup(host);
+    r->servers = new bd::String(rbl_servers);
+    r->server = new bd::String;
+  }
+
+  bd::String rbl_server = newsplit(*(r->servers), ',');
+
+  if (!rbl_server) {
+    sdprintf("Done checking rbl (no match) for %s:%s", chan->dname, host);
+    delete r->servers;
+    delete r->server;
+    free(r->host);
+    free(r);
+    return; //No more servers
+  }
+
+  *(r->server) = rbl_server;
+
+  size_t iplen = strlen(host) + 1 + rbl_server.length() + 1;
+  char *ip = (char *) my_calloc(1, iplen);
+  reverse_ip(host, ip);
+  strlcat(ip, ".", iplen);
+  strlcat(ip, rbl_server.c_str(), iplen);
+
+  if (egg_dns_lookup(ip, 20, resolve_rbl_callback, (void *) r, DNS_A) == -2) { //Already querying?
+    // Querying on clones will cause the callback to not be called and this nick will be ignored
+    // cleanup memory as this chain is not even starting.
+    delete r->servers;
+    delete r->server;
+    free(r->host);
+    free(r);
+  }
+
+  free(ip);
+}
+
 /* ID length for !channels.
  */
 #define CHANNEL_ID_LEN 5
@@ -1782,6 +1875,9 @@ static int got352or4(struct chanset_t *chan, char *user, char *host, char *nick,
   //This bot is set +r, so resolve.
   if (!m->userip[0] && doresolv(chan))
     resolve_to_member(chan, nick, host);
+  else if (!me && !m->user && m->userip[0] && doresolv(chan) && channel_rbl(chan))
+    resolve_to_rbl(chan, host);
+
 
   get_user_flagrec(m->user, &fr, chan->dname, chan);
   
@@ -2475,9 +2571,11 @@ static int gotjoin(char *from, char *chname)
           m->tried_getuser = 1;
  
           if (!m->user && !m->userip[0] && doresolv(chan)) {
-            if (is_dotted_ip(host))
+            if (is_dotted_ip(host)) {
               strlcpy(m->userip, uhost, sizeof(m->userip));
-            else
+              if (channel_rbl(chan))
+                resolve_to_rbl(chan, host);
+            } else
               resolve_to_member(chan, nick, host);
           }
         }
@@ -2498,6 +2596,8 @@ static int gotjoin(char *from, char *chname)
 
         if (!m->userip[0] && doresolv(chan))
           resolve_to_member(chan, nick, host);
+        else if (!m->user && m->userip[0] && doresolv(chan) && channel_rbl(chan))
+          resolve_to_rbl(chan, host);
 
 //	m->flags |= STOPWHO;
 

+ 1 - 0
src/mod/irc.mod/irc.c

@@ -28,6 +28,7 @@
 #include "src/common.h"
 #define MAKING_IRC
 #include "irc.h"
+#include "src/adns.h"
 #include "src/match.h"
 #include "src/settings.h"
 #include "src/tandem.h"

+ 9 - 0
src/mod/irc.mod/irc.h

@@ -22,6 +22,10 @@ enum { BC_NOCOOKIE = 1, BC_SLACK, BC_HASH };
 
 #ifdef MAKING_IRC
 
+namespace bd {
+  class String;
+}
+
 #ifdef CACHE
 typedef struct cache_chan_b {
   struct cache_chan_b *next;
@@ -94,6 +98,11 @@ static void send_chan_who(int queue, struct chanset_t* chan);
 #define newban(chan, mask, who)         new_mask((chan)->channel.ban, mask, who)
 #define newexempt(chan, mask, who)      new_mask((chan)->channel.exempt, mask, who)
 #define newinvite(chan, mask, who)      new_mask((chan)->channel.invite, mask, who)
+void resolve_to_member(struct chanset_t *chan, char *nick, char *host);
+
+typedef struct resolvstruct resolv_member;
+void resolve_to_rbl(struct chanset_t *chan, char *host, struct resolvstruct *r = NULL);
+static void do_mask(struct chanset_t *chan, masklist *m, char *mask, char Mode);
 
 #endif /* MAKING_IRC */
 

+ 3 - 0
src/set.c

@@ -29,6 +29,7 @@ static bool parsing_botset = 0;
 
 char altchars[50] = "";
 char alias[1024] = "";
+char rbl_servers[1024] = "";
 bool auth_chan;
 char auth_key[51] = "";
 char auth_prefix[2] = "";
@@ -64,6 +65,7 @@ bool manop_warn;
 char homechan[51] = "";
 char usermode[15] = "";
 
+////// THIS MUST REMAIN SORTED
 // VAR("bad-process",	&badprocess,		VAR_INT|VAR_DETECTED,				0, 4, "ignore"),
 // VAR("process-list",	process_list,		VAR_STRING|VAR_LIST,				0, 0, NULL),
 static variable_t vars[] = {
@@ -105,6 +107,7 @@ static variable_t vars[] = {
  VAR("op-bots",		&op_bots,		VAR_INT|VAR_NOLOC,				1, MAX_BOTS, "1"),
  VAR("op-requests",	&op_requests,		VAR_RATE|VAR_NOLOC,				0, 0, "2:5"),
  VAR("promisc",		&promisc,		VAR_INT|VAR_DETECTED,				0, 4, "warn"),
+ VAR("rbl-servers",	rbl_servers,		VAR_STRING|VAR_LIST|VAR_SHUFFLE|VAR_NOLHUB,	0, 0, DEFAULT_RBL),
  VAR("realname",	botrealname,		VAR_STRING|VAR_NOLHUB,				0, 0, "* I'm too lame to read BitchX.doc *"),
  VAR("server-port",	&default_port,		VAR_INT|VAR_SHORT|VAR_NOLHUB,			0, 65535, "6667"),
  VAR("servers",		&serverlist,		VAR_SERVERS|VAR_LIST|VAR_SHUFFLE|VAR_NOLHUB|VAR_NOLDEF,	0, 0, DEFAULT_SERVERS),

+ 1 - 1
src/set.h

@@ -67,7 +67,7 @@ typedef struct rate_b {
  interval_t time;
 } rate_t;
 
-extern char		auth_key[], auth_prefix[2], motd[], *def_chanset, alias[],
+extern char		auth_key[], auth_prefix[2], motd[], *def_chanset, alias[], rbl_servers[1024],
 			msgident[], msginvite[], msgop[], msgpass[],
                         homechan[], altchars[];
 extern bool		dccauth, auth_obscure, manop_warn, auth_chan, oidentd, ident_botnick, irc_autoaway, link_cleartext;