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 /src | |
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.
Diffstat (limited to 'src')
-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 |
5 files changed, 76 insertions, 47 deletions
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); +} /*************************************************************************/ |