diff options
author | Adam <Adam@anope.org> | 2013-05-08 09:50:43 -0400 |
---|---|---|
committer | Adam <Adam@anope.org> | 2013-05-08 09:50:43 -0400 |
commit | 9b07e163c0e1ceed30e72aead2338b47ef2da1b2 (patch) | |
tree | 4c13bd545846700a58c5526c3e4e9a6fdf0afc87 | |
parent | 6859decfb8ed0430e946ff81eca4f9da879f69c9 (diff) |
Make sockaddrs/cidr not throw on invalid ips to give us an easier/cheaper way to test for a valid IP
-rw-r--r-- | include/sockets.h | 3 | ||||
-rw-r--r-- | modules/commands/os_dns.cpp | 19 | ||||
-rw-r--r-- | modules/commands/os_session.cpp | 176 | ||||
-rw-r--r-- | modules/extra/m_proxyscan.cpp | 18 | ||||
-rw-r--r-- | modules/m_dns.cpp | 10 | ||||
-rw-r--r-- | modules/m_dnsbl.cpp | 9 | ||||
-rw-r--r-- | modules/protocol/bahamut.cpp | 18 | ||||
-rw-r--r-- | modules/protocol/inspircd11.cpp | 18 | ||||
-rw-r--r-- | modules/protocol/inspircd12.cpp | 9 | ||||
-rw-r--r-- | modules/protocol/unreal.cpp | 28 | ||||
-rw-r--r-- | modules/pseudoclients/operserv.cpp | 15 | ||||
-rw-r--r-- | src/hashcomp.cpp | 2 | ||||
-rw-r--r-- | src/misc.cpp | 8 | ||||
-rw-r--r-- | src/modes.cpp | 9 | ||||
-rw-r--r-- | src/sockets.cpp | 85 | ||||
-rw-r--r-- | src/users.cpp | 19 |
16 files changed, 207 insertions, 239 deletions
diff --git a/include/sockets.h b/include/sockets.h index 0e490ac24..8b1abe5c2 100644 --- a/include/sockets.h +++ b/include/sockets.h @@ -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; diff --git a/modules/commands/os_dns.cpp b/modules/commands/os_dns.cpp index 698fa0e1a..32e6be59d 100644 --- a/modules/commands/os_dns.cpp +++ b/modules/commands/os_dns.cpp @@ -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]); diff --git a/modules/commands/os_session.cpp b/modules/commands/os_session.cpp index 259c9bdd0..656e046af 100644 --- a/modules/commands/os_session.cpp +++ b/modules/commands/os_session.cpp @@ -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 - { - Session* &session = this->ss.FindOrCreateSession(u->ip); + cidr u_ip(u->ip); + if (!u_ip.valid()) + return; + + Session* &session = this->ss.FindOrCreateSession(u_ip); - if (session) + 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; - } + 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; + /* 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 (kill && !exempt) + { + if (OperServ) { - if (OperServ) + if (!sle_reason.empty()) { - 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); + 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"); - } + ++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"); } } - else - { - session = new Session(u->ip, u->ip.find(':') != Anope::string::npos ? ipv6_cidr : ipv4_cidr); - } } - 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; diff --git a/modules/extra/m_proxyscan.cpp b/modules/extra/m_proxyscan.cpp index da2ab5692..4e2a6bd88 100644 --- a/modules/extra/m_proxyscan.cpp +++ b/modules/extra/m_proxyscan.cpp @@ -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()) { diff --git a/modules/m_dns.cpp b/modules/m_dns.cpp index 9b0157069..ea64da92f 100644 --- a/modules/m_dns.cpp +++ b/modules/m_dns.cpp @@ -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); diff --git a/modules/m_dnsbl.cpp b/modules/m_dnsbl.cpp index ea1f1d9f6..08d4e365d 100644 --- a/modules/m_dnsbl.cpp +++ b/modules/m_dnsbl.cpp @@ -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); diff --git a/modules/protocol/bahamut.cpp b/modules/protocol/bahamut.cpp index 6aa097433..f485bd62c 100644 --- a/modules/protocol/bahamut.cpp +++ b/modules/protocol/bahamut.cpp @@ -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; diff --git a/modules/protocol/inspircd11.cpp b/modules/protocol/inspircd11.cpp index 12a22e724..f978417f6 100644 --- a/modules/protocol/inspircd11.cpp +++ b/modules/protocol/inspircd11.cpp @@ -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; diff --git a/modules/protocol/inspircd12.cpp b/modules/protocol/inspircd12.cpp index c3fa04b85..d46d8733e 100644 --- a/modules/protocol/inspircd12.cpp +++ b/modules/protocol/inspircd12.cpp @@ -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()); } diff --git a/modules/protocol/unreal.cpp b/modules/protocol/unreal.cpp index 4186ee5d0..ea5da3dbe 100644 --- a/modules/protocol/unreal.cpp +++ b/modules/protocol/unreal.cpp @@ -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]; diff --git a/modules/pseudoclients/operserv.cpp b/modules/pseudoclients/operserv.cpp index 0720110cb..a451813ef 100644 --- a/modules/pseudoclients/operserv.cpp +++ b/modules/pseudoclients/operserv.cpp @@ -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())) diff --git a/src/hashcomp.cpp b/src/hashcomp.cpp index 3c6430330..7b3b906c2 100644 --- a/src/hashcomp.cpp +++ b/src/hashcomp.cpp @@ -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; } diff --git a/src/misc.cpp b/src/misc.cpp index 29d3a7121..b446ea711 100644 --- a/src/misc.cpp +++ b/src/misc.cpp @@ -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); } diff --git a/src/modes.cpp b/src/modes.cpp index 9481f570e..1238df17d 100644 --- a/src/modes.cpp +++ b/src/modes.cpp @@ -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 &) { } } } diff --git a/src/sockets.cpp b/src/sockets.cpp index b30932935..8729303bf 100644 --- a/src/sockets.cpp +++ b/src/sockets.cpp @@ -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) diff --git a/src/users.cpp b/src/users.cpp index 58f586e27..bd376f6a1 100644 --- a/src/users.cpp +++ b/src/users.cpp @@ -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; |