1
0
mirror of https://github.com/anope/anope.git synced 2026-07-06 15:53:13 +02:00

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.

This commit is contained in:
Adam
2010-12-23 16:59:56 -05:00
parent 13688c595b
commit 12b0ff0593
9 changed files with 90 additions and 51 deletions
+1
View File
@@ -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
-------------------
+3
View File
@@ -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);
+6 -1
View File
@@ -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 */
+47 -39
View File
@@ -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;
}
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]);
}
}
if (ircdcap->tsmode)
free(av[2]);
else
free(av[1]);
av[0] = ci->name;
av[1] = sstrdup("-b");
ac = 3;
}
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]);
/* 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);
}
/*************************************************************************/
/**
+17 -5
View File
@@ -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
+1 -1
View File
@@ -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;
+1 -1
View File
@@ -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);
+12 -3
View File
@@ -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);
}
/*************************************************************************/
+2 -1
View File
@@ -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