diff options
author | Adam <Adam@anope.org> | 2010-12-23 16:59:56 -0500 |
---|---|---|
committer | Adam <Adam@anope.org> | 2010-12-23 16:59:56 -0500 |
commit | 12b0ff0593cc5f2c0f61ca575f9e0af8b0084994 (patch) | |
tree | 3edf1b1b9045e389ba0e957589c1017a22deeba5 | |
parent | 13688c595bd11c3a4a093bc82a7d5f2733640abb (diff) |
Bug #1079 - Prevent /cs ban, akick, unban, etc, from matching against users real hostname and IPs in an attempt to prevent unauthorized users from gaining other users IPs via brute force attacks.
-rw-r--r-- | Changes | 1 | ||||
-rw-r--r-- | include/extern.h | 3 | ||||
-rw-r--r-- | include/services.h | 7 | ||||
-rw-r--r-- | src/actions.c | 82 | ||||
-rw-r--r-- | src/channels.c | 22 | ||||
-rw-r--r-- | src/core/cs_ban.c | 2 | ||||
-rw-r--r-- | src/modules/bs_fantasy_unban.c | 2 | ||||
-rw-r--r-- | src/users.c | 15 | ||||
-rw-r--r-- | version.log | 3 |
9 files changed, 88 insertions, 49 deletions
@@ -1,6 +1,7 @@ Anope Version 1.8 - GIT ----------------------- 12/15 F Fixed /cs enforce #channel to say SET was enforced not (null) [#1213] +12/23 F Fixed /cs (un)ban and akick from matching users real hosts/IP [#1079] Anope Version 1.8.5 ------------------- diff --git a/include/extern.h b/include/extern.h index b46b4abc9..d39faa076 100644 --- a/include/extern.h +++ b/include/extern.h @@ -56,6 +56,7 @@ E void kill_user(char *source, char *user, char *reason); E void bad_password(User * u); E void sqline(char *mask, char *reason); E void common_unban(ChannelInfo * ci, char *nick); +E void common_unban_full(ChannelInfo * ci, char *nick, boolean full); E void common_svsmode(User * u, char *modes, char *arg); /**** botserv.c ****/ @@ -154,6 +155,7 @@ E int entry_match_mask(Entry *e, char *mask, uint32 ip); E Entry *elist_match(EList *list, char *nick, char *user, char *host, uint32 ip); E Entry *elist_match_mask(EList *list, char *mask, uint32 ip); E Entry *elist_match_user(EList *list, User *u); +E Entry *elist_match_user_full(EList *list, User *u, boolean full); E Entry *elist_find_mask(EList *list, char *mask); E long get_memuse(EList *list); @@ -1175,6 +1177,7 @@ E int is_excepted(ChannelInfo * ci, User * user); E int is_excepted_mask(ChannelInfo * ci, char *mask); E int match_usermask(const char *mask, User * user); +E int match_usermask_full(const char *mask, User * user, boolean full); E int match_userip(const char *mask, User * user, char *host); E void split_usermask(const char *mask, char **nick, char **user, char **host); diff --git a/include/services.h b/include/services.h index 53b6ea6d2..814aff0c5 100644 --- a/include/services.h +++ b/include/services.h @@ -324,7 +324,12 @@ struct ircdvars_ { int admin; /* Has Admin */ int chansqline; /* Supports Channel Sqlines */ int quitonkill; /* IRCD sends QUIT when kill */ - int svsmode_unban; /* svsmode can be used to unban */ + int svsmode_unban; /* svsmode can be used to unban + * Note the core no longer uses + * this because it can lead to + * users gaining other users IPs. + * It is kept for API compatability. + */ int protect; /* Has protect modes */ int reversekickcheck; /* Can reverse ban check */ int chanreg; /* channel mode +r for register */ diff --git a/src/actions.c b/src/actions.c index 35ec93af3..915483111 100644 --- a/src/actions.c +++ b/src/actions.c @@ -125,9 +125,10 @@ void sqline(char *mask, char *reason) * Unban the nick from a channel * @param ci channel info for the channel * @param nick to remove the ban for + * @param full True to match against realhost * @return void */ -void common_unban(ChannelInfo * ci, char *nick) +static void _common_unban(ChannelInfo * ci, char *nick, boolean full) { char *av[4]; char *host = NULL; @@ -162,52 +163,59 @@ void common_unban(ChannelInfo * ci, char *nick) if (host) ip = str_is_ip(host); - if (ircd->svsmode_unban) { - anope_cmd_unban(ci->name, nick); + if (ircdcap->tsmode) { + snprintf(buf, BUFSIZE - 1, "%ld", (long int) time(NULL)); + av[0] = ci->name; + av[1] = buf; + av[2] = sstrdup("-b"); + ac = 4; } else { - if (ircdcap->tsmode) { - snprintf(buf, BUFSIZE - 1, "%ld", (long int) time(NULL)); - av[0] = ci->name; - av[1] = buf; - av[2] = sstrdup("-b"); - ac = 4; - } else { - av[0] = ci->name; - av[1] = sstrdup("-b"); - ac = 3; - } + av[0] = ci->name; + av[1] = sstrdup("-b"); + ac = 3; + } - for (ban = ci->c->bans->entries; ban; ban = next) { - next = ban->next; - if (entry_match(ban, u->nick, u->username, u->host, ip) || - entry_match(ban, u->nick, u->username, u->vhost, ip) || - entry_match(ban, u->nick, u->username, u->chost, ip)) { - anope_cmd_mode(whosends(ci), ci->name, "-b %s", ban->mask); - if (ircdcap->tsmode) - av[3] = sstrdup(ban->mask); - else - av[2] = sstrdup(ban->mask); - - do_cmode(whosends(ci), ac, av); - - if (ircdcap->tsmode) - free(av[3]); - else - free(av[2]); - } + for (ban = ci->c->bans->entries; ban; ban = next) { + next = ban->next; + if ((full && entry_match(ban, u->nick, u->username, u->host, ip)) || + entry_match(ban, u->nick, u->username, u->vhost, 0) || + entry_match(ban, u->nick, u->username, u->chost, 0)) { + anope_cmd_mode(whosends(ci), ci->name, "-b %s", ban->mask); + if (ircdcap->tsmode) + av[3] = sstrdup(ban->mask); + else + av[2] = sstrdup(ban->mask); + + do_cmode(whosends(ci), ac, av); + + if (ircdcap->tsmode) + free(av[3]); + else + free(av[2]); } - - if (ircdcap->tsmode) - free(av[2]); - else - free(av[1]); } + + if (ircdcap->tsmode) + free(av[2]); + else + free(av[1]); + /* host_resolve() sstrdup us this info so we gotta free it */ if (host) { free(host); } } +void common_unban(ChannelInfo * ci, char *nick) +{ + _common_unban(ci, nick, false); +} + +void common_unban_full(ChannelInfo * ci, char *nick, boolean full) +{ + _common_unban(ci, nick, full); +} + /*************************************************************************/ /** diff --git a/src/channels.c b/src/channels.c index 53fe52120..f41b3c16b 100644 --- a/src/channels.c +++ b/src/channels.c @@ -2386,11 +2386,12 @@ Entry *elist_match_mask(EList * list, char *mask, uint32 ip) * Check if a user matches an entry on a list. * @param list EntryList that should be matched against * @param user The user to match against the entries + * @param full true to match against real host and real IP * @return Returns the first matching entry, if none, NULL is returned. */ -Entry *elist_match_user(EList * list, User * u) +static Entry *_elist_match_user(EList * list, User * u, boolean full) { - Entry *res; + Entry *res = NULL; char *host; uint32 ip = 0; @@ -2413,11 +2414,12 @@ Entry *elist_match_user(EList * list, User * u) ip = str_is_ip(host); /* Match what we ve got against the lists.. */ - res = elist_match(list, u->nick, u->username, u->host, ip); + if (full) + res = elist_match(list, u->nick, u->username, u->host, ip); if (!res) - res = elist_match(list, u->nick, u->username, u->vhost, ip); + res = elist_match(list, u->nick, u->username, u->vhost, 0); if (!res) - res = elist_match(list, u->nick, u->username, u->chost, ip); + res = elist_match(list, u->nick, u->username, u->chost, 0); if (host) free(host); @@ -2425,6 +2427,16 @@ Entry *elist_match_user(EList * list, User * u) return res; } +Entry *elist_match_user(EList *list, User *u) +{ + return _elist_match_user(list, u, false); +} + +Entry *elist_match_user_full(EList *list, User *u, boolean full) +{ + return _elist_match_user(list, u, full); +} + /** * Find a entry identical to the given mask.. * @param list EntryList that should be matched against diff --git a/src/core/cs_ban.c b/src/core/cs_ban.c index 6f5f45095..e293a5591 100644 --- a/src/core/cs_ban.c +++ b/src/core/cs_ban.c @@ -219,7 +219,7 @@ int do_unban(User * u) } else if (!check_access(u, ci, CA_UNBAN)) { notice_lang(s_ChanServ, u, PERMISSION_DENIED); } else { - common_unban(ci, u->nick); + common_unban_full(ci, u->nick, true); notice_lang(s_ChanServ, u, CHAN_UNBANNED, chan); } return MOD_CONT; diff --git a/src/modules/bs_fantasy_unban.c b/src/modules/bs_fantasy_unban.c index 3f2198862..2702aedf2 100644 --- a/src/modules/bs_fantasy_unban.c +++ b/src/modules/bs_fantasy_unban.c @@ -69,7 +69,7 @@ int do_fantasy(int argc, char **argv) if (argc >= 4) target = myStrGetToken(argv[3], ' ', 0); if (!target) - common_unban(ci, u->nick); + common_unban_full(ci, u->nick, true); else common_unban(ci, target); diff --git a/src/users.c b/src/users.c index 1ee55ab94..e9fd3d8ff 100644 --- a/src/users.c +++ b/src/users.c @@ -979,7 +979,7 @@ int is_excepted_mask(ChannelInfo * ci, char *mask) * just user@host)? */ -int match_usermask(const char *mask, User * user) +static int _match_usermask(const char *mask, User * user, boolean full) { char *mask2; char *nick, *username, *host; @@ -1007,12 +1007,12 @@ int match_usermask(const char *mask, User * user) if (nick) { result = match_wild_nocase(nick, user->nick) && match_wild_nocase(username, user->username) - && (match_wild_nocase(host, user->host) + && ((full && match_wild_nocase(host, user->host)) || match_wild_nocase(host, user->vhost) || match_wild_nocase(host, user->chost)); } else { result = match_wild_nocase(username, user->username) - && (match_wild_nocase(host, user->host) + && ((full && match_wild_nocase(host, user->host)) || match_wild_nocase(host, user->vhost) || match_wild_nocase(host, user->chost)); } @@ -1021,6 +1021,15 @@ int match_usermask(const char *mask, User * user) return result; } +int match_usermask(const char *mask, User *user) +{ + return _match_usermask(mask, user, false); +} + +int match_usermask_full(const char *mask, User *user, boolean full) +{ + return _match_usermask(mask, user, full); +} /*************************************************************************/ diff --git a/version.log b/version.log index 8f2910ae4..894e790d4 100644 --- a/version.log +++ b/version.log @@ -8,9 +8,10 @@ VERSION_MAJOR="1" VERSION_MINOR="8" VERSION_PATCH="5" VERSION_EXTRA="-git" -VERSION_BUILD="3048" +VERSION_BUILD="3049" # $Log$ # Changes since 1.8.5 Release +#Revision 3049 - Bug #1079 - Prevent /cs ban, akick, unban, etc, from matching against users real hostname and IPs in an attempt to prevent unauthorized users from gaining other users IPs via brute force attacks. #Revision 3048 - Bug #1213 - Fixed /cs enforce #channel to say SET was enforced not (null) #Revision 3047 - Fixed some warnings found by cppcheck #Revision 3046 - Fixed bug #1202 - Made Anope aware of plexus3's channel mode +z |