mirror of
https://github.com/anope/anope.git
synced 2026-06-29 14:36:39 +02:00
Make sockaddrs/cidr not throw on invalid ips to give us an easier/cheaper way to test for a valid IP
This commit is contained in:
@@ -79,6 +79,8 @@ union CoreExport sockaddrs
|
||||
* @throws A socket exception if given an invalid structure
|
||||
*/
|
||||
void ntop(int type, const void *src);
|
||||
|
||||
bool valid() const;
|
||||
};
|
||||
|
||||
class CoreExport cidr
|
||||
@@ -91,6 +93,7 @@ class CoreExport cidr
|
||||
cidr(const Anope::string &ip, unsigned char len);
|
||||
Anope::string mask() const;
|
||||
bool match(const sockaddrs &other);
|
||||
bool valid() const;
|
||||
|
||||
bool operator<(const cidr &other) const;
|
||||
bool operator==(const cidr &other) const;
|
||||
|
||||
@@ -446,22 +446,11 @@ class CommandOSDNS : public Command
|
||||
return;
|
||||
}
|
||||
|
||||
sockaddrs addr;
|
||||
try
|
||||
sockaddrs addr(params[2]);
|
||||
if (!addr.valid())
|
||||
{
|
||||
addr.pton(AF_INET, params[2]);
|
||||
}
|
||||
catch (const SocketException &)
|
||||
{
|
||||
try
|
||||
{
|
||||
addr.pton(AF_INET6, params[2]);
|
||||
}
|
||||
catch (const SocketException &)
|
||||
{
|
||||
source.Reply(_("%s is not a valid IP address."), params[2].c_str());
|
||||
return;
|
||||
}
|
||||
source.Reply(_("%s is not a valid IP address."), params[2].c_str());
|
||||
return;
|
||||
}
|
||||
|
||||
s->GetIPs().push_back(params[2]);
|
||||
|
||||
+79
-107
@@ -63,15 +63,9 @@ class MySessionService : public SessionService
|
||||
Exception *e = *it;
|
||||
if (Anope::Match(u->host, e->mask) || Anope::Match(u->ip, e->mask))
|
||||
return e;
|
||||
else if (e->mask.find_first_not_of("0123456789.:/") == Anope::string::npos && e->mask.find('/') != Anope::string::npos && u->ip.find_first_not_of("0123456789.:") == Anope::string::npos)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (cidr(e->mask).match(u->ip))
|
||||
return e;
|
||||
}
|
||||
catch (const SocketException &) { }
|
||||
}
|
||||
|
||||
if (cidr(e->mask).match(sockaddrs(u->ip)))
|
||||
return e;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
@@ -83,15 +77,9 @@ class MySessionService : public SessionService
|
||||
Exception *e = *it;
|
||||
if (Anope::Match(host, e->mask))
|
||||
return e;
|
||||
else if (e->mask.find_first_not_of("0123456789.:/") == Anope::string::npos && e->mask.find('/') != Anope::string::npos && host.find_first_not_of("0123456789.:") == Anope::string::npos)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (cidr(e->mask).match(host))
|
||||
return e;
|
||||
}
|
||||
catch (const SocketException &) { }
|
||||
}
|
||||
|
||||
if (cidr(e->mask).match(sockaddrs(host)))
|
||||
return e;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
@@ -110,6 +98,8 @@ class MySessionService : public SessionService
|
||||
Session *FindSession(const Anope::string &ip) anope_override
|
||||
{
|
||||
cidr c(ip, ip.find(':') != Anope::string::npos ? ipv6_cidr : ipv4_cidr);
|
||||
if (!c.valid())
|
||||
return NULL;
|
||||
SessionMap::iterator it = this->Sessions.find(c);
|
||||
if (it != this->Sessions.end())
|
||||
return it->second;
|
||||
@@ -119,13 +109,14 @@ class MySessionService : public SessionService
|
||||
SessionMap::iterator FindSessionIterator(const Anope::string &ip)
|
||||
{
|
||||
cidr c(ip, ip.find(':') != Anope::string::npos ? ipv6_cidr : ipv4_cidr);
|
||||
if (!c.valid())
|
||||
return this->Sessions.end();
|
||||
return this->Sessions.find(c);
|
||||
}
|
||||
|
||||
Session* &FindOrCreateSession(const Anope::string &ip)
|
||||
Session* &FindOrCreateSession(const cidr &ip)
|
||||
{
|
||||
cidr c(ip, ip.find(':') != Anope::string::npos ? ipv6_cidr : ipv4_cidr);
|
||||
return this->Sessions[c];
|
||||
return this->Sessions[ip];
|
||||
}
|
||||
|
||||
SessionMap &GetSessions() anope_override
|
||||
@@ -246,31 +237,24 @@ class CommandOSSession : public Command
|
||||
void DoView(CommandSource &source, const std::vector<Anope::string> ¶ms)
|
||||
{
|
||||
Anope::string param = params[1];
|
||||
Session *session = NULL;
|
||||
|
||||
try
|
||||
Session *session = session_service->FindSession(param);
|
||||
|
||||
Exception *exception = session_service->FindException(param);
|
||||
Anope::string entry = "no entry";
|
||||
unsigned limit = session_limit;
|
||||
if (exception)
|
||||
{
|
||||
session = session_service->FindSession(param);
|
||||
if (!exception->limit)
|
||||
limit = 0;
|
||||
else if (exception->limit > limit)
|
||||
limit = exception->limit;
|
||||
entry = exception->mask;
|
||||
}
|
||||
catch (const SocketException &) { }
|
||||
|
||||
if (!session)
|
||||
source.Reply(_("\002%s\002 not found on session list."), param.c_str());
|
||||
source.Reply(_("\002%s\002 not found on session list, but has a limit of \002%d\002 because it matches entry: \2%s\2."), param.c_str(), limit, entry.c_str());
|
||||
else
|
||||
{
|
||||
Exception *exception = session_service->FindException(param);
|
||||
Anope::string entry = "no entry";
|
||||
unsigned limit = session_limit;
|
||||
if (exception)
|
||||
{
|
||||
if (!exception->limit)
|
||||
limit = 0;
|
||||
else if (exception->limit > limit)
|
||||
limit = exception->limit;
|
||||
entry = exception->mask;
|
||||
}
|
||||
source.Reply(_("The host \002%s\002 currently has \002%d\002 sessions with a limit of \002%d\002 because it matches entry: \2%s\2."), session->addr.mask().c_str(), session->count, limit, entry.c_str());
|
||||
}
|
||||
}
|
||||
public:
|
||||
CommandOSSession(Module *creator) : Command(creator, "operserv/session", 2, 2)
|
||||
@@ -690,68 +674,68 @@ class OSSession : public Module
|
||||
if (u->Quitting() || !session_limit || exempt || !u->server || u->server->IsULined())
|
||||
return;
|
||||
|
||||
try
|
||||
cidr u_ip(u->ip);
|
||||
if (!u_ip.valid())
|
||||
return;
|
||||
|
||||
Session* &session = this->ss.FindOrCreateSession(u_ip);
|
||||
|
||||
if (session)
|
||||
{
|
||||
Session* &session = this->ss.FindOrCreateSession(u->ip);
|
||||
|
||||
if (session)
|
||||
bool kill = false;
|
||||
if (session->count >= session_limit)
|
||||
{
|
||||
bool kill = false;
|
||||
if (session->count >= session_limit)
|
||||
kill = true;
|
||||
Exception *exception = this->ss.FindException(u);
|
||||
if (exception)
|
||||
{
|
||||
kill = true;
|
||||
Exception *exception = this->ss.FindException(u);
|
||||
if (exception)
|
||||
{
|
||||
kill = false;
|
||||
if (exception->limit && session->count >= exception->limit)
|
||||
kill = true;
|
||||
}
|
||||
}
|
||||
|
||||
/* Previously on IRCds that send a QUIT (InspIRCD) when a user is killed, the session for a host was
|
||||
* decremented in do_quit, which caused problems and fixed here
|
||||
*
|
||||
* Now, we create the user struture before calling this to fix some user tracking issues,
|
||||
* so we must increment this here no matter what because it will either be
|
||||
* decremented when the user is killed or quits - Adam
|
||||
*/
|
||||
++session->count;
|
||||
|
||||
if (kill && !exempt)
|
||||
{
|
||||
if (OperServ)
|
||||
{
|
||||
if (!sle_reason.empty())
|
||||
{
|
||||
Anope::string message = sle_reason.replace_all_cs("%IP%", u->ip);
|
||||
u->SendMessage(OperServ, message);
|
||||
}
|
||||
if (!sle_detailsloc.empty())
|
||||
u->SendMessage(OperServ, sle_detailsloc);
|
||||
}
|
||||
|
||||
++session->hits;
|
||||
if (max_session_kill && session->hits >= max_session_kill && akills)
|
||||
{
|
||||
const Anope::string &akillmask = "*@" + u->ip;
|
||||
XLine *x = new XLine(akillmask, OperServ ? OperServ->nick : "", Anope::CurTime + session_autokill_expiry, "Session limit exceeded", XLineManager::GenerateUID());
|
||||
akills->AddXLine(x);
|
||||
akills->Send(NULL, x);
|
||||
Log(OperServ, "akill/session") << "Added a temporary AKILL for \002" << akillmask << "\002 due to excessive connections";
|
||||
}
|
||||
else
|
||||
{
|
||||
u->Kill(OperServ ? OperServ->nick : "", "Session limit exceeded");
|
||||
}
|
||||
kill = false;
|
||||
if (exception->limit && session->count >= exception->limit)
|
||||
kill = true;
|
||||
}
|
||||
}
|
||||
else
|
||||
|
||||
/* Previously on IRCds that send a QUIT (InspIRCD) when a user is killed, the session for a host was
|
||||
* decremented in do_quit, which caused problems and fixed here
|
||||
*
|
||||
* Now, we create the user struture before calling this to fix some user tracking issues,
|
||||
* so we must increment this here no matter what because it will either be
|
||||
* decremented when the user is killed or quits - Adam
|
||||
*/
|
||||
++session->count;
|
||||
|
||||
if (kill && !exempt)
|
||||
{
|
||||
session = new Session(u->ip, u->ip.find(':') != Anope::string::npos ? ipv6_cidr : ipv4_cidr);
|
||||
if (OperServ)
|
||||
{
|
||||
if (!sle_reason.empty())
|
||||
{
|
||||
Anope::string message = sle_reason.replace_all_cs("%IP%", u->ip);
|
||||
u->SendMessage(OperServ, message);
|
||||
}
|
||||
if (!sle_detailsloc.empty())
|
||||
u->SendMessage(OperServ, sle_detailsloc);
|
||||
}
|
||||
|
||||
++session->hits;
|
||||
if (max_session_kill && session->hits >= max_session_kill && akills)
|
||||
{
|
||||
const Anope::string &akillmask = "*@" + u->ip;
|
||||
XLine *x = new XLine(akillmask, OperServ ? OperServ->nick : "", Anope::CurTime + session_autokill_expiry, "Session limit exceeded", XLineManager::GenerateUID());
|
||||
akills->AddXLine(x);
|
||||
akills->Send(NULL, x);
|
||||
Log(OperServ, "akill/session") << "Added a temporary AKILL for \002" << akillmask << "\002 due to excessive connections";
|
||||
}
|
||||
else
|
||||
{
|
||||
u->Kill(OperServ ? OperServ->nick : "", "Session limit exceeded");
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (const SocketException &) { }
|
||||
else
|
||||
{
|
||||
session = new Session(u->ip, u->ip.find(':') != Anope::string::npos ? ipv6_cidr : ipv4_cidr);
|
||||
}
|
||||
}
|
||||
|
||||
void OnUserQuit(User *u, const Anope::string &msg) anope_override
|
||||
@@ -759,23 +743,11 @@ class OSSession : public Module
|
||||
if (!session_limit || !u->server || u->server->IsULined())
|
||||
return;
|
||||
|
||||
SessionService::SessionMap::iterator sit;
|
||||
try
|
||||
{
|
||||
sit = this->ss.FindSessionIterator(u->ip);
|
||||
}
|
||||
catch (const SocketException &)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
SessionService::SessionMap &sessions = this->ss.GetSessions();
|
||||
SessionService::SessionMap::iterator sit = this->ss.FindSessionIterator(u->ip);
|
||||
|
||||
if (sit == sessions.end())
|
||||
{
|
||||
Log(LOG_DEBUG) << "Tried to delete non-existant session: " << u->ip;
|
||||
return;
|
||||
}
|
||||
|
||||
Session *session = sit->second;
|
||||
|
||||
|
||||
@@ -149,14 +149,9 @@ class SOCKS5ProxyConnect : public ProxyConnect, public BinarySocket
|
||||
sockaddrs target_addr;
|
||||
char buf[4 + sizeof(target_addr.sa4.sin_addr.s_addr) + sizeof(target_addr.sa4.sin_port)];
|
||||
int ptr = 0;
|
||||
try
|
||||
{
|
||||
target_addr.pton(AF_INET, target_ip, target_port);
|
||||
}
|
||||
catch (const SocketException &)
|
||||
{
|
||||
target_addr.pton(AF_INET, target_ip, target_port);
|
||||
if (!target_addr.valid())
|
||||
return;
|
||||
}
|
||||
|
||||
buf[ptr++] = 5; // Version
|
||||
buf[ptr++] = 1; // # of methods
|
||||
@@ -340,15 +335,10 @@ class ModuleProxyScan : public Module
|
||||
|
||||
/* At this time we only support IPv4 */
|
||||
sockaddrs user_ip;
|
||||
try
|
||||
{
|
||||
user_ip.pton(AF_INET, user->ip);
|
||||
}
|
||||
catch (const SocketException &)
|
||||
{
|
||||
user_ip.pton(AF_INET, user->ip);
|
||||
if (!user_ip.valid())
|
||||
/* User doesn't have a valid IPv4 IP (ipv6/spoof/etc) */
|
||||
return;
|
||||
}
|
||||
|
||||
if (!this->con_notice.empty() && !this->con_source.empty())
|
||||
{
|
||||
|
||||
@@ -151,6 +151,8 @@ class Packet : public Query
|
||||
|
||||
sockaddrs addrs;
|
||||
addrs.ntop(AF_INET, &a);
|
||||
if (!addrs.valid())
|
||||
throw SocketException("Invalid IP");
|
||||
|
||||
record.rdata = addrs.addr();
|
||||
break;
|
||||
@@ -167,6 +169,8 @@ class Packet : public Query
|
||||
|
||||
sockaddrs addrs;
|
||||
addrs.ntop(AF_INET6, &a);
|
||||
if (!addrs.valid())
|
||||
throw SocketException("Invalid IP");
|
||||
|
||||
record.rdata = addrs.addr();
|
||||
break;
|
||||
@@ -272,6 +276,8 @@ class Packet : public Query
|
||||
if (q.type == QUERY_PTR)
|
||||
{
|
||||
sockaddrs ip(q.name);
|
||||
if (!ip.valid())
|
||||
throw SocketException("Invalid IP");
|
||||
|
||||
if (q.name.find(':') != Anope::string::npos)
|
||||
{
|
||||
@@ -347,6 +353,8 @@ class Packet : public Query
|
||||
throw SocketException("Unable to pack packet");
|
||||
|
||||
sockaddrs a(rr.rdata);
|
||||
if (!a.valid())
|
||||
throw SocketException("Invalid IP");
|
||||
|
||||
s = htons(4);
|
||||
memcpy(&output[pos], &s, 2);
|
||||
@@ -362,6 +370,8 @@ class Packet : public Query
|
||||
throw SocketException("Unable to pack packet");
|
||||
|
||||
sockaddrs a(rr.rdata);
|
||||
if (!a.valid())
|
||||
throw SocketException("Invalid IP");
|
||||
|
||||
s = htons(16);
|
||||
memcpy(&output[pos], &s, 2);
|
||||
|
||||
+2
-7
@@ -134,15 +134,10 @@ class ModuleDNSBL : public Module
|
||||
|
||||
/* At this time we only support IPv4 */
|
||||
sockaddrs user_ip;
|
||||
try
|
||||
{
|
||||
user_ip.pton(AF_INET, user->ip);
|
||||
}
|
||||
catch (const SocketException &)
|
||||
{
|
||||
user_ip.pton(AF_INET, user->ip);
|
||||
if (!user_ip.valid())
|
||||
/* User doesn't have a valid IPv4 IP (ipv6/spoof/etc) */
|
||||
return;
|
||||
}
|
||||
|
||||
const unsigned long &ip = user_ip.sa4.sin_addr.s_addr;
|
||||
unsigned long reverse_ip = (ip << 24) | ((ip & 0xFF00) << 8) | ((ip & 0xFF0000) >> 8) | (ip >> 24);
|
||||
|
||||
@@ -143,14 +143,15 @@ class BahamutIRCdProto : public IRCDProto
|
||||
return;
|
||||
|
||||
/* ZLine if we can instead */
|
||||
if (x->GetUser() == "*" && x->GetHost().find_first_not_of("0123456789:.") == Anope::string::npos)
|
||||
try
|
||||
if (x->GetUser() == "*")
|
||||
{
|
||||
sockaddrs a(x->GetHost());
|
||||
if (a.valid())
|
||||
{
|
||||
sockaddrs(x->GetHost());
|
||||
IRCD->SendSZLineDel(x);
|
||||
return;
|
||||
}
|
||||
catch (const SocketException &) { }
|
||||
}
|
||||
|
||||
UplinkSocket::Message() << "RAKILL " << x->GetHost() << " " << x->GetUser();
|
||||
}
|
||||
@@ -214,14 +215,15 @@ class BahamutIRCdProto : public IRCDProto
|
||||
}
|
||||
|
||||
/* ZLine if we can instead */
|
||||
if (x->GetUser() == "*" && x->GetHost().find_first_not_of("0123456789:.") == Anope::string::npos)
|
||||
try
|
||||
if (x->GetUser() == "*")
|
||||
{
|
||||
sockaddrs a(x->GetHost());
|
||||
if (a.valid())
|
||||
{
|
||||
sockaddrs(x->GetHost());
|
||||
IRCD->SendSZLine(u, x);
|
||||
return;
|
||||
}
|
||||
catch (const SocketException &) { }
|
||||
}
|
||||
|
||||
// Calculate the time left before this would expire, capping it at 2 days
|
||||
time_t timeleft = x->expires - Anope::CurTime;
|
||||
|
||||
@@ -80,14 +80,15 @@ class InspIRCdProto : public IRCDProto
|
||||
return;
|
||||
|
||||
/* ZLine if we can instead */
|
||||
if (x->GetUser() == "*" && x->GetHost().find_first_not_of("0123456789:.") == Anope::string::npos)
|
||||
try
|
||||
if (x->GetUser() == "*")
|
||||
{
|
||||
sockaddrs a(x->GetHost());
|
||||
if (a.valid())
|
||||
{
|
||||
sockaddrs(x->GetHost());
|
||||
IRCD->SendSZLineDel(x);
|
||||
return;
|
||||
}
|
||||
catch (const SocketException &) { }
|
||||
}
|
||||
|
||||
UplinkSocket::Message(OperServ) << "GLINE " << x->mask;
|
||||
}
|
||||
@@ -134,14 +135,15 @@ class InspIRCdProto : public IRCDProto
|
||||
}
|
||||
|
||||
/* ZLine if we can instead */
|
||||
if (x->GetUser() == "*" && x->GetHost().find_first_not_of("0123456789:.") == Anope::string::npos)
|
||||
try
|
||||
if (x->GetUser() == "*")
|
||||
{
|
||||
sockaddrs a(x->GetHost());
|
||||
if (a.valid())
|
||||
{
|
||||
sockaddrs(x->GetHost());
|
||||
IRCD->SendSZLine(u, x);
|
||||
return;
|
||||
}
|
||||
catch (const SocketException &) { }
|
||||
}
|
||||
|
||||
// Calculate the time left before this would expire, capping it at 2 days
|
||||
time_t timeleft = x->expires - Anope::CurTime;
|
||||
|
||||
@@ -180,14 +180,15 @@ class InspIRCd12Proto : public IRCDProto
|
||||
}
|
||||
|
||||
/* ZLine if we can instead */
|
||||
if (x->GetUser() == "*" && x->GetHost().find_first_not_of("0123456789:.") == Anope::string::npos)
|
||||
try
|
||||
if (x->GetUser() == "*")
|
||||
{
|
||||
sockaddrs addr(x->GetHost());
|
||||
if (addr.valid())
|
||||
{
|
||||
sockaddrs(x->GetHost());
|
||||
IRCD->SendSZLine(u, x);
|
||||
return;
|
||||
}
|
||||
catch (const SocketException &) { }
|
||||
}
|
||||
|
||||
SendAddLine("G", x->GetUser() + "@" + x->GetHost(), timeleft, x->by, x->GetReason());
|
||||
}
|
||||
|
||||
+13
-15
@@ -46,14 +46,15 @@ class UnrealIRCdProto : public IRCDProto
|
||||
return;
|
||||
|
||||
/* ZLine if we can instead */
|
||||
if (x->GetUser() == "*" && x->GetHost().find_first_not_of("0123456789:.") == Anope::string::npos)
|
||||
try
|
||||
if (x->GetUser() == "*")
|
||||
{
|
||||
sockaddrs a(x->GetHost());
|
||||
if (a.valid())
|
||||
{
|
||||
sockaddrs(x->GetHost());
|
||||
IRCD->SendSZLineDel(x);
|
||||
return;
|
||||
}
|
||||
catch (const SocketException &) { }
|
||||
}
|
||||
|
||||
UplinkSocket::Message() << "TKL - G " << x->GetUser() << " " << x->GetHost() << " " << x->by;
|
||||
}
|
||||
@@ -108,14 +109,15 @@ class UnrealIRCdProto : public IRCDProto
|
||||
}
|
||||
|
||||
/* ZLine if we can instead */
|
||||
if (x->GetUser() == "*" && x->GetHost().find_first_not_of("0123456789:.") == Anope::string::npos)
|
||||
try
|
||||
if (x->GetUser() == "*")
|
||||
{
|
||||
sockaddrs a(x->GetHost());
|
||||
if (a.valid())
|
||||
{
|
||||
sockaddrs(x->GetHost());
|
||||
IRCD->SendSZLine(u, x);
|
||||
return;
|
||||
}
|
||||
catch (const SocketException &) { }
|
||||
}
|
||||
|
||||
// Calculate the time left before this would expire, capping it at 2 days
|
||||
time_t timeleft = x->expires - Anope::CurTime;
|
||||
@@ -786,13 +788,9 @@ struct IRCDMessageNick : IRCDMessage
|
||||
Anope::string decoded_ip;
|
||||
Anope::B64Decode(params[9], decoded_ip);
|
||||
|
||||
try
|
||||
{
|
||||
sockaddrs ip_addr;
|
||||
ip_addr.ntop(params[9].length() == 8 ? AF_INET : AF_INET6, decoded_ip.c_str());
|
||||
ip = ip_addr.addr();
|
||||
}
|
||||
catch (const SocketException &ex) { }
|
||||
sockaddrs ip_addr;
|
||||
ip_addr.ntop(params[9].length() == 8 ? AF_INET : AF_INET6, decoded_ip.c_str());
|
||||
ip = ip_addr.addr();
|
||||
}
|
||||
|
||||
Anope::string vhost = params[8];
|
||||
|
||||
@@ -43,10 +43,7 @@ class SGLineManager : public XLineManager
|
||||
if (x->regex)
|
||||
{
|
||||
Anope::string uh = u->GetIdent() + "@" + u->host, nuhr = u->nick + "!" + uh + "#" + u->realname;
|
||||
if (x->regex->Matches(uh) || x->regex->Matches(nuhr))
|
||||
return true;
|
||||
|
||||
return false;
|
||||
return x->regex->Matches(uh) || x->regex->Matches(nuhr);
|
||||
}
|
||||
|
||||
if (!x->GetNick().empty() && !Anope::Match(u->nick, x->GetNick()))
|
||||
@@ -60,14 +57,8 @@ class SGLineManager : public XLineManager
|
||||
|
||||
if (x->GetHost().find('/') != Anope::string::npos)
|
||||
{
|
||||
try
|
||||
{
|
||||
cidr cidr_ip(x->GetHost());
|
||||
sockaddrs ip(u->ip);
|
||||
if (cidr_ip.match(ip))
|
||||
return true;
|
||||
}
|
||||
catch (const SocketException &) { }
|
||||
if (cidr(x->GetHost()).match(sockaddrs(u->ip)))
|
||||
return true;
|
||||
}
|
||||
|
||||
if (x->GetHost().empty() || Anope::Match(u->host, x->GetHost()) || Anope::Match(u->ip, x->GetHost()))
|
||||
|
||||
+1
-1
@@ -82,7 +82,7 @@ int ci::ci_char_traits::compare(const char *str1, const char *str2, size_t n)
|
||||
|
||||
const char *ci::ci_char_traits::find(const char *s1, int n, char c)
|
||||
{
|
||||
while (n-- > 0 && case_map_upper[static_cast<unsigned char>(*s1)] != static_cast<unsigned char>(c))
|
||||
while (n-- > 0 && case_map_upper[static_cast<unsigned char>(*s1)] != case_map_upper[static_cast<unsigned char>(c)])
|
||||
++s1;
|
||||
return n >= 0 ? s1 : NULL;
|
||||
}
|
||||
|
||||
+2
-6
@@ -707,12 +707,8 @@ Anope::string Anope::Resolve(const Anope::string &host, int type)
|
||||
{
|
||||
sockaddrs addr;
|
||||
memcpy(&addr, addrresult->ai_addr, addrresult->ai_addrlen);
|
||||
try
|
||||
{
|
||||
result = addr.addr();
|
||||
Log(LOG_DEBUG_2) << "Resolver: " << host << " -> " << result;
|
||||
}
|
||||
catch (const SocketException &) { }
|
||||
result = addr.addr();
|
||||
Log(LOG_DEBUG_2) << "Resolver: " << host << " -> " << result;
|
||||
|
||||
freeaddrinfo(addrresult);
|
||||
}
|
||||
|
||||
+4
-5
@@ -671,12 +671,12 @@ Entry::Entry(const Anope::string &m, const Anope::string &fh) : name(m), mask(fh
|
||||
{
|
||||
const Anope::string &cidr_ip = this->host.substr(0, sl),
|
||||
&cidr_range = this->host.substr(sl + 1);
|
||||
|
||||
sockaddrs addr(cidr_ip);
|
||||
|
||||
try
|
||||
{
|
||||
sockaddrs addr(cidr_ip);
|
||||
/* If we got here, cidr_ip is a valid ip */
|
||||
|
||||
if (cidr_range.is_pos_number_only())
|
||||
if (addr.valid() && cidr_range.is_pos_number_only())
|
||||
{
|
||||
this->cidr_len = convertTo<unsigned short>(cidr_range);
|
||||
/* If we got here, cidr_len is a valid number.
|
||||
@@ -689,7 +689,6 @@ Entry::Entry(const Anope::string &m, const Anope::string &fh) : name(m), mask(fh
|
||||
Log(LOG_DEBUG) << "Ban " << this->mask << " has cidr " << this->cidr_len;
|
||||
}
|
||||
}
|
||||
catch (const SocketException &) { }
|
||||
catch (const ConvertException &) { }
|
||||
}
|
||||
}
|
||||
|
||||
+52
-33
@@ -31,7 +31,7 @@ SocketIO NormalSocketIO;
|
||||
sockaddrs::sockaddrs(const Anope::string &address)
|
||||
{
|
||||
this->clear();
|
||||
if (!address.empty())
|
||||
if (!address.empty() && address.find_first_not_of_ci("0123456789abcdef.:") == Anope::string::npos)
|
||||
this->pton(address.find(':') != Anope::string::npos ? AF_INET6 : AF_INET, address);
|
||||
}
|
||||
|
||||
@@ -72,28 +72,28 @@ int sockaddrs::port() const
|
||||
|
||||
Anope::string sockaddrs::addr() const
|
||||
{
|
||||
char address[INET6_ADDRSTRLEN + 1] = "";
|
||||
char address[INET6_ADDRSTRLEN];
|
||||
|
||||
switch (sa.sa_family)
|
||||
{
|
||||
case AF_INET:
|
||||
if (!inet_ntop(AF_INET, &sa4.sin_addr, address, sizeof(address)))
|
||||
throw SocketException(Anope::LastError());
|
||||
return address;
|
||||
if (inet_ntop(AF_INET, &sa4.sin_addr, address, sizeof(address)))
|
||||
return address;
|
||||
break;
|
||||
case AF_INET6:
|
||||
if (!inet_ntop(AF_INET6, &sa6.sin6_addr, address, sizeof(address)))
|
||||
throw SocketException(Anope::LastError());
|
||||
return address;
|
||||
if (inet_ntop(AF_INET6, &sa6.sin6_addr, address, sizeof(address)))
|
||||
return address;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return address;
|
||||
return "";
|
||||
}
|
||||
|
||||
bool sockaddrs::operator()() const
|
||||
{
|
||||
return this->sa.sa_family != 0;
|
||||
return valid();
|
||||
}
|
||||
|
||||
bool sockaddrs::operator==(const sockaddrs &other) const
|
||||
@@ -115,35 +115,37 @@ bool sockaddrs::operator==(const sockaddrs &other) const
|
||||
|
||||
void sockaddrs::pton(int type, const Anope::string &address, int pport)
|
||||
{
|
||||
this->clear();
|
||||
|
||||
switch (type)
|
||||
{
|
||||
case AF_INET:
|
||||
{
|
||||
int i = inet_pton(type, address.c_str(), &sa4.sin_addr);
|
||||
if (i == 0)
|
||||
throw SocketException("Invalid IP");
|
||||
else if (i <= -1)
|
||||
throw SocketException("Invalid IP: " + Anope::LastError());
|
||||
sa4.sin_family = type;
|
||||
sa4.sin_port = htons(pport);
|
||||
return;
|
||||
if (i <= 0)
|
||||
this->clear();
|
||||
else
|
||||
{
|
||||
sa4.sin_family = type;
|
||||
sa4.sin_port = htons(pport);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case AF_INET6:
|
||||
{
|
||||
int i = inet_pton(type, address.c_str(), &sa6.sin6_addr);
|
||||
if (i == 0)
|
||||
throw SocketException("Invalid IP");
|
||||
else if (i <= -1)
|
||||
throw SocketException("Invalid IP: " + Anope::LastError());
|
||||
sa6.sin6_family = type;
|
||||
sa6.sin6_port = htons(pport);
|
||||
return;
|
||||
if (i <= 0)
|
||||
this->clear();
|
||||
else
|
||||
{
|
||||
sa6.sin6_family = type;
|
||||
sa6.sin6_port = htons(pport);
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
throw CoreException("Invalid socket type");
|
||||
}
|
||||
|
||||
void sockaddrs::ntop(int type, const void *src)
|
||||
@@ -151,7 +153,10 @@ void sockaddrs::ntop(int type, const void *src)
|
||||
char buf[INET6_ADDRSTRLEN];
|
||||
|
||||
if (inet_ntop(type, src, buf, sizeof(buf)) != buf)
|
||||
throw SocketException("Invalid addr");
|
||||
{
|
||||
this->clear();
|
||||
return;
|
||||
}
|
||||
|
||||
switch (type)
|
||||
{
|
||||
@@ -167,7 +172,12 @@ void sockaddrs::ntop(int type, const void *src)
|
||||
break;
|
||||
}
|
||||
|
||||
throw CoreException("Invalid socket type");
|
||||
this->clear();
|
||||
}
|
||||
|
||||
bool sockaddrs::valid() const
|
||||
{
|
||||
return size() != 0;
|
||||
}
|
||||
|
||||
cidr::cidr(const Anope::string &ip)
|
||||
@@ -185,11 +195,15 @@ cidr::cidr(const Anope::string &ip)
|
||||
{
|
||||
Anope::string real_ip = ip.substr(0, sl);
|
||||
Anope::string cidr_range = ip.substr(sl + 1);
|
||||
if (!cidr_range.is_pos_number_only())
|
||||
throw SocketException("Invalid CIDR range");
|
||||
|
||||
this->cidr_ip = real_ip;
|
||||
this->cidr_len = convertTo<unsigned int>(cidr_range);
|
||||
this->cidr_len = ipv6 ? 128 : 32;
|
||||
try
|
||||
{
|
||||
if (cidr_range.is_pos_number_only())
|
||||
this->cidr_len = convertTo<unsigned int>(cidr_range);
|
||||
}
|
||||
catch (const ConvertException &) { }
|
||||
this->addr.pton(ipv6 ? AF_INET6 : AF_INET, real_ip);
|
||||
}
|
||||
}
|
||||
@@ -209,7 +223,7 @@ Anope::string cidr::mask() const
|
||||
|
||||
bool cidr::match(const sockaddrs &other)
|
||||
{
|
||||
if (this->addr.sa.sa_family != other.sa.sa_family)
|
||||
if (!valid() || !other.valid() || this->addr.sa.sa_family != other.sa.sa_family)
|
||||
return false;
|
||||
|
||||
const unsigned char *ip, *their_ip;
|
||||
@@ -232,7 +246,7 @@ bool cidr::match(const sockaddrs &other)
|
||||
their_ip = reinterpret_cast<const unsigned char *>(&other.sa6.sin6_addr);
|
||||
break;
|
||||
default:
|
||||
throw SocketException("Invalid address type");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (memcmp(ip, their_ip, byte))
|
||||
@@ -290,6 +304,11 @@ bool cidr::operator!=(const cidr &other) const
|
||||
return !(*this == other);
|
||||
}
|
||||
|
||||
bool cidr::valid() const
|
||||
{
|
||||
return this->addr.valid();
|
||||
}
|
||||
|
||||
size_t cidr::hash::operator()(const cidr &s) const
|
||||
{
|
||||
switch (s.addr.sa.sa_family)
|
||||
|
||||
+10
-9
@@ -22,6 +22,7 @@
|
||||
#include "config.h"
|
||||
#include "opertype.h"
|
||||
#include "language.h"
|
||||
#include "sockets.h"
|
||||
|
||||
user_map UserListByNick, UserListByUID;
|
||||
|
||||
@@ -753,24 +754,24 @@ bool User::Quitting() const
|
||||
Anope::string User::Mask() const
|
||||
{
|
||||
Anope::string mask;
|
||||
Anope::string mident = this->GetIdent();
|
||||
Anope::string mhost = this->GetDisplayedHost();
|
||||
const Anope::string &mident = this->GetIdent();
|
||||
const Anope::string &mhost = this->GetDisplayedHost();
|
||||
|
||||
if (mident[0] == '~')
|
||||
mask = "*" + mident + "@";
|
||||
else
|
||||
mask = mident + "@";
|
||||
|
||||
size_t dot;
|
||||
/* To make sure this is an IP, make sure the host contains only numbers and dots, and check to make sure it only contains 3 dots */
|
||||
if (mhost.find_first_not_of("0123456789.") == Anope::string::npos && (dot = mhost.find('.')) != Anope::string::npos && (dot = mhost.find('.', dot + 1)) != Anope::string::npos && (dot = mhost.find('.', dot + 1)) != Anope::string::npos && mhost.find('.', dot + 1) == Anope::string::npos)
|
||||
{ /* IP addr */
|
||||
dot = mhost.find('.');
|
||||
mask += mhost.substr(0, dot) + ".*";
|
||||
sockaddrs addr(mhost);
|
||||
if (addr.valid() && addr.sa.sa_family == AF_INET)
|
||||
{
|
||||
size_t dot = mhost.find('.');
|
||||
mask += mhost.substr(0, dot) + (dot == Anope::string::npos ? "" : ".*");
|
||||
}
|
||||
else
|
||||
{
|
||||
if ((dot = mhost.find('.')) != Anope::string::npos && mhost.find('.', dot + 1) != Anope::string::npos)
|
||||
size_t dot = mhost.find('.');
|
||||
if (dot != Anope::string::npos && mhost.find('.', dot + 1) != Anope::string::npos)
|
||||
mask += "*" + mhost.substr(dot);
|
||||
else
|
||||
mask += mhost;
|
||||
|
||||
Reference in New Issue
Block a user