Ver Fonte

* Added flag '+r' which will make a bot resolve all hosts it sees to match against userlist. (You should only set this per-chan)
(THIS IS VERY CPU INTENSIVE)


svn: 2303

Bryan Drewery há 21 anos atrás
pai
commit
55e6306412
8 ficheiros alterados com 97 adições e 8 exclusões
  1. 1 0
      doc/UPDATES
  2. 2 0
      misc/help.txt
  3. 1 0
      src/chan.h
  4. 14 0
      src/flags.c
  5. 4 0
      src/flags.h
  6. 69 4
      src/mod/irc.mod/chan.c
  7. 4 4
      src/mod/irc.mod/cmdsirc.c
  8. 2 0
      src/mod/irc.mod/irc.c

+ 1 - 0
doc/UPDATES

@@ -50,6 +50,7 @@ Lines prefixed with '-' were disabled before release and are not finished, or ar
 * Fixed typo for 'help nopass'
 * Added CIDR/mask matching support for all user hosts, ie, '.+host user *!jerry@1.2.0.0/16' will match 'bob!jerry@1.2.3.4'
 * Balanced out mdop/mop kicks to not make entire net flood off.
+* Added flag '+r' which will make a bot resolve all hosts it sees to match against userlist. (You should only set this per-chan)
 
 1.2.4
 * Fixed cmd_botset not displaying botnick.

+ 2 - 0
misc/help.txt

@@ -1838,6 +1838,7 @@ See also: whom
       $bO$b - autoop (user is auto-opped in all channels)
       $bp$b - party-line (user has access to the partyline)
       $bq$b - quiet (user cannot gain voice on any channel)
+      $br$b - resolve (bot resolves clients in to match against userlist) [$bCPU INTENSIVE+$b]
       $bu$b - update-bot (see doc/UPGRADING)
       $bv$b - voice (user gets +v automatically from +y bots)
       $bw$b - wasop-test (needs wasop test for +stopnethack procedure)
@@ -1855,6 +1856,7 @@ See also: whom
       $bo$b - op (user has op access to the channel)
       $bO$b - autoop (user is auto-opped in channel)
       $bq$b - quiet (user cannot gain voice on the channel)
+      $br$b - resolve (bot resolves clients in channel to match against userlist) [$bCPU INTENSIVE+$b]
       $bv$b - voice (user gets +v automatically)
       $bw$b - wasop-test (needs wasop test for +stopnethack procedure)
       $by$b - voice-bot (bot gives out voices/auto-ops in the channel) [$bCPU INTENSIVE$b]

+ 1 - 0
src/chan.h

@@ -20,6 +20,7 @@ typedef struct memstruct {
   unsigned short flags;
   char nick[NICKLEN];
   char userhost[UHOSTLEN];
+  char userip[UHOSTLEN];
 } memberlist;
 
 #define CHANMETA "#&!+"

+ 14 - 0
src/flags.c

@@ -515,6 +515,20 @@ ischanhub()
     return 0;
 }
 
+int
+doresolv(struct chanset_t *chan)
+{
+  if (!chan)
+    return 0;
+
+  struct flag_record fr = { FR_GLOBAL | FR_CHAN, 0, 0, 0 };
+
+  get_user_flagrec(conf.bot->u, &fr, chan->dname);
+  if (glob_doresolv(fr) || chan_doresolv(fr))
+    return 1;
+  return 0;
+}
+
 int
 dovoice(struct chanset_t *chan)
 {

+ 4 - 0
src/flags.h

@@ -74,6 +74,7 @@ struct flag_record {
 #define USER_AUTOOP	FLAG[(int) 'O']
 #define USER_PARTY	FLAG[(int) 'p']
 #define USER_QUIET	FLAG[(int) 'q']
+#define USER_DORESOLV	FLAG[(int) 'r']
 #define USER_UPDATEHUB	FLAG[(int) 'u']
 #define USER_VOICE	FLAG[(int) 'v']
 #define USER_WASOPTEST	FLAG[(int) 'w']
@@ -122,6 +123,8 @@ struct flag_record {
 #define glob_noflood(x)                        ((x).global & USER_NOFLOOD)
 #define chan_noflood(x)                        ((x).chan & USER_NOFLOOD)
 #define glob_chanhub(x)                        ((x).global & USER_CHANHUB)
+#define glob_doresolv(x)                        ((x).global & USER_DORESOLV)
+#define chan_doresolv(x)                        ((x).chan & USER_DORESOLV)
 
 void init_flags(void);
 void get_user_flagrec(struct userrec *, struct flag_record *, const char *);
@@ -144,6 +147,7 @@ int chk_devoice(struct flag_record);
 int chk_noflood(struct flag_record);
 int ischanhub(void);
 int isupdatehub(void);
+int doresolv(struct chanset_t *);
 int dovoice(struct chanset_t *);
 int dolimit(struct chanset_t *);
 int whois_access(struct userrec *, struct userrec *);

+ 69 - 4
src/mod/irc.mod/chan.c

@@ -15,6 +15,53 @@ static int    count_ctcp = 0;
 static time_t last_invtime = (time_t) 0L;
 static char   last_invchan[300] = "";
 
+typedef struct resolvstruct {
+  struct chanset_t *chan;
+  char *nick;
+} 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)
+    return;
+
+  memberlist *m = NULL;
+  char *ps = NULL, *pe = NULL;
+
+  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] = "";
+
+            simple_snprintf(user, pe - ps + 1, m->userhost);
+            simple_snprintf(m->userip, sizeof(m->userip), "%s@%s", user, ips[0]);
+            return;
+          }
+        }
+      }
+    }
+  }
+
+  return;
+}
+
+
+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);
+
+  egg_dns_lookup(host, 20, resolv_member_callback, (void *) r);
+}
+
 /* ID length for !channels.
  */
 #define CHANNEL_ID_LEN 5
@@ -1296,6 +1343,9 @@ void recheck_channel(struct chanset_t *chan, int dobans)
 static int got302(char *from, char *msg)
 {
   char *p = NULL, *nick = NULL, *uhost = NULL;
+  struct chanset_t *chan = NULL;
+  memberlist *m = NULL;
+
 #ifdef CACHE
   cache_t *cache = NULL;
   cache_chan_t *cchan = NULL;
@@ -1598,8 +1648,13 @@ static int got352or4(struct chanset_t *chan, char *user, char *host, char *nick,
 
   /* Store the userhost */
   if (!m->userhost[0])
-    simple_sprintf(m->userhost, "%s@%s", user, host);
-  simple_sprintf(userhost, "%s!%s", nick, m->userhost);
+    simple_snprintf(m->userhost, sizeof(m->userhost), "%s@%s", user, host);
+  if (doresolv(chan) && is_dotted_ip(host))
+    simple_snprintf(m->userip, sizeof(m->userip), "%s@%s", user, host);
+  else
+    resolve_to_member(chan, nick, host);
+
+  simple_snprintf(userhost, sizeof(userhost), "%s!%s", nick, m->userhost);
 
   waschanop = me_op(chan);      /* Am I opped here? */
   if (strchr(flags, '@') != NULL)	/* Flags say he's opped? */
@@ -2329,6 +2384,8 @@ static int gotjoin(char *from, char *chname)
 	m->flags |= STOPWHO;
         irc_log(chan, "%s returned from netsplit", m->nick);
       } else {
+        char *p = NULL;
+
 	if (m)
 	  killmember(chan, nick);
 	m = newmember(chan, nick);
@@ -2337,8 +2394,16 @@ static int gotjoin(char *from, char *chname)
 	m->flags = 0;
 	m->last = now;
 	m->delay = 0L;
-	strcpy(m->nick, nick);
-	strcpy(m->userhost, uhost);
+	strlcpy(m->nick, nick, sizeof(m->nick));
+	strlcpy(m->userhost, uhost, sizeof(m->userhost));
+        if (doresolv(chan) && (p = strchr(uhost, '@'))) {
+          p++;
+          if (is_dotted_ip(p))
+            strlcpy(m->userip, uhost, sizeof(m->userip));
+          else
+            resolve_to_member(chan, nick, p); 
+        }
+        
 	m->user = u;
 	m->flags |= STOPWHO;
 

+ 4 - 4
src/mod/irc.mod/cmdsirc.c

@@ -1306,9 +1306,9 @@ static void cmd_channel(int idx, char *par)
     if (maxhandlen < 9) maxhandlen = 9;
     
     dprintf(idx, "(n = owner, m = master, o = op, d = deop, b = bot) CAP:global\n");
-    egg_snprintf(format, sizeof format, " %%-%us %%-%us %%-6s %%-4s %%-5s %%s\n", 
+    egg_snprintf(format, sizeof format, " %%-%us %%-%us %%-6s %%-4s %%-5s %%s %%s\n", 
 			maxnicklen, maxhandlen);
-    dprintf(idx, format, "NICKNAME", "HANDLE", " JOIN", "  HOPS", "IDLE", "USER@HOST");
+    dprintf(idx, format, "NICKNAME", "HANDLE", " JOIN", "  HOPS", "IDLE", "USER@HOST", "USER@IP");
     for (m = chan->channel.member; m && m->nick[0]; m = m->next) {
       if (m->joined > 0) {
 	if ((now - (m->joined)) > 86400)
@@ -1406,10 +1406,10 @@ static void cmd_channel(int idx, char *par)
 	  egg_snprintf(s1, sizeof s1, "%2lim", ((now - (m->last)) / 60));
 	else
 	  strlcpy(s1, "   ", sizeof s1);
-	egg_snprintf(format, sizeof format, "%%c%%c%%-%us %%-%us %%s %%c   %%d %%s  %%s\n", 
+	egg_snprintf(format, sizeof format, "%%c%%c%%-%us %%-%us %%s %%c   %%d %%s  %%s %%s\n", 
 			maxnicklen, maxhandlen);
 	dprintf(idx, format, chanflag[0], chanflag[1], m->nick,	handle, s, atrflag, m->hops,
-                     s1, m->userhost);
+                     s1, m->userhost, m->userip);
       }
       if (chan_fakeop(m))
 	dprintf(idx, "    (FAKE CHANOP GIVEN BY SERVER)\n");

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

@@ -20,6 +20,8 @@
 #include "src/userrec.h"
 #include "src/misc.h"
 #include "src/rfc1459.h"
+#include "src/socket.h"
+#include "src/adns.h"
 #include "src/chanprog.h"
 #include "src/auth.h"
 #include "src/userrec.h"