1
0
mirror of https://github.com/anope/anope.git synced 2026-06-12 17:24:49 +02:00

Improve the ban mask parsing in Entry.

This commit is contained in:
Sadie Powell
2026-01-20 12:31:05 +00:00
parent 172f443421
commit 6e18030285
8 changed files with 75 additions and 58 deletions
+4 -3
View File
@@ -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
+1 -1
View File
@@ -226,7 +226,7 @@ private:
else
{
// Normalize the entry mask.
mask = Entry("", mask).GetNUHMask();
mask = Entry("", mask).GetCleanMask();
}
}
}
+1 -1
View File
@@ -153,7 +153,7 @@ class CommandCSFlags final
else
{
// Normalize the entry mask.
mask = Entry("", mask).GetNUHMask();
mask = Entry("", mask).GetCleanMask();
}
}
}
+1 -1
View File
@@ -201,7 +201,7 @@ private:
else
{
// Normalize the entry mask.
mask = Entry("", mask).GetNUHMask();
mask = Entry("", mask).GetCleanMask();
}
}
}
+2 -2
View File
@@ -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);
}
};
+2 -2
View File
@@ -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);
}
};
+67 -51
View File
@@ -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);
const Anope::string &nu = fh.substr(0, at);
size_t ex = nu.find('!');
if (ex != Anope::string::npos)
{
this->user = nu.substr(ex + 1);
this->nick = nu.substr(0, ex);
}
if (this->mask.find_first_of(".:") == Anope::string::npos)
this->nick = this->mask;
else
this->user = nu;
this->host = this->mask;
}
else if (this->mask[first_sep] == '!')
{
this->nick = this->mask.substr(0, first_sep);
const auto second_sep = this->mask.find('@');
if (second_sep == Anope::string::npos)
this->user = this->mask.substr(first_sep + 1);
else
{
if (fh.find('.') != Anope::string::npos || fh.find(':') != Anope::string::npos)
this->host = fh;
else
this->nick = fh;
this->user = this->mask.substr(first_sep + 1, second_sep - first_sep - 1);
this->host = this->mask.substr(second_sep + 1);
}
at = this->host.find('#');
if (at != Anope::string::npos)
}
else if (this->mask[first_sep] == '@')
{
this->real = this->host.substr(at + 1);
this->host = this->host.substr(0, at);
this->user = this->mask.substr(0, first_sep);
this->host = this->mask.substr(first_sep + 1);
}
/* If the mask is all *'s it will match anything, so just clear it */
// If the mask can have a realname then extract that.
if (r)
{
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 (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);
break;
case AF_INET6:
if (cidr_len <= 128)
c = "/" + Anope::ToString(cidr_len);
{
if (cidr_len < 32)
cmask.append("/").append(Anope::ToString(cidr_len));
break;
}
case AF_INET6:
{
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
View File
@@ -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)