summaryrefslogtreecommitdiff
path: root/include/modules
diff options
context:
space:
mode:
Diffstat (limited to 'include/modules')
-rw-r--r--include/modules/account.h41
-rw-r--r--include/modules/cap.h88
-rw-r--r--include/modules/dns.h193
-rw-r--r--include/modules/hash.h58
-rw-r--r--include/modules/httpd.h239
-rw-r--r--include/modules/ldap.h199
-rw-r--r--include/modules/regex.h62
-rw-r--r--include/modules/sasl.h31
-rw-r--r--include/modules/spanningtree.h40
-rw-r--r--include/modules/sql.h184
-rw-r--r--include/modules/ssl.h246
11 files changed, 1381 insertions, 0 deletions
diff --git a/include/modules/account.h b/include/modules/account.h
new file mode 100644
index 000000000..c00b044e4
--- /dev/null
+++ b/include/modules/account.h
@@ -0,0 +1,41 @@
+/*
+ * InspIRCd -- Internet Relay Chat Daemon
+ *
+ * Copyright (C) 2008 Craig Edwards <craigedwards@brainbox.cc>
+ *
+ * This file is part of InspIRCd. InspIRCd is free software: you can
+ * redistribute it and/or modify it under the terms of the GNU General Public
+ * License as published by the Free Software Foundation, version 2.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+
+#pragma once
+
+#include <map>
+#include <string>
+
+class AccountEvent : public Event
+{
+ public:
+ User* const user;
+ const std::string account;
+ AccountEvent(Module* me, User* u, const std::string& name)
+ : Event(me, "account_login"), user(u), account(name)
+ {
+ }
+};
+
+typedef StringExtItem AccountExtItem;
+
+inline AccountExtItem* GetAccountExtItem()
+{
+ return static_cast<AccountExtItem*>(ServerInstance->Extensions.GetItem("accountname"));
+}
diff --git a/include/modules/cap.h b/include/modules/cap.h
new file mode 100644
index 000000000..1b33e05bb
--- /dev/null
+++ b/include/modules/cap.h
@@ -0,0 +1,88 @@
+/*
+ * InspIRCd -- Internet Relay Chat Daemon
+ *
+ * Copyright (C) 2009 Daniel De Graaf <danieldg@inspircd.org>
+ * Copyright (C) 2008 Craig Edwards <craigedwards@brainbox.cc>
+ *
+ * This file is part of InspIRCd. InspIRCd is free software: you can
+ * redistribute it and/or modify it under the terms of the GNU General Public
+ * License as published by the Free Software Foundation, version 2.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+
+#pragma once
+
+class CapEvent : public Event
+{
+ public:
+ enum CapEventType
+ {
+ CAPEVENT_REQ,
+ CAPEVENT_LS,
+ CAPEVENT_LIST,
+ CAPEVENT_CLEAR
+ };
+
+ CapEventType type;
+ std::vector<std::string> wanted;
+ std::vector<std::string> ack;
+ User* user;
+ CapEvent(Module* sender, User* u, CapEventType capevtype) : Event(sender, "cap_request"), type(capevtype), user(u) {}
+};
+
+class GenericCap
+{
+ public:
+ LocalIntExt ext;
+ const std::string cap;
+ GenericCap(Module* parent, const std::string &Cap) : ext("cap_" + Cap, parent), cap(Cap)
+ {
+ }
+
+ void HandleEvent(Event& ev)
+ {
+ if (ev.id != "cap_request")
+ return;
+
+ CapEvent *data = static_cast<CapEvent*>(&ev);
+ if (data->type == CapEvent::CAPEVENT_REQ)
+ {
+ for (std::vector<std::string>::iterator it = data->wanted.begin(); it != data->wanted.end(); ++it)
+ {
+ if (it->empty())
+ continue;
+ bool enablecap = ((*it)[0] != '-');
+ if (((enablecap) && (*it == cap)) || (*it == "-" + cap))
+ {
+ // we can handle this, so ACK it, and remove it from the wanted list
+ data->ack.push_back(*it);
+ data->wanted.erase(it);
+ ext.set(data->user, enablecap ? 1 : 0);
+ break;
+ }
+ }
+ }
+ else if (data->type == CapEvent::CAPEVENT_LS)
+ {
+ data->wanted.push_back(cap);
+ }
+ else if (data->type == CapEvent::CAPEVENT_LIST)
+ {
+ if (ext.get(data->user))
+ data->wanted.push_back(cap);
+ }
+ else if (data->type == CapEvent::CAPEVENT_CLEAR)
+ {
+ data->ack.push_back("-" + cap);
+ ext.set(data->user, 0);
+ }
+ }
+};
diff --git a/include/modules/dns.h b/include/modules/dns.h
new file mode 100644
index 000000000..c76c53805
--- /dev/null
+++ b/include/modules/dns.h
@@ -0,0 +1,193 @@
+/*
+ * InspIRCd -- Internet Relay Chat Daemon
+ *
+ * Copyright (C) 2013 Adam <Adam@anope.org>
+ * Copyright (C) 2003-2013 Anope Team <team@anope.org>
+ *
+ * This file is part of InspIRCd. InspIRCd is free software: you can
+ * redistribute it and/or modify it under the terms of the GNU General Public
+ * License as published by the Free Software Foundation, version 2.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#pragma once
+
+namespace DNS
+{
+ /** Valid query types
+ */
+ enum QueryType
+ {
+ /* Nothing */
+ QUERY_NONE,
+ /* A simple A lookup */
+ QUERY_A = 1,
+ /* A CNAME lookup */
+ QUERY_CNAME = 5,
+ /* Reverse DNS lookup */
+ QUERY_PTR = 12,
+ /* IPv6 AAAA lookup */
+ QUERY_AAAA = 28
+ };
+
+ /** Flags that can be AND'd into DNSPacket::flags to receive certain values
+ */
+ enum
+ {
+ QUERYFLAGS_QR = 0x8000,
+ QUERYFLAGS_OPCODE = 0x7800,
+ QUERYFLAGS_AA = 0x400,
+ QUERYFLAGS_TC = 0x200,
+ QUERYFLAGS_RD = 0x100,
+ QUERYFLAGS_RA = 0x80,
+ QUERYFLAGS_Z = 0x70,
+ QUERYFLAGS_RCODE = 0xF
+ };
+
+ enum Error
+ {
+ ERROR_NONE,
+ ERROR_UNKNOWN,
+ ERROR_UNLOADED,
+ ERROR_TIMEDOUT,
+ ERROR_NOT_AN_ANSWER,
+ ERROR_NONSTANDARD_QUERY,
+ ERROR_FORMAT_ERROR,
+ ERROR_SERVER_FAILURE,
+ ERROR_DOMAIN_NOT_FOUND,
+ ERROR_NOT_IMPLEMENTED,
+ ERROR_REFUSED,
+ ERROR_NO_RECORDS,
+ ERROR_INVALIDTYPE
+ };
+
+ const int PORT = 53;
+
+ /**
+ * The maximum value of a dns request id,
+ * 16 bits wide, 0xFFFF.
+ */
+ const int MAX_REQUEST_ID = 0xFFFF;
+
+ class Exception : public ModuleException
+ {
+ public:
+ Exception(const std::string& message) : ModuleException(message) { }
+ };
+
+ struct Question
+ {
+ std::string name;
+ QueryType type;
+ unsigned short qclass;
+
+ Question() : type(QUERY_NONE), qclass(0) { }
+ Question(const std::string& n, QueryType t, unsigned short c = 1) : name(n), type(t), qclass(c) { }
+ inline bool operator==(const Question& other) const { return name == other.name && type == other.type && qclass == other.qclass; }
+
+ struct hash
+ {
+ size_t operator()(const Question& question) const
+ {
+ return irc::insensitive()(question.name);
+ }
+ };
+ };
+
+ struct ResourceRecord : Question
+ {
+ unsigned int ttl;
+ std::string rdata;
+ time_t created;
+
+ ResourceRecord(const std::string& n, QueryType t, unsigned short c = 1) : Question(n, t, c), ttl(0), created(ServerInstance->Time()) { }
+ ResourceRecord(const Question& question) : Question(question), ttl(0), created(ServerInstance->Time()) { }
+ };
+
+ struct Query
+ {
+ std::vector<Question> questions;
+ std::vector<ResourceRecord> answers;
+ Error error;
+ bool cached;
+
+ Query() : error(ERROR_NONE), cached(false) { }
+ Query(const Question& question) : error(ERROR_NONE), cached(false) { questions.push_back(question); }
+ };
+
+ class ReplySocket;
+ class Request;
+
+ /** DNS manager
+ */
+ class Manager : public DataProvider
+ {
+ public:
+ Manager(Module* mod) : DataProvider(mod, "DNS") { }
+
+ virtual void Process(Request* req) = 0;
+ virtual void RemoveRequest(Request* req) = 0;
+ virtual std::string GetErrorStr(Error) = 0;
+ };
+
+ /** A DNS query.
+ */
+ class Request : public Timer, public Question
+ {
+ protected:
+ Manager* const manager;
+ public:
+ /* Use result cache if available */
+ bool use_cache;
+ /* Request id */
+ unsigned short id;
+ /* Creator of this request */
+ Module* const creator;
+
+ Request(Manager* mgr, Module* mod, const std::string& addr, QueryType qt, bool usecache = true)
+ : Timer((ServerInstance->Config->dns_timeout ? ServerInstance->Config->dns_timeout : 5), ServerInstance->Time())
+ , Question(addr, qt)
+ , manager(mgr)
+ , use_cache(usecache)
+ , id(0)
+ , creator(mod)
+ {
+ ServerInstance->Timers.AddTimer(this);
+ }
+
+ virtual ~Request()
+ {
+ manager->RemoveRequest(this);
+ }
+
+ /** Called when this request succeeds
+ * @param r The query sent back from the nameserver
+ */
+ virtual void OnLookupComplete(const Query* req) = 0;
+
+ /** Called when this request fails or times out.
+ * @param r The query sent back from the nameserver, check the error code.
+ */
+ virtual void OnError(const Query* req) { }
+
+ /** Used to time out the query, calls OnError and asks the TimerManager
+ * to delete this request
+ */
+ bool Tick(time_t now)
+ {
+ Query rr(*this);
+ rr.error = ERROR_TIMEDOUT;
+ this->OnError(&rr);
+ delete this;
+ return false;
+ }
+ };
+
+} // namespace DNS
diff --git a/include/modules/hash.h b/include/modules/hash.h
new file mode 100644
index 000000000..da04c45ba
--- /dev/null
+++ b/include/modules/hash.h
@@ -0,0 +1,58 @@
+/*
+ * InspIRCd -- Internet Relay Chat Daemon
+ *
+ * Copyright (C) 2010 Daniel De Graaf <danieldg@inspircd.org>
+ *
+ * This file is part of InspIRCd. InspIRCd is free software: you can
+ * redistribute it and/or modify it under the terms of the GNU General Public
+ * License as published by the Free Software Foundation, version 2.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+
+#pragma once
+
+#include "modules.h"
+
+class HashProvider : public DataProvider
+{
+ public:
+ const unsigned int out_size;
+ const unsigned int block_size;
+ HashProvider(Module* mod, const std::string& Name, int osiz, int bsiz)
+ : DataProvider(mod, Name), out_size(osiz), block_size(bsiz) {}
+ virtual std::string sum(const std::string& data) = 0;
+ inline std::string hexsum(const std::string& data)
+ {
+ return BinToHex(sum(data));
+ }
+
+ inline std::string b64sum(const std::string& data)
+ {
+ return BinToBase64(sum(data), NULL, 0);
+ }
+
+ /** HMAC algorithm, RFC 2104 */
+ std::string hmac(const std::string& key, const std::string& msg)
+ {
+ std::string hmac1, hmac2;
+ std::string kbuf = key.length() > block_size ? sum(key) : key;
+ kbuf.resize(block_size);
+
+ for (size_t n = 0; n < block_size; n++)
+ {
+ hmac1.push_back(static_cast<char>(kbuf[n] ^ 0x5C));
+ hmac2.push_back(static_cast<char>(kbuf[n] ^ 0x36));
+ }
+ hmac2.append(msg);
+ hmac1.append(sum(hmac2));
+ return sum(hmac1);
+ }
+};
diff --git a/include/modules/httpd.h b/include/modules/httpd.h
new file mode 100644
index 000000000..86234d53f
--- /dev/null
+++ b/include/modules/httpd.h
@@ -0,0 +1,239 @@
+/*
+ * InspIRCd -- Internet Relay Chat Daemon
+ *
+ * Copyright (C) 2009 Daniel De Graaf <danieldg@inspircd.org>
+ * Copyright (C) 2008 Pippijn van Steenhoven <pip88nl@gmail.com>
+ * Copyright (C) 2007 John Brooks <john.brooks@dereferenced.net>
+ * Copyright (C) 2007 Dennis Friis <peavey@inspircd.org>
+ * Copyright (C) 2006 Craig Edwards <craigedwards@brainbox.cc>
+ *
+ * This file is part of InspIRCd. InspIRCd is free software: you can
+ * redistribute it and/or modify it under the terms of the GNU General Public
+ * License as published by the Free Software Foundation, version 2.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+
+#pragma once
+
+#include "base.h"
+
+#include <string>
+#include <sstream>
+#include <map>
+
+/** A modifyable list of HTTP header fields
+ */
+class HTTPHeaders
+{
+ protected:
+ std::map<std::string,std::string> headers;
+ public:
+
+ /** Set the value of a header
+ * Sets the value of the named header. If the header is already present, it will be replaced
+ */
+ void SetHeader(const std::string &name, const std::string &data)
+ {
+ headers[name] = data;
+ }
+
+ /** Set the value of a header, only if it doesn't exist already
+ * Sets the value of the named header. If the header is already present, it will NOT be updated
+ */
+ void CreateHeader(const std::string &name, const std::string &data)
+ {
+ if (!IsSet(name))
+ SetHeader(name, data);
+ }
+
+ /** Remove the named header
+ */
+ void RemoveHeader(const std::string &name)
+ {
+ headers.erase(name);
+ }
+
+ /** Remove all headers
+ */
+ void Clear()
+ {
+ headers.clear();
+ }
+
+ /** Get the value of a header
+ * @return The value of the header, or an empty string
+ */
+ std::string GetHeader(const std::string &name)
+ {
+ std::map<std::string,std::string>::iterator it = headers.find(name);
+ if (it == headers.end())
+ return std::string();
+
+ return it->second;
+ }
+
+ /** Check if the given header is specified
+ * @return true if the header is specified
+ */
+ bool IsSet(const std::string &name)
+ {
+ std::map<std::string,std::string>::iterator it = headers.find(name);
+ return (it != headers.end());
+ }
+
+ /** Get all headers, formatted by the HTTP protocol
+ * @return Returns all headers, formatted according to the HTTP protocol. There is no request terminator at the end
+ */
+ std::string GetFormattedHeaders()
+ {
+ std::string re;
+
+ for (std::map<std::string,std::string>::iterator i = headers.begin(); i != headers.end(); i++)
+ re += i->first + ": " + i->second + "\r\n";
+
+ return re;
+ }
+};
+
+class HttpServerSocket;
+
+/** This class represents a HTTP request.
+ */
+class HTTPRequest : public Event
+{
+ protected:
+ std::string type;
+ std::string document;
+ std::string ipaddr;
+ std::string postdata;
+
+ public:
+
+ HTTPHeaders *headers;
+ int errorcode;
+
+ /** A socket pointer, which you must return in your HTTPDocument class
+ * if you reply to this request.
+ */
+ HttpServerSocket* sock;
+
+ /** Initialize HTTPRequest.
+ * This constructor is called by m_httpd.so to initialize the class.
+ * @param request_type The request type, e.g. GET, POST, HEAD
+ * @param uri The URI, e.g. /page
+ * @param hdr The headers sent with the request
+ * @param opaque An opaque pointer used internally by m_httpd, which you must pass back to the module in your reply.
+ * @param ip The IP address making the web request.
+ * @param pdata The post data (content after headers) received with the request, up to Content-Length in size
+ */
+ HTTPRequest(Module* me, const std::string &eventid, const std::string &request_type, const std::string &uri,
+ HTTPHeaders* hdr, HttpServerSocket* socket, const std::string &ip, const std::string &pdata)
+ : Event(me, eventid), type(request_type), document(uri), ipaddr(ip), postdata(pdata), headers(hdr), sock(socket)
+ {
+ }
+
+ /** Get the post data (request content).
+ * All post data will be returned, including carriage returns and linefeeds.
+ * @return The postdata
+ */
+ std::string& GetPostData()
+ {
+ return postdata;
+ }
+
+ /** Get the request type.
+ * Any request type can be intercepted, even ones which are invalid in the HTTP/1.1 spec.
+ * @return The request type, e.g. GET, POST, HEAD
+ */
+ std::string& GetType()
+ {
+ return type;
+ }
+
+ /** Get URI.
+ * The URI string (URL minus hostname and scheme) will be provided by this function.
+ * @return The URI being requested
+ */
+ std::string& GetURI()
+ {
+ return document;
+ }
+
+ /** Get IP address of requester.
+ * The requesting system's ip address will be returned.
+ * @return The IP address as a string
+ */
+ std::string& GetIP()
+ {
+ return ipaddr;
+ }
+};
+
+/** If you want to reply to HTTP requests, you must return a HTTPDocumentResponse to
+ * the httpd module via the HTTPdAPI.
+ * When you initialize this class you initialize it with all components required to
+ * form a valid HTTP response: the document data and a response code.
+ * You can add additional HTTP headers, if you want.
+ */
+class HTTPDocumentResponse
+{
+ public:
+ /** Module that generated this reply
+ */
+ Module* const module;
+
+ std::stringstream* document;
+ unsigned int responsecode;
+
+ /** Any extra headers to include with the defaults
+ */
+ HTTPHeaders headers;
+
+ HTTPRequest& src;
+
+ /** Initialize a HTTPDocumentResponse ready for sending to the httpd module.
+ * @param mod A pointer to the module who responded to the request
+ * @param req The request you obtained from the HTTPRequest at an earlier time
+ * @param doc A stringstream containing the document body
+ * @param response A valid HTTP/1.0 or HTTP/1.1 response code. The response text will be determined for you
+ * based upon the response code.
+ */
+ HTTPDocumentResponse(Module* mod, HTTPRequest& req, std::stringstream* doc, unsigned int response)
+ : module(mod), document(doc), responsecode(response), src(req)
+ {
+ }
+};
+
+class HTTPdAPIBase : public DataProvider
+{
+ public:
+ HTTPdAPIBase(Module* parent)
+ : DataProvider(parent, "m_httpd_api")
+ {
+ }
+
+ /** Answer an incoming HTTP request with the provided document
+ * @param response The response created by your module that will be sent to the client
+ */
+ virtual void SendResponse(HTTPDocumentResponse& response) = 0;
+};
+
+/** The API provided by the httpd module that allows other modules to respond to incoming
+ * HTTP requests
+ */
+class HTTPdAPI : public dynamic_reference<HTTPdAPIBase>
+{
+ public:
+ HTTPdAPI(Module* parent)
+ : dynamic_reference<HTTPdAPIBase>(parent, "m_httpd_api")
+ {
+ }
+};
diff --git a/include/modules/ldap.h b/include/modules/ldap.h
new file mode 100644
index 000000000..75ab16077
--- /dev/null
+++ b/include/modules/ldap.h
@@ -0,0 +1,199 @@
+/*
+ * InspIRCd -- Internet Relay Chat Daemon
+ *
+ * Copyright (C) 2013 Adam <Adam@anope.org>
+ * Copyright (C) 2003-2013 Anope Team <team@anope.org>
+ *
+ * This file is part of InspIRCd. InspIRCd is free software: you can
+ * redistribute it and/or modify it under the terms of the GNU General Public
+ * License as published by the Free Software Foundation, version 2.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#pragma once
+
+typedef int LDAPQuery;
+
+class LDAPException : public ModuleException
+{
+ public:
+ LDAPException(const std::string& reason) : ModuleException(reason) { }
+
+ virtual ~LDAPException() throw() { }
+};
+
+struct LDAPModification
+{
+ enum LDAPOperation
+ {
+ LDAP_ADD,
+ LDAP_DEL,
+ LDAP_REPLACE
+ };
+
+ LDAPOperation op;
+ std::string name;
+ std::vector<std::string> values;
+};
+
+typedef std::vector<LDAPModification> LDAPMods;
+
+struct LDAPAttributes : public std::map<std::string, std::vector<std::string> >
+{
+ size_t size(const std::string& attr) const
+ {
+ const std::vector<std::string>& array = this->getArray(attr);
+ return array.size();
+ }
+
+ const std::vector<std::string> keys() const
+ {
+ std::vector<std::string> k;
+ for (const_iterator it = this->begin(), it_end = this->end(); it != it_end; ++it)
+ k.push_back(it->first);
+ return k;
+ }
+
+ const std::string& get(const std::string& attr) const
+ {
+ const std::vector<std::string>& array = this->getArray(attr);
+ if (array.empty())
+ throw LDAPException("Empty attribute " + attr + " in LDAPResult::get");
+ return array[0];
+ }
+
+ const std::vector<std::string>& getArray(const std::string& attr) const
+ {
+ const_iterator it = this->find(attr);
+ if (it == this->end())
+ throw LDAPException("Unknown attribute " + attr + " in LDAPResult::getArray");
+ return it->second;
+ }
+};
+
+struct LDAPResult
+{
+ std::vector<LDAPAttributes> messages;
+ std::string error;
+
+ enum QueryType
+ {
+ QUERY_UNKNOWN,
+ QUERY_BIND,
+ QUERY_SEARCH,
+ QUERY_ADD,
+ QUERY_DELETE,
+ QUERY_MODIFY,
+ QUERY_COMPARE
+ };
+
+ QueryType type;
+ LDAPQuery id;
+
+ LDAPResult()
+ : type(QUERY_UNKNOWN), id(-1)
+ {
+ }
+
+ size_t size() const
+ {
+ return this->messages.size();
+ }
+
+ bool empty() const
+ {
+ return this->messages.empty();
+ }
+
+ const LDAPAttributes& get(size_t sz) const
+ {
+ if (sz >= this->messages.size())
+ throw LDAPException("Index out of range");
+ return this->messages[sz];
+ }
+
+ const std::string& getError() const
+ {
+ return this->error;
+ }
+};
+
+class LDAPInterface
+{
+ public:
+ ModuleRef creator;
+
+ LDAPInterface(Module* m) : creator(m) { }
+ virtual ~LDAPInterface() { }
+
+ virtual void OnResult(const LDAPResult& r) = 0;
+ virtual void OnError(const LDAPResult& err) = 0;
+};
+
+class LDAPProvider : public DataProvider
+{
+ public:
+ LDAPProvider(Module* Creator, const std::string& Name)
+ : DataProvider(Creator, Name) { }
+
+ /** Attempt to bind to the LDAP server as a manager
+ * @param i The LDAPInterface the result is sent to
+ * @return The query ID
+ */
+ virtual LDAPQuery BindAsManager(LDAPInterface *i) = 0;
+
+ /** Bind to LDAP
+ * @param i The LDAPInterface the result is sent to
+ * @param who The binddn
+ * @param pass The password
+ * @return The query ID
+ */
+ virtual LDAPQuery Bind(LDAPInterface* i, const std::string& who, const std::string& pass) = 0;
+
+ /** Search ldap for the specified filter
+ * @param i The LDAPInterface the result is sent to
+ * @param base The base DN to search
+ * @param filter The filter to apply
+ * @return The query ID
+ */
+ virtual LDAPQuery Search(LDAPInterface* i, const std::string& base, const std::string& filter) = 0;
+
+ /** Add an entry to LDAP
+ * @param i The LDAPInterface the result is sent to
+ * @param dn The dn of the entry to add
+ * @param attributes The attributes
+ * @return The query ID
+ */
+ virtual LDAPQuery Add(LDAPInterface* i, const std::string& dn, LDAPMods& attributes) = 0;
+
+ /** Delete an entry from LDAP
+ * @param i The LDAPInterface the result is sent to
+ * @param dn The dn of the entry to delete
+ * @return The query ID
+ */
+ virtual LDAPQuery Del(LDAPInterface* i, const std::string& dn) = 0;
+
+ /** Modify an existing entry in LDAP
+ * @param i The LDAPInterface the result is sent to
+ * @param base The base DN to modify
+ * @param attributes The attributes to modify
+ * @return The query ID
+ */
+ virtual LDAPQuery Modify(LDAPInterface* i, const std::string& base, LDAPMods& attributes) = 0;
+
+ /** Compare an attribute in LDAP with our value
+ * @param i The LDAPInterface the result is sent to
+ * @param dn DN to use for comparing
+ * @param attr Attr of DN to compare with
+ * @param val value to compare attr of dn
+ * @return the query ID
+ */
+ virtual LDAPQuery Compare(LDAPInterface* i, const std::string& dn, const std::string& attr, const std::string& val) = 0;
+};
diff --git a/include/modules/regex.h b/include/modules/regex.h
new file mode 100644
index 000000000..5ef00cdd0
--- /dev/null
+++ b/include/modules/regex.h
@@ -0,0 +1,62 @@
+/*
+ * InspIRCd -- Internet Relay Chat Daemon
+ *
+ * Copyright (C) 2009 Daniel De Graaf <danieldg@inspircd.org>
+ * Copyright (C) 2008 Thomas Stagner <aquanight@inspircd.org>
+ *
+ * This file is part of InspIRCd. InspIRCd is free software: you can
+ * redistribute it and/or modify it under the terms of the GNU General Public
+ * License as published by the Free Software Foundation, version 2.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+
+#pragma once
+
+#include "inspircd.h"
+
+class Regex : public classbase
+{
+protected:
+ /** The uncompiled regex string. */
+ std::string regex_string;
+
+ // Constructor may as well be protected, as this class is abstract.
+ Regex(const std::string& rx) : regex_string(rx) { }
+
+public:
+
+ virtual ~Regex() { }
+
+ virtual bool Matches(const std::string& text) = 0;
+
+ const std::string& GetRegexString() const
+ {
+ return regex_string;
+ }
+};
+
+class RegexFactory : public DataProvider
+{
+ public:
+ RegexFactory(Module* Creator, const std::string& Name) : DataProvider(Creator, Name) { }
+
+ virtual Regex* Create(const std::string& expr) = 0;
+};
+
+class RegexException : public ModuleException
+{
+ public:
+ RegexException(const std::string& regex, const std::string& error)
+ : ModuleException("Error in regex '" + regex + "': " + error) { }
+
+ RegexException(const std::string& regex, const std::string& error, int offset)
+ : ModuleException("Error in regex '" + regex + "' at offset " + ConvToStr(offset) + ": " + error) { }
+};
diff --git a/include/modules/sasl.h b/include/modules/sasl.h
new file mode 100644
index 000000000..321711a68
--- /dev/null
+++ b/include/modules/sasl.h
@@ -0,0 +1,31 @@
+/*
+ * InspIRCd -- Internet Relay Chat Daemon
+ *
+ * Copyright (C) 2010 Daniel De Graaf <danieldg@inspircd.org>
+ *
+ * This file is part of InspIRCd. InspIRCd is free software: you can
+ * redistribute it and/or modify it under the terms of the GNU General Public
+ * License as published by the Free Software Foundation, version 2.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+
+#pragma once
+
+class SASLFallback : public Event
+{
+ public:
+ const parameterlist& params;
+ SASLFallback(Module* me, const parameterlist& p)
+ : Event(me, "sasl_fallback"), params(p)
+ {
+ Send();
+ }
+};
diff --git a/include/modules/spanningtree.h b/include/modules/spanningtree.h
new file mode 100644
index 000000000..99f4f9fc4
--- /dev/null
+++ b/include/modules/spanningtree.h
@@ -0,0 +1,40 @@
+/*
+ * InspIRCd -- Internet Relay Chat Daemon
+ *
+ * Copyright (C) 2009 Daniel De Graaf <danieldg@inspircd.org>
+ *
+ * This file is part of InspIRCd. InspIRCd is free software: you can
+ * redistribute it and/or modify it under the terms of the GNU General Public
+ * License as published by the Free Software Foundation, version 2.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+
+#pragma once
+
+struct AddServerEvent : public Event
+{
+ const std::string servername;
+ AddServerEvent(Module* me, const std::string& name)
+ : Event(me, "new_server"), servername(name)
+ {
+ Send();
+ }
+};
+
+struct DelServerEvent : public Event
+{
+ const std::string servername;
+ DelServerEvent(Module* me, const std::string& name)
+ : Event(me, "lost_server"), servername(name)
+ {
+ Send();
+ }
+};
diff --git a/include/modules/sql.h b/include/modules/sql.h
new file mode 100644
index 000000000..3f378d8b8
--- /dev/null
+++ b/include/modules/sql.h
@@ -0,0 +1,184 @@
+/*
+ * InspIRCd -- Internet Relay Chat Daemon
+ *
+ * Copyright (C) 2010 Daniel De Graaf <danieldg@inspircd.org>
+ *
+ * This file is part of InspIRCd. InspIRCd is free software: you can
+ * redistribute it and/or modify it under the terms of the GNU General Public
+ * License as published by the Free Software Foundation, version 2.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+
+#pragma once
+
+/** Defines the error types which SQLerror may be set to
+ */
+enum SQLerrorNum { SQL_NO_ERROR, SQL_BAD_DBID, SQL_BAD_CONN, SQL_QSEND_FAIL, SQL_QREPLY_FAIL };
+
+/** A list of format parameters for an SQLquery object.
+ */
+typedef std::vector<std::string> ParamL;
+
+typedef std::map<std::string, std::string> ParamM;
+
+class SQLEntry
+{
+ public:
+ std::string value;
+ bool nul;
+ SQLEntry() : nul(true) {}
+ SQLEntry(const std::string& v) : value(v), nul(false) {}
+ inline operator std::string&() { return value; }
+};
+
+typedef std::vector<SQLEntry> SQLEntries;
+
+/**
+ * Result of an SQL query. Only valid inside OnResult
+ */
+class SQLResult : public classbase
+{
+ public:
+ /**
+ * Return the number of rows in the result.
+ *
+ * Note that if you have perfomed an INSERT or UPDATE query or other
+ * query which will not return rows, this will return the number of
+ * affected rows. In this case you SHOULD NEVER access any of the result
+ * set rows, as there aren't any!
+ * @returns Number of rows in the result set.
+ */
+ virtual int Rows() = 0;
+
+ /**
+ * Return a single row (result of the query). The internal row counter
+ * is incremented by one.
+ *
+ * @param result Storage for the result data.
+ * @returns true if there was a row, false if no row exists (end of
+ * iteration)
+ */
+ virtual bool GetRow(SQLEntries& result) = 0;
+
+ /** Returns column names for the items in this row
+ */
+ virtual void GetCols(std::vector<std::string>& result) = 0;
+};
+
+/** SQLerror holds the error state of a request.
+ * The error string varies from database software to database software
+ * and should be used to display informational error messages to users.
+ */
+class SQLerror
+{
+ public:
+ /** The error id
+ */
+ SQLerrorNum id;
+
+ /** The error string
+ */
+ std::string str;
+
+ /** Initialize an SQLerror
+ * @param i The error ID to set
+ * @param s The (optional) error string to set
+ */
+ SQLerror(SQLerrorNum i, const std::string &s = "")
+ : id(i), str(s)
+ {
+ }
+
+ /** Return the error string for an error
+ */
+ const char* Str()
+ {
+ if(str.length())
+ return str.c_str();
+
+ switch(id)
+ {
+ case SQL_BAD_DBID:
+ return "Invalid database ID";
+ case SQL_BAD_CONN:
+ return "Invalid connection";
+ case SQL_QSEND_FAIL:
+ return "Sending query failed";
+ case SQL_QREPLY_FAIL:
+ return "Getting query result failed";
+ default:
+ return "Unknown error";
+ }
+ }
+};
+
+/**
+ * Object representing an SQL query. This should be allocated on the heap and
+ * passed to an SQLProvider, which will free it when the query is complete or
+ * when the querying module is unloaded.
+ *
+ * You should store whatever information is needed to have the callbacks work in
+ * this object (UID of user, channel name, etc).
+ */
+class SQLQuery : public classbase
+{
+ public:
+ ModuleRef creator;
+
+ SQLQuery(Module* Creator) : creator(Creator) {}
+ virtual ~SQLQuery() {}
+
+ virtual void OnResult(SQLResult& result) = 0;
+ /**
+ * Called when the query fails
+ */
+ virtual void OnError(SQLerror& error) { }
+};
+
+/**
+ * Provider object for SQL servers
+ */
+class SQLProvider : public DataProvider
+{
+ public:
+ SQLProvider(Module* Creator, const std::string& Name) : DataProvider(Creator, Name) {}
+ /** Submit an asynchronous SQL request
+ * @param callback The result reporting point
+ * @param query The hardcoded query string. If you have parameters to substitute, see below.
+ */
+ virtual void submit(SQLQuery* callback, const std::string& query) = 0;
+
+ /** Submit an asynchronous SQL request
+ * @param callback The result reporting point
+ * @param format The simple parameterized query string ('?' parameters)
+ * @param p Parameters to fill in for the '?' entries
+ */
+ virtual void submit(SQLQuery* callback, const std::string& format, const ParamL& p) = 0;
+
+ /** Submit an asynchronous SQL request.
+ * @param callback The result reporting point
+ * @param format The parameterized query string ('$name' parameters)
+ * @param p Parameters to fill in for the '$name' entries
+ */
+ virtual void submit(SQLQuery* callback, const std::string& format, const ParamM& p) = 0;
+
+ /** Convenience function to prepare a map from a User* */
+ void PopulateUserInfo(User* user, ParamM& userinfo)
+ {
+ userinfo["nick"] = user->nick;
+ userinfo["host"] = user->host;
+ userinfo["ip"] = user->GetIPString();
+ userinfo["gecos"] = user->fullname;
+ userinfo["ident"] = user->ident;
+ userinfo["server"] = user->server->GetName();
+ userinfo["uuid"] = user->uuid;
+ }
+};
diff --git a/include/modules/ssl.h b/include/modules/ssl.h
new file mode 100644
index 000000000..0f58e0b7b
--- /dev/null
+++ b/include/modules/ssl.h
@@ -0,0 +1,246 @@
+/*
+ * InspIRCd -- Internet Relay Chat Daemon
+ *
+ * Copyright (C) 2009 Daniel De Graaf <danieldg@inspircd.org>
+ * Copyright (C) 2006 Craig Edwards <craigedwards@brainbox.cc>
+ *
+ * This file is part of InspIRCd. InspIRCd is free software: you can
+ * redistribute it and/or modify it under the terms of the GNU General Public
+ * License as published by the Free Software Foundation, version 2.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+
+#pragma once
+
+#include <string>
+#include "iohook.h"
+
+/** ssl_cert is a class which abstracts SSL certificate
+ * and key information.
+ *
+ * Because gnutls and openssl represent key information in
+ * wildly different ways, this class allows it to be accessed
+ * in a unified manner. These classes are attached to ssl-
+ * connected local users using SSLCertExt
+ */
+class ssl_cert : public refcountbase
+{
+ public:
+ std::string dn;
+ std::string issuer;
+ std::string error;
+ std::string fingerprint;
+ bool trusted, invalid, unknownsigner, revoked;
+
+ ssl_cert() : trusted(false), invalid(true), unknownsigner(true), revoked(false) {}
+
+ /** Get certificate distinguished name
+ * @return Certificate DN
+ */
+ const std::string& GetDN()
+ {
+ return dn;
+ }
+
+ /** Get Certificate issuer
+ * @return Certificate issuer
+ */
+ const std::string& GetIssuer()
+ {
+ return issuer;
+ }
+
+ /** Get error string if an error has occured
+ * @return The error associated with this users certificate,
+ * or an empty string if there is no error.
+ */
+ const std::string& GetError()
+ {
+ return error;
+ }
+
+ /** Get key fingerprint.
+ * @return The key fingerprint as a hex string.
+ */
+ const std::string& GetFingerprint()
+ {
+ return fingerprint;
+ }
+
+ /** Get trust status
+ * @return True if this is a trusted certificate
+ * (the certificate chain validates)
+ */
+ bool IsTrusted()
+ {
+ return trusted;
+ }
+
+ /** Get validity status
+ * @return True if the certificate itself is
+ * correctly formed.
+ */
+ bool IsInvalid()
+ {
+ return invalid;
+ }
+
+ /** Get signer status
+ * @return True if the certificate appears to be
+ * self-signed.
+ */
+ bool IsUnknownSigner()
+ {
+ return unknownsigner;
+ }
+
+ /** Get revokation status.
+ * @return True if the certificate is revoked.
+ * Note that this only works properly for GnuTLS
+ * right now.
+ */
+ bool IsRevoked()
+ {
+ return revoked;
+ }
+
+ bool IsCAVerified()
+ {
+ return trusted && !invalid && !revoked && !unknownsigner && error.empty();
+ }
+
+ std::string GetMetaLine()
+ {
+ std::stringstream value;
+ bool hasError = !error.empty();
+ value << (IsInvalid() ? "v" : "V") << (IsTrusted() ? "T" : "t") << (IsRevoked() ? "R" : "r")
+ << (IsUnknownSigner() ? "s" : "S") << (hasError ? "E" : "e") << " ";
+ if (hasError)
+ value << GetError();
+ else
+ value << GetFingerprint() << " " << GetDN() << " " << GetIssuer();
+ return value.str();
+ }
+};
+
+class SSLIOHook : public IOHook
+{
+ protected:
+ /** Peer SSL certificate, set by the SSL module
+ */
+ reference<ssl_cert> certificate;
+
+ public:
+ SSLIOHook(IOHookProvider* hookprov)
+ : IOHook(hookprov)
+ {
+ }
+
+ /**
+ * Get the certificate sent by this peer
+ * @return The SSL certificate sent by the peer, NULL if no cert was sent
+ */
+ ssl_cert* GetCertificate() const
+ {
+ return certificate;
+ }
+
+ /**
+ * Get the fingerprint of the peer's certificate
+ * @return The fingerprint of the SSL client certificate sent by the peer,
+ * empty if no cert was sent
+ */
+ std::string GetFingerprint() const
+ {
+ ssl_cert* cert = GetCertificate();
+ if (cert)
+ return cert->GetFingerprint();
+ return "";
+ }
+};
+
+/** Helper functions for obtaining SSL client certificates and key fingerprints
+ * from StreamSockets
+ */
+class SSLClientCert
+{
+ public:
+ /**
+ * Get the client certificate from a socket
+ * @param sock The socket to get the certificate from, the socket does not have to use SSL
+ * @return The SSL client certificate information, NULL if the peer is not using SSL
+ */
+ static ssl_cert* GetCertificate(StreamSocket* sock)
+ {
+ IOHook* iohook = sock->GetIOHook();
+ if ((!iohook) || (iohook->prov->type != IOHookProvider::IOH_SSL))
+ return NULL;
+
+ SSLIOHook* ssliohook = static_cast<SSLIOHook*>(iohook);
+ return ssliohook->GetCertificate();
+ }
+
+ /**
+ * Get the fingerprint of a client certificate from a socket
+ * @param sock The socket to get the certificate fingerprint from, the
+ * socket does not have to use SSL
+ * @return The key fingerprint from the SSL certificate sent by the peer,
+ * empty if no cert was sent or the peer is not using SSL
+ */
+ static std::string GetFingerprint(StreamSocket* sock)
+ {
+ ssl_cert* cert = SSLClientCert::GetCertificate(sock);
+ if (cert)
+ return cert->GetFingerprint();
+ return "";
+ }
+};
+
+class UserCertificateAPIBase : public DataProvider
+{
+ public:
+ UserCertificateAPIBase(Module* parent)
+ : DataProvider(parent, "m_sslinfo_api")
+ {
+ }
+
+ /** Get the SSL certificate of a user
+ * @param user The user whose certificate to get, user may be remote
+ * @return The SSL certificate of the user or NULL if the user is not using SSL
+ */
+ virtual ssl_cert* GetCertificate(User* user) = 0;
+
+ /** Get the key fingerprint from a user's certificate
+ * @param user The user whose key fingerprint to get, user may be remote
+ * @return The key fingerprint from the user's SSL certificate or an empty string
+ * if the user is not using SSL or did not provide a client certificate
+ */
+ std::string GetFingerprint(User* user)
+ {
+ ssl_cert* cert = GetCertificate(user);
+ if (cert)
+ return cert->GetFingerprint();
+ return "";
+ }
+};
+
+/** API implemented by m_sslinfo that allows modules to retrive the SSL certificate
+ * information of local and remote users. It can also be used to find out whether a
+ * user is using SSL or not.
+ */
+class UserCertificateAPI : public dynamic_reference<UserCertificateAPIBase>
+{
+ public:
+ UserCertificateAPI(Module* parent)
+ : dynamic_reference<UserCertificateAPIBase>(parent, "m_sslinfo_api")
+ {
+ }
+};