From: Michael Poole Date: Tue, 1 Nov 2005 00:37:44 +0000 (+0000) Subject: Avoid leaking information through ChanServ's ban matching. X-Git-Tag: v1.4.0-rc1~160 X-Git-Url: http://git.pk910.de/?a=commitdiff_plain;ds=sidebyside;h=e36a8c061fa07c9b03f5ac150c3a6738248ca5e3;p=srvx.git Avoid leaking information through ChanServ's ban matching. 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 --- diff --git a/ChangeLog b/ChangeLog index 3f306c1..e1a78d2 100644 --- 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 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 patch-31 Summary: diff --git a/src/chanserv.c b/src/chanserv.c index d9fc2a2..b5966e1 100644 --- a/src/chanserv.c +++ b/src/chanserv.c @@ -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); diff --git a/src/common.h b/src/common.h index 6e0d5c1..694df8a 100644 --- a/src/common.h +++ b/src/common.h @@ -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); diff --git a/src/opserv.c b/src/opserv.c index acfee7c..2f365ad 100644 --- a/src/opserv.c +++ b/src/opserv.c @@ -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; } diff --git a/src/tools.c b/src/tools.c index a626386..6883b71 100644 --- a/src/tools.c +++ b/src/tools.c @@ -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); }