Avoid leaking information through ChanServ's ban matching.
authorMichael Poole <mdpoole@troilus.org>
Tue, 1 Nov 2005 00:37:44 +0000 (00:37 +0000)
committerMichael Poole <mdpoole@troilus.org>
Tue, 1 Nov 2005 00:37:44 +0000 (00:37 +0000)
src/common.h (user_matches_glob): Convert last argument to be flags.

src/tools.c (user_matches_glob): Reorder tests to properly implement
    the MATCH_VISIBLE flag.

src/chanserv.c: Update callers of user_matches_glob() to set
    the MATCH_VISIBLE flag (in addition to MATCH_USENICK).

src/opserv.c: Update callers of user_matches_glob() to pass the
    MATCH_USENICK flag.
git-archimport-id: srvx@srvx.net--2005-srvx/srvx--devo--1.3--patch-32

ChangeLog
src/chanserv.c
src/common.h
src/opserv.c
src/tools.c

index 3f306c1499e8839c8f520f55ccb75ad8af555975..e1a78d2dc35d28b2ebf1d22f7553fe5f8d17d3de 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -2,6 +2,28 @@
 # arch-tag: automatic-ChangeLog--srvx@srvx.net--2005-srvx/srvx--devo--1.3
 #
 
+2005-11-01 00:37:44 GMT        Michael Poole <mdpoole@troilus.org>     patch-32
+
+    Summary:
+      Avoid leaking information through ChanServ's ban matching.
+    Revision:
+      srvx--devo--1.3--patch-32
+
+    src/common.h (user_matches_glob): Convert last argument to be flags.
+    
+    src/tools.c (user_matches_glob): Reorder tests to properly implement
+        the MATCH_VISIBLE flag.
+    
+    src/chanserv.c: Update callers of user_matches_glob() to set
+        the MATCH_VISIBLE flag (in addition to MATCH_USENICK).
+    
+    src/opserv.c: Update callers of user_matches_glob() to pass the
+        MATCH_USENICK flag.
+
+    modified files:
+     ChangeLog src/chanserv.c src/common.h src/opserv.c src/tools.c
+
+
 2005-11-01 00:23:14 GMT        Michael Poole <mdpoole@troilus.org>     patch-31
 
     Summary:
index d9fc2a25749d3e3a216dc8648a5ce09dbac9a14a..b5966e17853b292f802746c6fd7d6a843983ca78 100644 (file)
@@ -2702,7 +2702,7 @@ bad_channel_ban(struct chanNode *channel, struct userNode *user, const char *ban
         if(IsService(mn->user))
             continue;
 
-        if(!user_matches_glob(mn->user, ban, 1))
+        if(!user_matches_glob(mn->user, ban, MATCH_USENICK | MATCH_VISIBLE))
             continue;
 
         if(protect_user(mn->user, user, channel->channel_info))
@@ -3043,7 +3043,8 @@ find_matching_bans(struct banList *bans, struct userNode *actee, const char *mas
     {
         for(ii = count = 0; ii < bans->used; ++ii)
         {
-            match[ii] = user_matches_glob(actee, bans->list[ii]->ban, 1);
+            match[ii] = user_matches_glob(actee, bans->list[ii]->ban,
+                                          MATCH_USENICK | MATCH_VISIBLE);
             if(match[ii])
                 count++;
         }
@@ -3118,7 +3119,8 @@ unban_user(struct userNode *user, struct chanNode *channel, unsigned int argc, c
        while(ban)
        {
            if(actee)
-               for( ; ban && !user_matches_glob(actee, ban->mask, 1);
+               for( ; ban && !user_matches_glob(actee, ban->mask,
+                                                 MATCH_USENICK | MATCH_VISIBLE);
                     ban = ban->next);
            else
                for( ; ban && !match_ircglobs(mask, ban->mask);
@@ -5888,7 +5890,7 @@ handle_join(struct modeNode *mNode)
         unsigned int ii;
         for(ii = 0; ii < channel->banlist.used; ii++)
         {
-            if(user_matches_glob(user, channel->banlist.list[ii]->ban, 1))
+            if(user_matches_glob(user, channel->banlist.list[ii]->ban, MATCH_USENICK | MATCH_VISIBLE))
             {
                 /* Riding a netburst.  Naughty. */
                 KickChannelUser(user, channel, chanserv, "User from far side of netsplit should have been banned - bye.");
@@ -5903,8 +5905,8 @@ handle_join(struct modeNode *mNode)
     {
         /* Not joining through a ban. */
         for(bData = cData->bans;
-                bData && !user_matches_glob(user, bData->mask, 1);
-                bData = bData->next);
+            bData && !user_matches_glob(user, bData->mask, MATCH_USENICK | MATCH_VISIBLE);
+            bData = bData->next);
 
         if(bData)
         {
@@ -6085,14 +6087,14 @@ handle_auth(struct userNode *user, UNUSED_ARG(struct handle_info *old_handle))
            || IsSuspended(channel->channel_info))
             continue;
         for(jj = 0; jj < channel->banlist.used; ++jj)
-            if(user_matches_glob(user, channel->banlist.list[jj]->ban, 1))
+            if(user_matches_glob(user, channel->banlist.list[jj]->ban, MATCH_USENICK | MATCH_VISIBLE))
                 break;
         if(jj < channel->banlist.used)
             continue;
         for(ban = channel->channel_info->bans; ban; ban = ban->next)
         {
             char kick_reason[MAXLEN];
-            if(!user_matches_glob(user, ban->mask, 1))
+            if(!user_matches_glob(user, ban->mask, MATCH_USENICK | MATCH_VISIBLE))
                 continue;
             change.args[0].mode = MODE_BAN;
             change.args[0].u.hostmask = ban->mask;
@@ -6305,7 +6307,7 @@ handle_nick_change(struct userNode *user, UNUSED_ARG(const char *old_nick))
             continue;
         /* Look for a matching ban already on the channel. */
         for(jj = 0; jj < channel->banlist.used; ++jj)
-            if(user_matches_glob(user, channel->banlist.list[jj]->ban, 1))
+            if(user_matches_glob(user, channel->banlist.list[jj]->ban, MATCH_USENICK | MATCH_VISIBLE))
                 break;
         /* Need not act if we found one. */
         if(jj < channel->banlist.used)
@@ -6313,7 +6315,7 @@ handle_nick_change(struct userNode *user, UNUSED_ARG(const char *old_nick))
         /* Look for a matching ban in this channel. */
         for(bData = channel->channel_info->bans; bData; bData = bData->next)
         {
-            if(!user_matches_glob(user, bData->mask, 1))
+            if(!user_matches_glob(user, bData->mask, MATCH_USENICK | MATCH_VISIBLE))
                 continue;
             change.args[0].u.hostmask = bData->mask;
             mod_chanmode_announce(chanserv, channel, &change);
index 6e0d5c120b35a487bee707672f28b69ffdc5c2eb..694df8a3b3f1a3bc42d85c8c0fa2bc6db71075ea 100644 (file)
@@ -170,7 +170,9 @@ int split_line(char *line, int irc_colon, int argv_size, char *argv[]);
 #define match_ircglobs !mmatch
 int mmatch(const char *glob, const char *newglob);
 int match_ircglob(const char *text, const char *glob);
-int user_matches_glob(struct userNode *user, const char *glob, int include_nick);
+#define MATCH_USENICK 1
+#define MATCH_VISIBLE 2
+int user_matches_glob(struct userNode *user, const char *glob, int flags);
 
 int is_ircmask(const char *text);
 int is_gline(const char *text);
index acfee7c0a53cb9124826b1f7e10817b66dccefac..2f365adc3926c5f00b2ad49d48cd0d59b305ece0 100644 (file)
@@ -1738,7 +1738,7 @@ opserv_new_user_check(struct userNode *user)
 
     /* Gag them if appropriate. */
     for (gag = gagList; gag; gag = gag->next) {
-        if (user_matches_glob(user, gag->mask, 1)) {
+        if (user_matches_glob(user, gag->mask, MATCH_USENICK)) {
             gag_helper_func(user, NULL);
             break;
         }
@@ -3758,7 +3758,7 @@ opserv_alert_check_nick(struct userNode *user, UNUSED_ARG(const char *old_nick))
     /* Gag them if appropriate (and only if). */
     user->modes &= ~FLAGS_GAGGED;
     for (gag = gagList; gag; gag = gag->next) {
-        if (user_matches_glob(user, gag->mask, 1)) {
+        if (user_matches_glob(user, gag->mask, MATCH_USENICK)) {
             gag_helper_func(user, NULL);
             break;
         }
index a626386e47a3cbbd87f261bbdaf20bed55b71157..6883b7122851d4418388fd77ac99688020b9c916 100644 (file)
@@ -577,7 +577,7 @@ match_ircglob(const char *text, const char *glob)
 extern const char *hidden_host_suffix;
 
 int
-user_matches_glob(struct userNode *user, const char *orig_glob, int include_nick)
+user_matches_glob(struct userNode *user, const char *orig_glob, int flags)
 {
     char *glob, *marker;
 
@@ -585,9 +585,9 @@ user_matches_glob(struct userNode *user, const char *orig_glob, int include_nick
     glob = alloca(strlen(orig_glob)+1);
     strcpy(glob, orig_glob);
     /* Check the nick, if it's present */
-    if (include_nick) {
+    if (flags & MATCH_USENICK) {
         if (!(marker = strchr(glob, '!'))) {
-            log_module(MAIN_LOG, LOG_ERROR, "user_matches_glob(\"%s\", \"%s\", %d) called, and glob doesn't include a '!'", user->nick, orig_glob, include_nick);
+            log_module(MAIN_LOG, LOG_ERROR, "user_matches_glob(\"%s\", \"%s\", %d) called, and glob doesn't include a '!'", user->nick, orig_glob, flags);
             return 0;
         }
         *marker = 0;
@@ -596,17 +596,13 @@ user_matches_glob(struct userNode *user, const char *orig_glob, int include_nick
     }
     /* Check the ident */
     if (!(marker = strchr(glob, '@'))) {
-        log_module(MAIN_LOG, LOG_ERROR, "user_matches_glob(\"%s\", \"%s\", %d) called, and glob doesn't include an '@'", user->nick, orig_glob, include_nick);
+        log_module(MAIN_LOG, LOG_ERROR, "user_matches_glob(\"%s\", \"%s\", %d) called, and glob doesn't include an '@'", user->nick, orig_glob, flags);
         return 0;
     }
     *marker = 0;
     if (!match_ircglob(user->ident, glob))
         return 0;
     glob = marker + 1;
-    /* If it might be an IP glob, test that. */
-    if (!glob[strspn(glob, "0123456789./*?")]
-        && match_ircglob(irc_ntoa(&user->ip), glob))
-        return 1;
     /* Check for a fakehost match. */
     if (IsFakeHost(user) && match_ircglob(user->fakehost, glob))
         return 1;
@@ -617,6 +613,13 @@ user_matches_glob(struct userNode *user, const char *orig_glob, int include_nick
         if (match_ircglob(hidden_host, glob))
             return 1;
     }
+    /* If only matching the visible hostnames, bail early. */
+    if ((flags & MATCH_VISIBLE) && (IsFakeHost(user) || IsHiddenHost(user)))
+        return 0;
+    /* If it might be an IP glob, test that. */
+    if (!glob[strspn(glob, "0123456789./*?")]
+        && match_ircglob(irc_ntoa(&user->ip), glob))
+        return 1;
     /* None of the above; could only be a hostname match. */
     return match_ircglob(user->hostname, glob);
 }