summaryrefslogtreecommitdiff
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
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.
-rw-r--r--CMakeLists.txt1
-rw-r--r--data/example.conf79
-rw-r--r--docs/Changes.conf2
-rw-r--r--include/config.h5
-rw-r--r--include/dns.h181
-rw-r--r--include/extern.h6
-rw-r--r--include/services.h7
-rw-r--r--include/socketengine.h4
-rw-r--r--include/sockets.h76
-rw-r--r--include/sysconf.h.cmake1
-rw-r--r--include/users.h8
-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
-rw-r--r--src/actions.cpp19
-rw-r--r--src/base64.cpp14
-rw-r--r--src/channels.cpp24
-rw-r--r--src/config.cpp32
-rw-r--r--src/dns.cpp550
-rw-r--r--src/init.cpp9
-rw-r--r--src/logger.cpp2
-rw-r--r--src/main.cpp5
-rw-r--r--src/misc.cpp63
-rw-r--r--src/operserv.cpp20
-rw-r--r--src/servers.cpp9
-rw-r--r--src/sockets.cpp288
-rw-r--r--src/users.cpp39
34 files changed, 1304 insertions, 349 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt
index f3c1e26df..a92086489 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -322,7 +322,6 @@ check_include_file(sys/select.h HAVE_SYS_SELECT_H)
check_include_file(sys/eventfd.h HAVE_SYS_EVENTFD_H)
# Check for the existance of the following functions
-check_function_exists(gethostbyname HAVE_GETHOSTBYNAME)
check_function_exists(gettimeofday HAVE_GETTIMEOFDAY)
check_function_exists(setgrent HAVE_SETGRENT)
check_function_exists(strcasecmp HAVE_STRCASECMP)
diff --git a/data/example.conf b/data/example.conf
index d7c7c9372..b98595ef7 100644
--- a/data/example.conf
+++ b/data/example.conf
@@ -820,6 +820,29 @@ mail
}
/*
+ * [OPTIONAL] DNS Config
+ *
+ * This section is used to configure DNS.
+ * At this time DNS is only used by a few modules (m_dnsbl)
+ * and is not required by the core to function.
+ */
+dns
+{
+ /*
+ * The nameserver to use for resolving hostnames, must be an IP or a resolver configuration file.
+ * The below should work fine on all nix like systems. Windows users will have to find their nameservers
+ * from ipconfig /all and put the IP here
+ */
+ nameserver = "/etc/resolv.conf"
+ #nameserver = "127.0.0.1"
+
+ /*
+ * How long to wait before a DNS query has timed out
+ */
+ timeout = 5
+}
+
+/*
* [REQUIRED] NickServ Config
*
* This section is used to set up the Nickname Registration Service pseudo-client.
@@ -1585,7 +1608,13 @@ module { name = "os_ignore" }
module { name = "cs_appendtopic" }
module { name = "cs_enforce" }
module { name = "ns_maxemail" }
-module { name = "hs_request" }
+
+/*
+ * [OPTIONAL] Module-Specific Options
+ *
+ * The following blocks are used for options pertaining to modules and are not part of the core.
+ * Unless otherwise stated, most of the options are optional.
+ */
/*
* m_ssl
@@ -1595,10 +1624,9 @@ module { name = "hs_request" }
module { name = "m_ssl" }
/*
- * [OPTIONAL] Module-Specific Options
+ * db_plain
*
- * The following blocks are used for options pertaining to modules and are not part of the core.
- * Unless otherwise stated, most of the options are optional.
+ * This is the default flatfile database format
*/
db_plain
{
@@ -1608,11 +1636,20 @@ db_plain
database = "anope.db"
}
+/*
+ * cs_set_misc
+ *
+ * Allows you to create misc /chanserv set commands, and have the data
+ * show up in /chanserv info
+ */
module { name = "cs_set_misc" }
cs_set_misc
{
+ /* The name of the command */
name = "OINFO"
+ /* A short description of the command */
desc = "Associate oper only information to this channel"
+ /* Set to yes if only opers can set it and see it */
operonly = yes
}
cs_set_misc
@@ -1654,6 +1691,7 @@ m_helpchan
helpchannel = "#help"
}
+module { name = "hs_request" }
hs_request
{
/*
@@ -1683,3 +1721,36 @@ ns_maxemail
#maxemails = 1
}
+module { name = "m_dnsbl" }
+m_dnsbl
+{
+ /*
+ * If set, Services will check clients against the DNSBLs when services connect to its uplink.
+ * This is not recommended, and on large networks will open a very large amount of DNS queries.
+ * While services are not drastically affected by this, your nameserver/DNSBL might care.
+ */
+ check_on_connect = no;
+
+ /*
+ * If set, Services will check clients when coming back from a netsplit. This can cause a large number
+ * of DNS queries open at once. While services are not drastically affected by this, your nameserver/DNSBL
+ * might care.
+ */
+ check_on_netburst = no;
+}
+blacklist
+{
+ /* Name of the blacklist */
+ name = "rbl.efnetrbl.org";
+ /* How long to set the akill for */
+ time = 4h;
+ /* Reason for akill, %h is replaced with the hostname of the user, and %i with the IP */
+ reason = "You are listed in the efnet RBL, visit http://rbl.efnetrbl.org/?i=%i for info"
+}
+blacklist
+{
+ name = "dnsbl.dronebl.org";
+ time = 4h;
+ reason = "You have a host listed in the DroneBL. For more information, visit http://dronebl.org/lookup.do?ip=%i"
+}
+
diff --git a/docs/Changes.conf b/docs/Changes.conf
index c49953e6d..992624d63 100644
--- a/docs/Changes.conf
+++ b/docs/Changes.conf
@@ -12,6 +12,8 @@ options:socketengine added to choose what socket engine to use
module:cs_set_misc and module:ns_set_misc added to replace the old set url/icq/email modules
options:hideprivilegedcommands added to hide privileged commands from normal users
log block added to customize logging
+dns block added to configure dns settings
+m_dnsbl added
** MODIFIED CONFIGURATION DIRECTIVES **
opertype:commands changed operserv/sgline to opserv/snline
diff --git a/include/config.h b/include/config.h
index 11969707f..4ea2aae23 100644
--- a/include/config.h
+++ b/include/config.h
@@ -572,6 +572,11 @@ class ServerConfig
/* Don't quote the To: address */
bool DontQuoteAddresses;
+ /* Nameserver to use for resolving hostnames */
+ Anope::string NameServer;
+ /* TIme before a DNS query is considered dead */
+ time_t DNSTimeout;
+
/* Prefix of guest nicks when a user gets forced off of a nick */
Anope::string NSGuestNickPrefix;
/* Allow users to set kill immed on */
diff --git a/include/dns.h b/include/dns.h
new file mode 100644
index 000000000..a8ef82d44
--- /dev/null
+++ b/include/dns.h
@@ -0,0 +1,181 @@
+#ifndef DNS_H
+#define DNS_H
+
+/** Valid query types
+ */
+enum QueryType
+{
+ /* Nothing */
+ DNS_QUERY_NONE,
+ /* A simple A lookup */
+ DNS_QUERY_A = 1,
+ /* A CNAME lookup */
+ DNS_QUERY_CNAME = 5,
+ /* Reverse DNS lookup */
+ DNS_QUERY_PTR = 12,
+ /* IPv6 AAAA lookup */
+ DNS_QUERY_AAAA = 28
+};
+
+/** Flags that can be AND'd into DNSPacket::flags to receive certain values
+ */
+enum QueryFlags
+{
+ DNS_QUERYFLAGS_QR = 0x8000,
+ DNS_QUERYFLAGS_OPCODE = 0x7800,
+ DNS_QUERYFLAGS_AA = 0x400,
+ DBS_QUERYFLAGS_TC = 0x200,
+ DNS_QUERYFLAGS_RD = 0x100,
+ DNS_QUERYFLAGS_RA = 0x80,
+ DNS_QUERYFLAGS_Z = 0x70,
+ DNS_QUERYFLAGS_RCODE = 0xF
+};
+
+enum DNSError
+{
+ DNS_ERROR_UNKNOWN,
+ DNS_ERROR_TIMEOUT,
+ DNS_ERROR_NOT_AN_ANSWER,
+ DNS_ERROR_NONSTANDARD_QUERY,
+ DNS_ERROR_FORMAT_ERROR,
+ DNS_ERROR_SERVER_FAILURE,
+ DNS_ERROR_DOMAIN_NOT_FOUND,
+ DNS_ERROR_NOT_IMPLEMENTED,
+ DNS_ERROR_REFUSED,
+ DNS_ERROR_NO_RECORDS,
+ DNS_ERROR_INVALID_TYPE
+};
+
+class DNSRequestTimeout; // Forward declarations
+struct DNSRecord;
+
+/** The request
+ */
+class DNSRequest
+{
+ /* Timeout timer for this request */
+ DNSRequestTimeout *timeout;
+
+ public:
+ /* Address we're looking up */
+ Anope::string address;
+ /* QueryType, A, AAAA, PTR etc */
+ QueryType QT;
+
+ DNSRequest(const Anope::string &addr, QueryType qt, bool cache = false);
+
+ virtual ~DNSRequest();
+
+ virtual void OnLookupComplete(const DNSRecord *r) = 0;
+
+ virtual void OnError(DNSError error, const Anope::string &message);
+};
+
+/** A full packet sent to the nameserver, may contain multiple queries
+ */
+struct DNSPacket
+{
+ /* Our 16-bit id for this header */
+ unsigned short id;
+ /* Flags on the query */
+ unsigned short flags;
+ /* Number of queries */
+ unsigned short qdcount;
+ /* Number of resource records in answer */
+ unsigned short ancount;
+ /* Number of NS resource records in authority records section */
+ unsigned short nscount;
+ /* Number of resource records in the additional records section */
+ unsigned short arcount;
+ /* How many of the bytes of the payload are in use */
+ unsigned short payload_count;
+ /* The queries, at most can be 512 bytes */
+ unsigned char payload[512];
+
+ inline DNSPacket();
+
+ bool AddQuestion(const Anope::string &address, QueryType qt);
+
+ inline void FillPacket(const unsigned char *input, const size_t length);
+
+ inline void FillBuffer(unsigned char *buffer);
+};
+
+struct DNSRecord
+{
+ /* Name of the initial lookup */
+ Anope::string name;
+ /* Result of the lookup */
+ Anope::string result;
+ /* Type of query this was */
+ QueryType type;
+ /* Record class, should always be 1 */
+ unsigned short record_class;
+ /* Time to live */
+ unsigned long ttl;
+ /* Record length */
+ unsigned short rdlength;
+
+ inline DNSRecord();
+ time_t created;
+};
+
+/** The socket used to talk to the nameserver, uses UDP
+ */
+class DNSSocket : public ClientSocket
+{
+ private:
+ sockaddrs server_addr;
+
+ int SendTo(const unsigned char *buf, size_t len) const;
+ int RecvFrom(char *buf, size_t size, sockaddrs &addrs) const;
+ public:
+ DNSSocket(const Anope::string &nTargetHost, int nPort);
+ virtual ~DNSSocket();
+
+ bool ProcessRead();
+
+ bool ProcessWrite();
+};
+
+/** DNS manager, manages the connection and all requests
+ */
+class DNSManager : public Timer
+{
+ std::multimap<Anope::string, DNSRecord *> cache;
+ public:
+ DNSSocket *sock;
+
+ std::deque<DNSPacket *> packets;
+ std::map<short, DNSRequest *> requests;
+
+ static const int DNSPort = 53;
+
+ DNSManager();
+
+ ~DNSManager();
+
+ void AddCache(DNSRecord *rr);
+ bool CheckCache(DNSRequest *request);
+ void Tick(time_t now);
+};
+
+/** A DNS timeout, one is made for every DNS request to detect timeouts
+ */
+class DNSRequestTimeout : public Timer
+{
+ DNSRequest *request;
+ public:
+ bool done;
+
+ DNSRequestTimeout(DNSRequest *r, time_t timeout);
+
+ ~DNSRequestTimeout();
+
+ void Tick(time_t);
+};
+
+extern DNSManager *DNSEngine;
+
+#endif // DNS_H
+
diff --git a/include/extern.h b/include/extern.h
index 48336be5f..2294c3f28 100644
--- a/include/extern.h
+++ b/include/extern.h
@@ -276,7 +276,6 @@ E uint16 netmask_to_cidr(uint32 mask);
E bool str_is_wildcard(const Anope::string &str);
E bool str_is_pure_wildcard(const Anope::string &str);
-E uint32 str_is_ip(const Anope::string &str);
E bool str_is_cidr(const Anope::string &str, uint32 &ip, uint32 &mask, Anope::string &host);
/**** modes.cpp ****/
@@ -362,7 +361,7 @@ E User *finduser(const Anope::string &nick);
E Anope::string TS6SID;
-E User *do_nick(const Anope::string &source, const Anope::string &nick, const Anope::string &username, const Anope::string &host, const Anope::string &server, const Anope::string &realname, time_t ts, uint32 ip, const Anope::string &vhost, const Anope::string &uid);
+E User *do_nick(const Anope::string &source, const Anope::string &nick, const Anope::string &username, const Anope::string &host, const Anope::string &server, const Anope::string &realname, time_t ts, const Anope::string &ip, const Anope::string &vhost, const Anope::string &uid);
E void do_umode(const Anope::string &source, int ac, const char **av);
E void do_quit(const Anope::string &source, int ac, const char **av);
@@ -382,9 +381,6 @@ E void UserSetInternalModes(User *user, int ac, const char **av);
E void b64_encode(const Anope::string &src, Anope::string &target);
E void b64_decode(const Anope::string &src, Anope::string &target);
-E int decode_ip(const Anope::string &buf);
-
-E Anope::string host_resolve(const Anope::string &host);
#ifdef _WIN32
E Anope::string GetWindowsVersion();
diff --git a/include/services.h b/include/services.h
index f44425656..63e2492b2 100644
--- a/include/services.h
+++ b/include/services.h
@@ -363,6 +363,9 @@ template<typename T, size_t Size = 32> class Flags
#include "sockets.h"
#include "socketengine.h"
+#include "extensible.h"
+#include "timers.h"
+#include "dns.h"
/*************************************************************************/
@@ -427,7 +430,6 @@ class Server;
struct EList;
struct Session;
-#include "extensible.h"
#include "threadengine.h"
#include "opertype.h"
#include "modes.h"
@@ -457,7 +459,6 @@ struct IRCDVar
int vident; /* Supports vidents */
int svshold; /* Supports svshold */
int tsonmode; /* Timestamp on mode changes */
- int nickip; /* Sends IP on NICK */
int omode; /* On the fly o:lines */
int umode; /* change user modes */
int nickvhost; /* Users vhost sent during NICK */
@@ -1054,8 +1055,6 @@ struct Uplink
Uplink(const Anope::string &_host, int _port, const Anope::string &_password, bool _ipv6) : host(_host), port(_port), password(_password), ipv6(_ipv6) { }
};
-#include "timers.h"
-
/** Timer for colliding nicks to force people off of nicknames
*/
class NickServCollide : public Timer
diff --git a/include/socketengine.h b/include/socketengine.h
index 7279ba3ad..c45249810 100644
--- a/include/socketengine.h
+++ b/include/socketengine.h
@@ -43,12 +43,12 @@ class CoreExport SocketEngineBase
/** Mark a socket as writeable
* @param s The socket
*/
- virtual void MarkWriteable(Socket *s) { }
+ virtual void MarkWritable(Socket *s) { }
/** Unmark a socket as writeable
* @param s The socket
*/
- virtual void ClearWriteable(Socket *s) { }
+ virtual void ClearWritable(Socket *s) { }
/** Read from sockets and do things
*/
diff --git a/include/sockets.h b/include/sockets.h
index 6eeb3bf3d..772a08a65 100644
--- a/include/sockets.h
+++ b/include/sockets.h
@@ -22,6 +22,49 @@
# define CloseSocket close
#endif
+/** A sockaddr union used to combine IPv4 and IPv6 sockaddrs
+ */
+union CoreExport sockaddrs
+{
+ sockaddr sa;
+ sockaddr_in sa4;
+ sockaddr_in6 sa6;
+
+ /** Get the size of the sockaddr we represent
+ * @return The size
+ */
+ size_t size() const;
+
+ /** Get the port represented by this addr
+ * @return The port, or -1 on fail
+ */
+ int port() const;
+
+ /** Get the address represented by this addr
+ * @return The address
+ */
+ Anope::string addr() const;
+
+ /** Construct the object, sets everything to 0
+ */
+ sockaddrs();
+
+ /** Check if this sockaddr has data in it
+ */
+ bool operator()() const;
+
+ /** Compares with sockaddr with another. Compares address type, port, and address
+ * @return true if they are the same
+ */
+ bool operator==(const sockaddrs &other) const;
+ /* The same as above but not */
+ inline bool operator!=(const sockaddrs &other) const { return !(*this == other); }
+
+ void pton(int type, const Anope::string &address, int pport = 0);
+
+ void ntop(int type, const void *src);
+};
+
class SocketException : public CoreException
{
public:
@@ -44,12 +87,13 @@ enum SocketType
enum SocketFlag
{
- SF_DEAD
+ SF_DEAD,
+ SF_WRITABLE
};
-class CoreExport Socket : public Flags<SocketFlag, 1>
+class CoreExport Socket : public Flags<SocketFlag, 2>
{
- private:
+ protected:
/** Really recieve something from the buffer
* @param buf The buf to read to
* @param sz How much to read
@@ -63,7 +107,6 @@ class CoreExport Socket : public Flags<SocketFlag, 1>
*/
virtual int SendInternal(const Anope::string &buf) const;
- protected:
/* Socket FD */
int Sock;
/* Port we're connected to */
@@ -88,8 +131,9 @@ class CoreExport Socket : public Flags<SocketFlag, 1>
/** Default constructor
* @param nsock The socket to use, 0 if we need to create our own
* @param nIPv6 true if using ipv6
+ * @param type The socket type, defaults to SOCK_STREAM
*/
- Socket(int nsock, bool nIPv6);
+ Socket(int nsock, bool nIPv6, int type = SOCK_STREAM);
/** Default destructor
*/
@@ -130,7 +174,7 @@ class CoreExport Socket : public Flags<SocketFlag, 1>
*/
virtual bool ProcessRead();
- /** Called when there is something to be written to this socket
+ /** Called when the socket is ready to be written to
* @return true on success, false to drop this socket
*/
virtual bool ProcessWrite();
@@ -156,20 +200,37 @@ class CoreExport Socket : public Flags<SocketFlag, 1>
class CoreExport Pipe : public Socket
{
private:
+ /** The FD of the write pipe (if this isn't evenfd)
+ * this->Sock is the readfd
+ */
int WritePipe;
+ /** Our overloaded RecvInternal call
+ */
int RecvInternal(char *buf, size_t sz) const;
+ /** Our overloaded SendInternal call
+ */
int SendInternal(const Anope::string &buf) const;
public:
+ /** Constructor
+ */
Pipe();
+ /** Called when data is to be read
+ */
bool ProcessRead();
+ /** Function that calls OnNotify
+ */
bool Read(const Anope::string &);
+ /** Called when this pipe needs to be woken up
+ */
void Notify();
+ /** Should be overloaded to do something useful
+ */
virtual void OnNotify();
};
@@ -190,8 +251,9 @@ class CoreExport ClientSocket : public Socket
* @param nPort The target port to connect to
* @param nBindHost The host to bind to for connecting
* @param nIPv6 true to use IPv6
+ * @param type The socket type, defaults to SOCK_STREAM
*/
- ClientSocket(const Anope::string &nTargetHost, int nPort, const Anope::string &nBindHost, bool nIPv6);
+ ClientSocket(const Anope::string &nTargetHost, int nPort, const Anope::string &nBindHost = "", bool nIPv6 = false, int type = SOCK_STREAM);
/** Default destructor
*/
diff --git a/include/sysconf.h.cmake b/include/sysconf.h.cmake
index 0184c5359..2d278e3dd 100644
--- a/include/sysconf.h.cmake
+++ b/include/sysconf.h.cmake
@@ -8,7 +8,6 @@
#cmakedefine HAVE_STDINT_H 1
#cmakedefine HAVE_STDDEF_H 1
#cmakedefine HAVE_BACKTRACE 1
-#cmakedefine HAVE_GETHOSTBYNAME 1
#cmakedefine HAVE_GETTIMEOFDAY 1
#cmakedefine HAVE_SETGRENT 1
#cmakedefine HAVE_STRCASECMP 1
diff --git a/include/users.h b/include/users.h
index 596f5ee39..b880a197a 100644
--- a/include/users.h
+++ b/include/users.h
@@ -51,10 +51,10 @@ class CoreExport User : public Extensible
Anope::string nick; /* User's current nick */
Anope::string host; /* User's real hostname */
- Anope::string hostip; /* User's IP number */
- Anope::string vhost; /* User's virtual hostname */
- Anope::string chost; /* User's cloaked hostname */
- Anope::string realname; /* Realname */
+ Anope::string vhost; /* User's virtual hostname */
+ Anope::string chost; /* User's cloaked hostname */
+ Anope::string realname; /* Realname */
+ sockaddrs ip; /* User's IP */
Server *server; /* Server user is connected to */
time_t timestamp; /* Timestamp of the nick */
time_t my_signon; /* When did _we_ see the user? */
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/