diff options
| author | Adam <Adam@anope.org> | 2010-09-09 23:43:11 -0400 |
|---|---|---|
| committer | Adam <Adam@anope.org> | 2010-09-09 23:43:11 -0400 |
| commit | 46813ccb8c6ab572b8a9ff0a39afb1d92dc4482b (patch) | |
| tree | 562da502a102230ce207bbe921fdc978ee71e20c /modules | |
| parent | fdd196e50b4616ac377bd0ee0ae5ce6c57b657ee (diff) | |
Added an asynchronous DNS system and m_dnsbl, which checks clients against DNS blacklists.
Rewrote internal handling of IPs, we now properly support users using IPv6.
Fixed a few problems with the UnrealIRCd protocol module.
Diffstat (limited to 'modules')
| -rw-r--r-- | modules/core/os_defcon.cpp | 2 | ||||
| -rw-r--r-- | modules/extra/m_dnsbl.cpp | 123 | ||||
| -rw-r--r-- | modules/protocol/bahamut.cpp | 5 | ||||
| -rw-r--r-- | modules/protocol/inspircd11.cpp | 7 | ||||
| -rw-r--r-- | modules/protocol/inspircd12.cpp | 5 | ||||
| -rw-r--r-- | modules/protocol/inspircd20.cpp | 5 | ||||
| -rw-r--r-- | modules/protocol/ratbox.cpp | 5 | ||||
| -rw-r--r-- | modules/protocol/unreal32.cpp | 21 | ||||
| -rw-r--r-- | modules/socketengines/m_socketengine_epoll.cpp | 20 | ||||
| -rw-r--r-- | modules/socketengines/m_socketengine_select.cpp | 16 |
10 files changed, 171 insertions, 38 deletions
diff --git a/modules/core/os_defcon.cpp b/modules/core/os_defcon.cpp index 009d34dda..711046beb 100644 --- a/modules/core/os_defcon.cpp +++ b/modules/core/os_defcon.cpp @@ -274,7 +274,7 @@ class OSDefcon : public Module void OnUserConnect(User *u) { Session *session = findsession(u->host); - Exception *exception = find_hostip_exception(u->host, u->hostip); + Exception *exception = find_hostip_exception(u->host, u->ip.addr()); if (CheckDefCon(DEFCON_REDUCE_SESSION) && !exception) { diff --git a/modules/extra/m_dnsbl.cpp b/modules/extra/m_dnsbl.cpp new file mode 100644 index 000000000..cecff84a8 --- /dev/null +++ b/modules/extra/m_dnsbl.cpp @@ -0,0 +1,123 @@ +/* + * (C) 2003-2010 Anope Team + * Contact us at team@anope.org + * + * Please read COPYING and README for further details. + */ + +#include "module.h" + +struct Blacklist +{ + Anope::string name; + time_t bantime; + Anope::string reason; + + Blacklist(const Anope::string &n, time_t b, const Anope::string &r) : name(n), bantime(b), reason(r) { } +}; + +class DNSBLResolver : public DNSRequest +{ + dynamic_reference<User> user; + Blacklist blacklist; + public: + DNSBLResolver(User *u, const Blacklist &b, const Anope::string &host) : DNSRequest(host, DNS_QUERY_A, true), user(u), blacklist(b) { } + + void OnLookupComplete(const DNSRecord *) + { + if (!user || !SGLine) + return; + + Anope::string reason = this->blacklist.reason; + reason = reason.replace_all_ci("%i", user->ip.addr()); + reason = reason.replace_all_ci("%h", user->host); + + XLine *x = SGLine->Add(NULL, NULL, Anope::string("*@") + user->host, time(NULL) + this->blacklist.bantime, reason); + if (x) + { + static Command command_akill("AKILL", 0); + command_akill.service = OperServ; + Log(LOG_COMMAND, OperServ, &command_akill) << "for " << user->GetMask() << " (Listed in " << this->blacklist.name << ")"; + /* If AkillOnAdd is disabled send it anyway, noone wants bots around... */ + if (!Config->AkillOnAdd) + ircdproto->SendAkill(x); + } + } +}; + +class ModuleDNSBL : public Module +{ + std::vector<Blacklist> blacklists; + bool check_on_connect; + bool check_on_netburst; + + public: + ModuleDNSBL(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator) + { + OnReload(false); + + Implementation i[] = { I_OnReload, I_OnPreUserConnect }; + ModuleManager::Attach(i, this, 2); + } + + void OnReload(bool) + { + ConfigReader config; + + this->check_on_connect = config.ReadFlag("m_dnsbl", "check_on_connect", "no", 0); + this->check_on_netburst = config.ReadFlag("m_dnsbl", "check_on_netburst", "no", 0); + + this->blacklists.clear(); + for (int i = 0, num = config.Enumerate("blacklist"); i < num; ++i) + { + Anope::string bname = config.ReadValue("blacklist", "name", "", i); + if (bname.empty()) + continue; + Anope::string sbantime = config.ReadValue("blacklist", "time", "4h", i); + time_t bantime = dotime(sbantime); + if (bantime < 0) + bantime = 9000; + Anope::string reason = config.ReadValue("blacklist", "reason", "", i); + + this->blacklists.push_back(Blacklist(bname, bantime, reason)); + } + } + + EventReturn OnPreUserConnect(User *u) + { + if (!this->check_on_connect && !Me->IsSynced()) + return EVENT_CONTINUE; + if (!this->check_on_netburst && !u->server->IsSynced()) + return EVENT_CONTINUE; + /* At this time we only support IPv4 */ + if (u->ip.sa.sa_family != AF_INET) + return EVENT_CONTINUE; + + unsigned long ip = u->ip.sa4.sin_addr.s_addr; + unsigned long reverse_ip = ((ip & 0xFF) << 24) | ((ip & 0xFF00) << 8) | ((ip & 0xFF0000) >> 8) | ((ip & 0xFF000000) >> 24); + + sockaddrs user_ip; + user_ip.sa4.sin_family = AF_INET; + user_ip.sa4.sin_addr.s_addr = reverse_ip; + + for (unsigned i = 0; i < this->blacklists.size(); ++i) + { + const Blacklist &b = this->blacklists[i]; + + try + { + Anope::string dnsbl_host = user_ip.addr() + "." + b.name; + new DNSBLResolver(u, b, dnsbl_host); + } + catch (const SocketException &ex) + { + Log() << "Resolver: " << ex.GetReason(); + } + } + + return EVENT_CONTINUE; + } +}; + +MODULE_INIT(ModuleDNSBL) + diff --git a/modules/protocol/bahamut.cpp b/modules/protocol/bahamut.cpp index ae65bd364..9938d33c7 100644 --- a/modules/protocol/bahamut.cpp +++ b/modules/protocol/bahamut.cpp @@ -34,7 +34,6 @@ IRCDVar myIrcd[] = { 0, /* vidents */ 1, /* svshold */ 1, /* time stamp on mode */ - 1, /* NICKIP */ 0, /* O:LINE */ 1, /* UMODE */ 0, /* VHOST ON NICK */ @@ -451,7 +450,7 @@ int anope_event_nick(const Anope::string &source, int ac, const char **av) if (ac != 2) { - user = do_nick(source, av[0], av[4], av[5], av[6], av[9], Anope::string(av[2]).is_pos_number_only() ? convertTo<time_t>(av[2]) : 0, Anope::string(av[8]).is_pos_number_only() ? convertTo<uint32>(av[8]) : 0, "", ""); + user = do_nick(source, av[0], av[4], av[5], av[6], av[9], Anope::string(av[2]).is_pos_number_only() ? convertTo<time_t>(av[2]) : 0, av[8], "", ""); if (user) { UserSetInternalModes(user, 1, &av[3]); @@ -467,7 +466,7 @@ int anope_event_nick(const Anope::string &source, int ac, const char **av) } } else - do_nick(source, av[0], "", "", "", "", Anope::string(av[1]).is_pos_number_only() ? convertTo<time_t>(av[1]) : 0, 0, "", ""); + do_nick(source, av[0], "", "", "", "", Anope::string(av[1]).is_pos_number_only() ? convertTo<time_t>(av[1]) : 0, "", "", ""); return MOD_CONT; } diff --git a/modules/protocol/inspircd11.cpp b/modules/protocol/inspircd11.cpp index ebbedd362..042814465 100644 --- a/modules/protocol/inspircd11.cpp +++ b/modules/protocol/inspircd11.cpp @@ -35,7 +35,6 @@ IRCDVar myIrcd[] = { 1, /* vidents */ 1, /* svshold */ 0, /* time stamp on mode */ - 0, /* NICKIP */ 1, /* O:LINE */ 1, /* UMODE */ 1, /* VHOST ON NICK */ @@ -714,11 +713,9 @@ int anope_event_nick(const Anope::string &source, int ac, const char **av) { time_t ts = Anope::string(av[0]).is_pos_number_only() ? convertTo<time_t>(av[0]) : 0; - user = do_nick("", av[1], av[4], av[2], source, av[7], ts, 0, av[3], ""); + user = do_nick("", av[1], av[4], av[2], source, av[7], ts, av[6], av[3], ""); if (user) { - user->hostip = av[6]; - UserSetInternalModes(user, 1, &av[5]); user->SetCloakedHost(av[3]); @@ -735,7 +732,7 @@ int anope_event_nick(const Anope::string &source, int ac, const char **av) } } else - do_nick(source, av[0], "", "", "", "", 0, 0, "", ""); + do_nick(source, av[0], "", "", "", "", 0, "", "", ""); return MOD_CONT; } diff --git a/modules/protocol/inspircd12.cpp b/modules/protocol/inspircd12.cpp index 8b6c55907..0fec91e25 100644 --- a/modules/protocol/inspircd12.cpp +++ b/modules/protocol/inspircd12.cpp @@ -35,7 +35,6 @@ IRCDVar myIrcd[] = { 1, /* vidents */ 1, /* svshold */ 0, /* time stamp on mode */ - 0, /* NICKIP */ 0, /* O:LINE */ 1, /* UMODE */ 1, /* VHOST ON NICK */ @@ -725,7 +724,7 @@ int anope_event_sethost(const Anope::string &source, int ac, const char **av) int anope_event_nick(const Anope::string &source, int ac, const char **av) { - do_nick(source, av[0], "", "", "", "", 0, 0, "", ""); + do_nick(source, av[0], "", "", "", "", 0, "", "", ""); return MOD_CONT; } @@ -764,7 +763,7 @@ int anope_event_uid(const Anope::string &source, int ac, const char **av) } user = NULL; - user = do_nick("", av[2], av[5], av[3], s->GetName(), av[ac - 1], ts, 0, av[4], av[0]); + user = do_nick("", av[2], av[5], av[3], s->GetName(), av[ac - 1], ts, av[6], av[4], av[0]); if (user) { UserSetInternalModes(user, 1, &av[8]); diff --git a/modules/protocol/inspircd20.cpp b/modules/protocol/inspircd20.cpp index be7b7c760..4445b82b9 100644 --- a/modules/protocol/inspircd20.cpp +++ b/modules/protocol/inspircd20.cpp @@ -35,7 +35,6 @@ IRCDVar myIrcd[] = { 1, /* vidents */ 1, /* svshold */ 0, /* time stamp on mode */ - 0, /* NICKIP */ 0, /* O:LINE */ 1, /* UMODE */ 1, /* VHOST ON NICK */ @@ -722,7 +721,7 @@ int anope_event_sethost(const Anope::string &source, int ac, const char **av) int anope_event_nick(const Anope::string &source, int ac, const char **av) { - do_nick(source, av[0], "", "", "", "", 0, 0, "", ""); + do_nick(source, av[0], "", "", "", "", 0, "", "", ""); return MOD_CONT; } @@ -761,7 +760,7 @@ int anope_event_uid(const Anope::string &source, int ac, const char **av) } user = NULL; - user = do_nick("", av[2], av[5], av[3], s->GetName(), av[ac - 1], ts, 0, av[4], av[0]); + user = do_nick("", av[2], av[5], av[3], s->GetName(), av[ac - 1], ts, av[6], av[4], av[0]); if (user) { UserSetInternalModes(user, 1, &av[8]); diff --git a/modules/protocol/ratbox.cpp b/modules/protocol/ratbox.cpp index db5c4d5bd..d43a80b52 100644 --- a/modules/protocol/ratbox.cpp +++ b/modules/protocol/ratbox.cpp @@ -34,7 +34,6 @@ IRCDVar myIrcd[] = { 0, /* vidents */ 0, /* svshold */ 0, /* time stamp on mode */ - 0, /* NICKIP */ 0, /* UMODE */ 0, /* O:LINE */ 0, /* VHOST ON NICK */ @@ -405,7 +404,7 @@ int anope_event_nick(const Anope::string &source, int ac, const char **av) { Server *s = Server::Find(source); /* Source is always the server */ - user = do_nick("", av[0], av[4], av[5], s->GetName(), av[8], Anope::string(av[2]).is_pos_number_only() ? convertTo<time_t>(av[2]) : 0, 0, "*", av[7]); + user = do_nick("", av[0], av[4], av[5], s->GetName(), av[8], Anope::string(av[2]).is_pos_number_only() ? convertTo<time_t>(av[2]) : 0, av[6], "*", av[7]); if (user) { UserSetInternalModes(user, 1, &av[3]); @@ -421,7 +420,7 @@ int anope_event_nick(const Anope::string &source, int ac, const char **av) } } else if (ac == 2) - do_nick(source, av[0], "", "", "", "", Anope::string(av[1]).is_pos_number_only() ? convertTo<time_t>(av[1]) : 0, 0, "", ""); + do_nick(source, av[0], "", "", "", "", Anope::string(av[1]).is_pos_number_only() ? convertTo<time_t>(av[1]) : 0, "", "", ""); return MOD_CONT; } diff --git a/modules/protocol/unreal32.cpp b/modules/protocol/unreal32.cpp index 047f51b15..fb12892e2 100644 --- a/modules/protocol/unreal32.cpp +++ b/modules/protocol/unreal32.cpp @@ -34,7 +34,6 @@ IRCDVar myIrcd[] = { 1, /* vidents */ 1, /* svshold */ 1, /* time stamp on mode */ - 1, /* NICKIP */ 1, /* O:LINE */ 1, /* UMODE */ 1, /* VHOST ON NICK */ @@ -133,7 +132,7 @@ class UnrealIRCdProto : public IRCDProto time_t timeleft = x->Expires - time(NULL); if (timeleft > 172800) timeleft = 172800; - send_cmd("", "BD + G %s %s %s %ld %ld :%s", x->GetUser().c_str(), x->GetHost().c_str(), x->By.c_str(), static_cast<long>(time(NULL) + timeleft), static_cast<long>(x->Expires), x->Reason.c_str()); + send_cmd("", "BD + G %s %s %s %ld %ld :%s", x->GetUser().c_str(), x->GetHost().c_str(), x->By.c_str(), static_cast<long>(time(NULL) + timeleft), static_cast<long>(x->Created), x->Reason.c_str()); } void SendSVSKillInternal(const BotInfo *source, const User *user, const Anope::string &buf) @@ -175,7 +174,7 @@ class UnrealIRCdProto : public IRCDProto void SendClientIntroduction(const Anope::string &nick, const Anope::string &user, const Anope::string &host, const Anope::string &real, const Anope::string &modes, const Anope::string &) { EnforceQlinedNick(nick, Config->ServerName); - send_cmd("", "& %s 1 %ld %s %s %s 0 %s %s%s :%s", nick.c_str(), static_cast<long>(time(NULL)), user.c_str(), host.c_str(), Config->ServerName.c_str(), modes.c_str(), host.c_str(), myIrcd->nickip ? " *" : "", real.c_str()); + send_cmd("", "& %s 1 %ld %s %s %s 0 %s %s * :%s", nick.c_str(), static_cast<long>(time(NULL)), user.c_str(), host.c_str(), Config->ServerName.c_str(), modes.c_str(), host.c_str(), real.c_str()); } void SendKickInternal(const BotInfo *source, const Channel *chan, const User *user, const Anope::string &buf) @@ -860,11 +859,17 @@ int anope_event_nick(const Anope::string &source, int ac, const char **av) <codemastr> it's sent when a nick collision occurs - so we have to leave it around for now -TSL */ - do_nick(source, av[0], av[3], av[4], av[5], av[6], Anope::string(av[2]).is_pos_number_only() ? convertTo<time_t>(av[2]) : 0, 0, "*", ""); + do_nick(source, av[0], av[3], av[4], av[5], av[6], Anope::string(av[2]).is_pos_number_only() ? convertTo<time_t>(av[2]) : 0, "", "*", ""); } else if (ac == 11) { - user = do_nick(source, av[0], av[3], av[4], av[5], av[10], Anope::string(av[2]).is_pos_number_only() ? convertTo<time_t>(av[2]) : 0, ntohl(decode_ip(av[9])), av[8], ""); + Anope::string decoded_ip; + b64_decode(av[9], decoded_ip); + + sockaddrs ip; + ip.ntop(strlen(av[9]) == 8 ? AF_INET : AF_INET6, decoded_ip.c_str()); + + user = do_nick(source, av[0], av[3], av[4], av[5], av[10], Anope::string(av[2]).is_pos_number_only() ? convertTo<time_t>(av[2]) : 0, ip.addr(), av[8], ""); if (user) { UserSetInternalModes(user, 1, &av[7]); @@ -883,7 +888,7 @@ int anope_event_nick(const Anope::string &source, int ac, const char **av) else { /* NON NICKIP */ - user = do_nick(source, av[0], av[3], av[4], av[5], av[9], Anope::string(av[2]).is_pos_number_only() ? convertTo<time_t>(av[2]) : 0, 0, av[8], ""); + user = do_nick(source, av[0], av[3], av[4], av[5], av[9], Anope::string(av[2]).is_pos_number_only() ? convertTo<time_t>(av[2]) : 0, "", av[8], ""); if (user) { UserSetInternalModes(user, 1, &av[7]); @@ -901,7 +906,7 @@ int anope_event_nick(const Anope::string &source, int ac, const char **av) } } else - do_nick(source, av[0], "", "", "", "", Anope::string(av[1]).is_pos_number_only() ? convertTo<time_t>(av[1]) : 0, 0, "", ""); + do_nick(source, av[0], "", "", "", "", Anope::string(av[1]).is_pos_number_only() ? convertTo<time_t>(av[1]) : 0, "", "", ""); return MOD_CONT; } @@ -1136,7 +1141,7 @@ void moduleAddIRCDMsgs() Anope::AddMessage("PRIVMSG", anope_event_privmsg); Anope::AddMessage("!", anope_event_privmsg); Anope::AddMessage("QUIT", anope_event_quit); - Anope::AddMessage("),", anope_event_quit); + Anope::AddMessage(",", anope_event_quit); Anope::AddMessage("SERVER", anope_event_server); Anope::AddMessage("'", anope_event_server); Anope::AddMessage("SQUIT", anope_event_squit); diff --git a/modules/socketengines/m_socketengine_epoll.cpp b/modules/socketengines/m_socketengine_epoll.cpp index 5a2561b25..5edc40502 100644 --- a/modules/socketengines/m_socketengine_epoll.cpp +++ b/modules/socketengines/m_socketengine_epoll.cpp @@ -80,8 +80,11 @@ class SocketEngineEPoll : public SocketEngineBase --SocketCount; } - void MarkWriteable(Socket *s) + void MarkWritable(Socket *s) { + if (s->HasFlag(SF_WRITABLE)) + return; + epoll_event ev; memset(&ev, 0, sizeof(ev)); @@ -91,10 +94,15 @@ class SocketEngineEPoll : public SocketEngineBase if (epoll_ctl(EngineHandle, EPOLL_CTL_MOD, ev.data.fd, &ev) == -1) Log() << "Unable to mark fd " << ev.data.fd << " as writable in socketengine epoll: " << strerror(errno); + else + s->SetFlag(SF_WRITABLE); } - void ClearWriteable(Socket *s) + void ClearWriteble(Socket *s) { + if (!s->HasFlag(SF_WRITABLE)) + return; + epoll_event ev; memset(&ev, 0, sizeof(ev)); @@ -104,6 +112,8 @@ class SocketEngineEPoll : public SocketEngineBase if (epoll_ctl(EngineHandle, EPOLL_CTL_MOD, ev.data.fd, &ev) == -1) Log() << "Unable to mark fd " << ev.data.fd << " as unwritable in socketengine epoll: " << strerror(errno); + else + s->UnsetFlag(SF_WRITABLE); } void Process() @@ -150,7 +160,7 @@ class SocketEngineEPoll : public SocketEngineBase class ModuleSocketEngineEPoll : public Module { - SocketEngineEPoll *engine; + SocketEngineEPoll engine; public: ModuleSocketEngineEPoll(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator) @@ -159,13 +169,11 @@ class ModuleSocketEngineEPoll : public Module this->SetPermanent(true); this->SetType(SOCKETENGINE); - engine = new SocketEngineEPoll(); - SocketEngine = engine; + SocketEngine = &engine; } ~ModuleSocketEngineEPoll() { - delete engine; SocketEngine = NULL; } }; diff --git a/modules/socketengines/m_socketengine_select.cpp b/modules/socketengines/m_socketengine_select.cpp index e708693d2..b966820bd 100644 --- a/modules/socketengines/m_socketengine_select.cpp +++ b/modules/socketengines/m_socketengine_select.cpp @@ -41,14 +41,20 @@ class SocketEngineSelect : public SocketEngineBase Sockets.erase(s->GetSock()); } - void MarkWriteable(Socket *s) + void MarkWritable(Socket *s) { + if (s->HasFlag(SF_WRITABLE)) + return; FD_SET(s->GetSock(), &WriteFDs); + s->SetFlag(SF_WRITABLE); } - void ClearWriteable(Socket *s) + void ClearWritable(Socket *s) { + if (!s->HasFlag(SF_WRITABLE)) + return; FD_CLR(s->GetSock(), &WriteFDs); + s->UnsetFlag(SF_WRITABLE); } void Process() @@ -101,7 +107,7 @@ class SocketEngineSelect : public SocketEngineBase class ModuleSocketEngineSelect : public Module { - SocketEngineSelect *engine; + SocketEngineSelect engine; public: ModuleSocketEngineSelect(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator) @@ -110,13 +116,11 @@ class ModuleSocketEngineSelect : public Module this->SetPermanent(true); this->SetType(SOCKETENGINE); - engine = new SocketEngineSelect(); - SocketEngine = engine; + SocketEngine = &engine; } ~ModuleSocketEngineSelect() { - delete engine; SocketEngine = NULL; } }; |
