mirror of
https://github.com/anope/anope.git
synced 2026-06-12 15:44:46 +02:00
Improve the ban mask parsing in Entry.
This commit is contained in:
+4
-3
@@ -442,16 +442,17 @@ public:
|
||||
|
||||
/** Constructor
|
||||
* @param mode What mode this host is for, can be empty for unknown/no mode
|
||||
* @param host A full or partial nick!ident@host/cidr#real name mask
|
||||
* @param mask A full or partial nick!ident@host/cidr#real name mask
|
||||
* @Param real Whether to allow a real name in the mask.
|
||||
*/
|
||||
Entry(const Anope::string &mode, const Anope::string &host);
|
||||
Entry(const Anope::string &mode, const Anope::string &mask, bool real = true);
|
||||
|
||||
/** Get the banned mask for this entry
|
||||
* @return The mask
|
||||
*/
|
||||
Anope::string GetMask() const;
|
||||
|
||||
Anope::string GetNUHMask() const;
|
||||
Anope::string GetCleanMask() const;
|
||||
|
||||
/** Check if this entry matches a user
|
||||
* @param u The user
|
||||
|
||||
@@ -226,7 +226,7 @@ private:
|
||||
else
|
||||
{
|
||||
// Normalize the entry mask.
|
||||
mask = Entry("", mask).GetNUHMask();
|
||||
mask = Entry("", mask).GetCleanMask();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -153,7 +153,7 @@ class CommandCSFlags final
|
||||
else
|
||||
{
|
||||
// Normalize the entry mask.
|
||||
mask = Entry("", mask).GetNUHMask();
|
||||
mask = Entry("", mask).GetCleanMask();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -201,7 +201,7 @@ private:
|
||||
else
|
||||
{
|
||||
// Normalize the entry mask.
|
||||
mask = Entry("", mask).GetNUHMask();
|
||||
mask = Entry("", mask).GetCleanMask();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -788,7 +788,7 @@ namespace InspIRCdExtBan
|
||||
|
||||
bool Matches(User *u, const Entry *e) override
|
||||
{
|
||||
return Entry(this->name, e->GetMask()).Matches(u);
|
||||
return Entry(this->name, e->GetMask(), false).Matches(u);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -898,7 +898,7 @@ namespace InspIRCdExtBan
|
||||
|
||||
bool Matches(User *u, const Entry *e) override
|
||||
{
|
||||
return !u->Account() && Entry(this->base, e->GetMask()).Matches(u);
|
||||
return !u->Account() && Entry(this->base, e->GetMask(), false).Matches(u);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -564,7 +564,7 @@ namespace UnrealExtBan
|
||||
|
||||
bool Matches(User *u, const Entry *e) override
|
||||
{
|
||||
return Entry(this->base, e->GetMask()).Matches(u);
|
||||
return Entry(this->base, e->GetMask(), false).Matches(u);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -646,7 +646,7 @@ namespace UnrealExtBan
|
||||
/* strip down the time (~t:1234:) and call other matchers */
|
||||
auto real_mask = e->GetMask();
|
||||
real_mask = real_mask.substr(real_mask.find(":") + 1);
|
||||
return Entry("BAN", real_mask).Matches(u);
|
||||
return Entry("BAN", real_mask, false).Matches(u);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
+63
-47
@@ -673,42 +673,49 @@ void ModeManager::StackerDel(Mode *m)
|
||||
}
|
||||
}
|
||||
|
||||
Entry::Entry(const Anope::string &m, const Anope::string &fh) : name(m), mask(fh)
|
||||
Entry::Entry(const Anope::string &n, const Anope::string &m, bool r)
|
||||
: name(n)
|
||||
, mask(m)
|
||||
{
|
||||
Anope::string n, u, h;
|
||||
|
||||
size_t at = fh.find('@');
|
||||
if (at != Anope::string::npos)
|
||||
const auto first_sep = this->mask.find_first_of("!@");
|
||||
if (first_sep == Anope::string::npos)
|
||||
{
|
||||
this->host = fh.substr(at + 1);
|
||||
if (this->mask.find_first_of(".:") == Anope::string::npos)
|
||||
this->nick = this->mask;
|
||||
else
|
||||
this->host = this->mask;
|
||||
}
|
||||
else if (this->mask[first_sep] == '!')
|
||||
{
|
||||
this->nick = this->mask.substr(0, first_sep);
|
||||
|
||||
const Anope::string &nu = fh.substr(0, at);
|
||||
|
||||
size_t ex = nu.find('!');
|
||||
if (ex != Anope::string::npos)
|
||||
const auto second_sep = this->mask.find('@');
|
||||
if (second_sep == Anope::string::npos)
|
||||
this->user = this->mask.substr(first_sep + 1);
|
||||
else
|
||||
{
|
||||
this->user = nu.substr(ex + 1);
|
||||
this->nick = nu.substr(0, ex);
|
||||
this->user = this->mask.substr(first_sep + 1, second_sep - first_sep - 1);
|
||||
this->host = this->mask.substr(second_sep + 1);
|
||||
}
|
||||
else
|
||||
this->user = nu;
|
||||
}
|
||||
else
|
||||
else if (this->mask[first_sep] == '@')
|
||||
{
|
||||
if (fh.find('.') != Anope::string::npos || fh.find(':') != Anope::string::npos)
|
||||
this->host = fh;
|
||||
else
|
||||
this->nick = fh;
|
||||
this->user = this->mask.substr(0, first_sep);
|
||||
this->host = this->mask.substr(first_sep + 1);
|
||||
}
|
||||
|
||||
at = this->host.find('#');
|
||||
if (at != Anope::string::npos)
|
||||
// If the mask can have a realname then extract that.
|
||||
if (r)
|
||||
{
|
||||
this->real = this->host.substr(at + 1);
|
||||
this->host = this->host.substr(0, at);
|
||||
const auto real_sep = this->host.find('#');
|
||||
if (real_sep != Anope::string::npos)
|
||||
{
|
||||
this->real = this->host.substr(real_sep + 1);
|
||||
this->host.erase(real_sep);
|
||||
}
|
||||
}
|
||||
|
||||
/* If the mask is all *'s it will match anything, so just clear it */
|
||||
// If the mask is all *'s it will match anything, so just clear it.
|
||||
if (this->nick.find_first_not_of("*") == Anope::string::npos)
|
||||
this->nick.clear();
|
||||
|
||||
@@ -719,22 +726,19 @@ Entry::Entry(const Anope::string &m, const Anope::string &fh) : name(m), mask(fh
|
||||
this->host.clear();
|
||||
else
|
||||
{
|
||||
/* Host might be a CIDR range */
|
||||
size_t sl = this->host.find_last_of('/');
|
||||
if (sl != Anope::string::npos)
|
||||
// Host might be a CIDR range.
|
||||
const auto cidr_sep = this->host.find_last_of('/');
|
||||
if (cidr_sep != Anope::string::npos)
|
||||
{
|
||||
const Anope::string &cidr_ip = this->host.substr(0, sl),
|
||||
&cidr_range = this->host.substr(sl + 1);
|
||||
sockaddrs cidr_addr(this->host.substr(0, cidr_sep));
|
||||
const auto cidr_range = this->host.substr(cidr_sep + 1);
|
||||
|
||||
sockaddrs addr(cidr_ip);
|
||||
auto range = Anope::TryConvert<unsigned short>(cidr_range);
|
||||
if (addr.valid() && range.has_value())
|
||||
const auto range = Anope::TryConvert<unsigned short>(cidr_range);
|
||||
if (cidr_addr.valid() && range.has_value())
|
||||
{
|
||||
this->cidr_len = range.value();
|
||||
this->host = cidr_ip;
|
||||
this->family = addr.family();
|
||||
|
||||
Log(LOG_DEBUG) << "Ban " << mask << " has cidr " << this->cidr_len;
|
||||
this->family = cidr_addr.family();
|
||||
this->host = cidr_addr.addr();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -748,26 +752,38 @@ Anope::string Entry::GetMask() const
|
||||
return this->mask;
|
||||
}
|
||||
|
||||
Anope::string Entry::GetNUHMask() const
|
||||
Anope::string Entry::GetCleanMask() const
|
||||
{
|
||||
Anope::string n = nick.empty() ? "*" : nick,
|
||||
u = user.empty() ? "*" : user,
|
||||
h = host.empty() ? "*" : host,
|
||||
r = real.empty() ? "" : "#" + real,
|
||||
c;
|
||||
Anope::string cmask;
|
||||
cmask.append(this->nick.empty() ? "*" : this->nick);
|
||||
cmask.push_back('!');
|
||||
cmask.append(this->user.empty() ? "*" : this->user);
|
||||
cmask.push_back('@');
|
||||
cmask.append(this->host.empty() ? "*" : this->host);
|
||||
|
||||
switch (family)
|
||||
{
|
||||
case AF_INET:
|
||||
if (cidr_len <= 32)
|
||||
c = "/" + Anope::ToString(cidr_len);
|
||||
{
|
||||
if (cidr_len < 32)
|
||||
cmask.append("/").append(Anope::ToString(cidr_len));
|
||||
break;
|
||||
}
|
||||
case AF_INET6:
|
||||
if (cidr_len <= 128)
|
||||
c = "/" + Anope::ToString(cidr_len);
|
||||
{
|
||||
if (cidr_len < 128)
|
||||
cmask.append("/").append(Anope::ToString(cidr_len));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return n + "!" + u + "@" + h + c + r;
|
||||
if (!this->real.empty())
|
||||
{
|
||||
cmask.push_back('#');
|
||||
cmask.append(this->real);
|
||||
}
|
||||
|
||||
return cmask;
|
||||
}
|
||||
|
||||
bool Entry::Matches(User *u, bool full) const
|
||||
|
||||
+1
-1
@@ -389,7 +389,7 @@ Anope::string IRCDProto::NormalizeMask(const Anope::string &mask)
|
||||
{
|
||||
if (IsExtbanValid(mask))
|
||||
return mask;
|
||||
return Entry("", mask).GetNUHMask();
|
||||
return Entry("", mask).GetCleanMask();
|
||||
}
|
||||
|
||||
void IRCDProto::SendContextNotice(BotInfo *bi, User *target, Channel *context, const Anope::string &msg, const Anope::map<Anope::string> &tags)
|
||||
|
||||
Reference in New Issue
Block a user