summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAdam <Adam@anope.org>2010-12-23 16:59:56 -0500
committerAdam <Adam@anope.org>2010-12-23 16:59:56 -0500
commit12b0ff0593cc5f2c0f61ca575f9e0af8b0084994 (patch)
tree3edf1b1b9045e389ba0e957589c1017a22deeba5
parent13688c595bd11c3a4a093bc82a7d5f2733640abb (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--Changes1
-rw-r--r--include/extern.h3
-rw-r--r--include/services.h7
-rw-r--r--src/actions.c82
-rw-r--r--src/channels.c22
-rw-r--r--src/core/cs_ban.c2
-rw-r--r--src/modules/bs_fantasy_unban.c2
-rw-r--r--src/users.c15
-rw-r--r--version.log3
9 files changed, 88 insertions, 49 deletions
diff --git a/Changes b/Changes
index 1e7ce85db..abf1c66d1 100644
--- a/Changes
+++ b/Changes
@@ -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