summaryrefslogtreecommitdiff
path: root/modules
diff options
context:
space:
mode:
authorAdam <Adam@anope.org>2010-09-09 23:43:11 -0400
committerAdam <Adam@anope.org>2010-09-09 23:43:11 -0400
commit46813ccb8c6ab572b8a9ff0a39afb1d92dc4482b (patch)
tree562da502a102230ce207bbe921fdc978ee71e20c /modules
parentfdd196e50b4616ac377bd0ee0ae5ce6c57b657ee (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.cpp2
-rw-r--r--modules/extra/m_dnsbl.cpp123
-rw-r--r--modules/protocol/bahamut.cpp5
-rw-r--r--modules/protocol/inspircd11.cpp7
-rw-r--r--modules/protocol/inspircd12.cpp5
-rw-r--r--modules/protocol/inspircd20.cpp5
-rw-r--r--modules/protocol/ratbox.cpp5
-rw-r--r--modules/protocol/unreal32.cpp21
-rw-r--r--modules/socketengines/m_socketengine_epoll.cpp20
-rw-r--r--modules/socketengines/m_socketengine_select.cpp16
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;
}
};