summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAdam <Adam@anope.org>2013-03-15 12:27:08 -0500
committerAdam <Adam@anope.org>2013-03-15 12:27:08 -0500
commit1a0e6b0be3f901462d4376c882f1dc7304bedaf9 (patch)
treeff20ba105783b7c79a14a257f79cabb5f3d63d0d
parent81c89bb7080f17a4bdfd8912863285713e0822df (diff)
Allow autokicking real names, extbans, and channels
-rw-r--r--include/modes.h4
-rw-r--r--include/protocol.h1
-rw-r--r--modules/commands/cs_akick.cpp91
-rw-r--r--modules/protocol/inspircd12.cpp5
-rw-r--r--modules/protocol/inspircd20.cpp1
-rw-r--r--modules/protocol/unreal.cpp5
-rw-r--r--src/modes.cpp33
7 files changed, 87 insertions, 53 deletions
diff --git a/include/modes.h b/include/modes.h
index a9957e332..bb329b5b4 100644
--- a/include/modes.h
+++ b/include/modes.h
@@ -401,11 +401,11 @@ class CoreExport Entry
Anope::string mask;
public:
unsigned short cidr_len;
- Anope::string nick, user, host;
+ Anope::string nick, user, host, real;
/** Constructor
* @param mode What mode this host is for, can be empty for unknown/no mode
- * @param host A full nick!ident@host/cidr mask
+ * @param host A full or poartial nick!ident@host/cidr#real name mask
*/
Entry(const Anope::string &mode, const Anope::string &host);
diff --git a/include/protocol.h b/include/protocol.h
index 385448662..9ff0167c9 100644
--- a/include/protocol.h
+++ b/include/protocol.h
@@ -222,6 +222,7 @@ class CoreExport IRCDProto : public Service
virtual bool IsChannelValid(const Anope::string &);
virtual bool IsIdentValid(const Anope::string &);
virtual bool IsHostValid(const Anope::string &);
+ virtual bool IsExtbanValid(const Anope::string &) { return false; }
};
class CoreExport MessageSource
diff --git a/modules/commands/cs_akick.cpp b/modules/commands/cs_akick.cpp
index b388620fc..a3133b8e9 100644
--- a/modules/commands/cs_akick.cpp
+++ b/modules/commands/cs_akick.cpp
@@ -13,39 +13,6 @@
#include "module.h"
-static void split_usermask(const Anope::string &mask, Anope::string &nick, Anope::string &user, Anope::string &host)
-{
- size_t ex = mask.find('!'), at = mask.find('@', ex == Anope::string::npos ? 0 : ex + 1);
- if (ex == Anope::string::npos)
- {
- if (at == Anope::string::npos)
- {
- nick = mask;
- user = host = "*";
- }
- else
- {
- nick = "*";
- user = mask.substr(0, at);
- host = mask.substr(at + 1);
- }
- }
- else
- {
- nick = mask.substr(0, ex);
- if (at == Anope::string::npos)
- {
- user = mask.substr(ex + 1);
- host = "*";
- }
- else
- {
- user = mask.substr(ex + 1, at - ex - 1);
- host = mask.substr(at + 1);
- }
- }
-}
-
class CommandCSAKick : public Command
{
void DoAdd(CommandSource &source, ChannelInfo *ci, const std::vector<Anope::string> &params)
@@ -59,12 +26,45 @@ class CommandCSAKick : public Command
if (reason.length() > Config->CSReasonMax)
reason = reason.substr(0, Config->CSReasonMax);
- if (!na)
+ if (IRCD->IsExtbanValid(mask))
+ ; /* If this is an extban don't try to complete the mask */
+ else if (IRCD->IsChannelValid(mask))
{
- Anope::string nick, user, host;
+ /* Also don't try to complete the mask if this is a channel */
- split_usermask(mask, nick, user, host);
- mask = nick + "!" + user + "@" + host;
+ if (mask.equals_ci(ci->name) && ci->HasExt("PEACE"))
+ {
+ source.Reply(ACCESS_DENIED);
+ return;
+ }
+ }
+ else if (!na)
+ {
+ /* If the mask contains a realname the reason must be prepended with a : */
+ if (mask.find('#') != Anope::string::npos)
+ {
+ size_t r = reason.find(':');
+ if (r != Anope::string::npos)
+ {
+ mask += " " + reason.substr(0, r);
+ mask.trim();
+ reason = reason.substr(r + 1);
+ reason.trim();
+ }
+ else
+ {
+ mask = mask + " " + reason;
+ reason.clear();
+ }
+ }
+
+ Entry e("", mask);
+
+ mask = (e.nick.empty() ? "*" : e.nick) + "!"
+ + (e.user.empty() ? "*" : e.user) + "@"
+ + (e.host.empty() ? "*" : e.host);
+ if (!e.real.empty())
+ mask += "#" + e.real;
}
else
nc = na->nc;
@@ -87,6 +87,9 @@ class CommandCSAKick : public Command
/* Opers overriding get to bypass PEACE */
if (override)
;
+ /* These peace checks are only for masks */
+ else if (IRCD->IsChannelValid(mask))
+ ;
/* Check whether target nick has equal/higher access
* or whether the mask matches a user with higher/equal access - Viper */
else if (ci->HasExt("PEACE") && nc)
@@ -526,22 +529,20 @@ class CSAKick : public Module
bool kick = false;
if (autokick->nc)
+ kick = autokick->nc == u->Account();
+ else if (IRCD->IsChannelValid(autokick->mask))
{
- if (autokick->nc == u->Account())
- kick = true;
+ Channel *c = Channel::Find(autokick->mask);
+ kick = c != NULL && c->FindUser(u);
}
else
- {
- Entry akick_mask("", autokick->mask);
- if (akick_mask.Matches(u))
- kick = true;
- }
+ kick = Entry("BAN", autokick->mask).Matches(u);
if (kick)
{
Log(LOG_DEBUG_2) << u->nick << " matched akick " << (autokick->nc ? autokick->nc->display : autokick->mask);
autokick->last_used = Anope::CurTime;
- if (!autokick->nc)
+ if (!autokick->nc && autokick->mask.find('#') == Anope::string::npos)
mask = autokick->mask;
reason = autokick->reason.empty() ? Config->CSAutokickReason : autokick->reason;
return EVENT_STOP;
diff --git a/modules/protocol/inspircd12.cpp b/modules/protocol/inspircd12.cpp
index 62886d311..1a7f338c1 100644
--- a/modules/protocol/inspircd12.cpp
+++ b/modules/protocol/inspircd12.cpp
@@ -374,6 +374,11 @@ class InspIRCd12Proto : public IRCDProto
void SendOper(User *u) anope_override
{
}
+
+ bool IsExtbanValid(const Anope::string &mask) anope_override
+ {
+ return mask.length() >= 3 && mask[1] == ':';
+ }
};
class InspIRCdExtBan : public ChannelModeList
diff --git a/modules/protocol/inspircd20.cpp b/modules/protocol/inspircd20.cpp
index cd2a1bbd4..632c60a3c 100644
--- a/modules/protocol/inspircd20.cpp
+++ b/modules/protocol/inspircd20.cpp
@@ -72,6 +72,7 @@ class InspIRCd20Proto : public IRCDProto
void SendLogin(User *u) anope_override { insp12->SendLogin(u); }
void SendLogout(User *u) anope_override { insp12->SendLogout(u); }
void SendChannel(Channel *c) anope_override { insp12->SendChannel(c); }
+ bool IsExtbanValid(const Anope::string &mask) anope_override { return insp12->IsExtbanValid(mask); }
};
class InspIRCdExtBan : public ChannelModeList
diff --git a/modules/protocol/unreal.cpp b/modules/protocol/unreal.cpp
index 3f1d33279..4bfc8e3fb 100644
--- a/modules/protocol/unreal.cpp
+++ b/modules/protocol/unreal.cpp
@@ -337,6 +337,11 @@ class UnrealIRCdProto : public IRCDProto
return IRCDProto::IsChannelValid(chan);
}
+ bool IsExtbanValid(const Anope::string &mask) anope_override
+ {
+ return mask.length() >= 4 && mask[0] == '~' && mask[2] == ':';
+ }
+
void SendLogin(User *u) anope_override
{
if (!u->Account())
diff --git a/src/modes.cpp b/src/modes.cpp
index b7c22dfc7..0eee41682 100644
--- a/src/modes.cpp
+++ b/src/modes.cpp
@@ -626,7 +626,19 @@ Entry::Entry(const Anope::string &m, const Anope::string &fh) : name(m), mask(fh
this->user = nu;
}
else
- this->host = fh;
+ {
+ if (fh.find('.') != Anope::string::npos || fh.find(':') != Anope::string::npos)
+ this->host = fh;
+ else
+ this->nick = fh;
+ }
+
+ at = this->host.find('#');
+ if (at != Anope::string::npos)
+ {
+ this->real = this->host.substr(at + 1);
+ this->host = this->host.substr(0, at);
+ }
/* If the mask is all *'s it will match anything, so just clear it */
if (this->nick.find_first_not_of("*") == Anope::string::npos)
@@ -667,6 +679,9 @@ Entry::Entry(const Anope::string &m, const Anope::string &fh) : name(m), mask(fh
catch (const ConvertException &) { }
}
}
+
+ if (this->real.find_first_not_of("*") == Anope::string::npos)
+ this->real.clear();
}
const Anope::string Entry::GetMask() const
@@ -677,12 +692,15 @@ const Anope::string Entry::GetMask() const
bool Entry::Matches(const User *u, bool full) const
{
/* First check if this mode has defined any matches (usually for extbans). */
- ChannelMode *cm = ModeManager::FindChannelModeByName(this->name);
- if (cm != NULL && cm->type == MODE_LIST)
+ if (IRCD->IsExtbanValid(this->mask))
{
- ChannelModeList *cml = anope_dynamic_static_cast<ChannelModeList *>(cm);
- if (cml->Matches(u, this))
- return true;
+ ChannelMode *cm = ModeManager::FindChannelModeByName(this->name);
+ if (cm != NULL && cm->type == MODE_LIST)
+ {
+ ChannelModeList *cml = anope_dynamic_static_cast<ChannelModeList *>(cm);
+ if (cml->Matches(u, this))
+ return true;
+ }
}
/* If the user's displayed host is their real host, then we can do a full match without
@@ -714,6 +732,9 @@ bool Entry::Matches(const User *u, bool full) const
(!full || (!Anope::Match(u->host, this->host) && !Anope::Match(u->ip, this->host))))
ret = false;
+ if (!this->real.empty() && !Anope::Match(u->realname, this->real))
+ ret = false;
+
return ret;
}