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 /** Constructor
* @param mode What mode this host is for, can be empty for unknown/no mode * @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 /** Get the banned mask for this entry
* @return The mask * @return The mask
*/ */
Anope::string GetMask() const; Anope::string GetMask() const;
Anope::string GetNUHMask() const; Anope::string GetCleanMask() const;
/** Check if this entry matches a user /** Check if this entry matches a user
* @param u The user * @param u The user
+1 -1
View File
@@ -226,7 +226,7 @@ private:
else else
{ {
// Normalize the entry mask. // Normalize the entry mask.
mask = Entry("", mask).GetNUHMask(); mask = Entry("", mask).GetCleanMask();
} }
} }
} }
+1 -1
View File
@@ -153,7 +153,7 @@ class CommandCSFlags final
else else
{ {
// Normalize the entry mask. // Normalize the entry mask.
mask = Entry("", mask).GetNUHMask(); mask = Entry("", mask).GetCleanMask();
} }
} }
} }
+1 -1
View File
@@ -201,7 +201,7 @@ private:
else else
{ {
// Normalize the entry mask. // 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 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 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 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 */ /* strip down the time (~t:1234:) and call other matchers */
auto real_mask = e->GetMask(); auto real_mask = e->GetMask();
real_mask = real_mask.substr(real_mask.find(":") + 1); 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
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; const auto first_sep = this->mask.find_first_of("!@");
if (first_sep == Anope::string::npos)
size_t at = fh.find('@');
if (at != 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); const auto second_sep = this->mask.find('@');
if (second_sep == Anope::string::npos)
size_t ex = nu.find('!'); this->user = this->mask.substr(first_sep + 1);
if (ex != Anope::string::npos) else
{ {
this->user = nu.substr(ex + 1); this->user = this->mask.substr(first_sep + 1, second_sep - first_sep - 1);
this->nick = nu.substr(0, ex); 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->user = this->mask.substr(0, first_sep);
this->host = fh; this->host = this->mask.substr(first_sep + 1);
else
this->nick = fh;
} }
at = this->host.find('#'); // If the mask can have a realname then extract that.
if (at != Anope::string::npos) if (r)
{ {
this->real = this->host.substr(at + 1); const auto real_sep = this->host.find('#');
this->host = this->host.substr(0, at); 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) if (this->nick.find_first_not_of("*") == Anope::string::npos)
this->nick.clear(); this->nick.clear();
@@ -719,22 +726,19 @@ Entry::Entry(const Anope::string &m, const Anope::string &fh) : name(m), mask(fh
this->host.clear(); this->host.clear();
else else
{ {
/* Host might be a CIDR range */ // Host might be a CIDR range.
size_t sl = this->host.find_last_of('/'); const auto cidr_sep = this->host.find_last_of('/');
if (sl != Anope::string::npos) if (cidr_sep != Anope::string::npos)
{ {
const Anope::string &cidr_ip = this->host.substr(0, sl), sockaddrs cidr_addr(this->host.substr(0, cidr_sep));
&cidr_range = this->host.substr(sl + 1); const auto cidr_range = this->host.substr(cidr_sep + 1);
sockaddrs addr(cidr_ip); const auto range = Anope::TryConvert<unsigned short>(cidr_range);
auto range = Anope::TryConvert<unsigned short>(cidr_range); if (cidr_addr.valid() && range.has_value())
if (addr.valid() && range.has_value())
{ {
this->cidr_len = range.value(); this->cidr_len = range.value();
this->host = cidr_ip; this->family = cidr_addr.family();
this->family = addr.family(); this->host = cidr_addr.addr();
Log(LOG_DEBUG) << "Ban " << mask << " has cidr " << this->cidr_len;
} }
} }
} }
@@ -748,26 +752,38 @@ Anope::string Entry::GetMask() const
return this->mask; return this->mask;
} }
Anope::string Entry::GetNUHMask() const Anope::string Entry::GetCleanMask() const
{ {
Anope::string n = nick.empty() ? "*" : nick, Anope::string cmask;
u = user.empty() ? "*" : user, cmask.append(this->nick.empty() ? "*" : this->nick);
h = host.empty() ? "*" : host, cmask.push_back('!');
r = real.empty() ? "" : "#" + real, cmask.append(this->user.empty() ? "*" : this->user);
c; cmask.push_back('@');
cmask.append(this->host.empty() ? "*" : this->host);
switch (family) switch (family)
{ {
case AF_INET: case AF_INET:
if (cidr_len <= 32) {
c = "/" + Anope::ToString(cidr_len); if (cidr_len < 32)
cmask.append("/").append(Anope::ToString(cidr_len));
break; break;
}
case AF_INET6: case AF_INET6:
if (cidr_len <= 128) {
c = "/" + Anope::ToString(cidr_len); if (cidr_len < 128)
cmask.append("/").append(Anope::ToString(cidr_len));
break; 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 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)) if (IsExtbanValid(mask))
return 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) void IRCDProto::SendContextNotice(BotInfo *bi, User *target, Channel *context, const Anope::string &msg, const Anope::map<Anope::string> &tags)