diff options
Diffstat (limited to 'modules/extra')
-rw-r--r-- | modules/extra/ldap.cpp (renamed from modules/extra/m_ldap.cpp) | 51 | ||||
-rw-r--r-- | modules/extra/ldap_authentication.cpp (renamed from modules/extra/m_ldap_authentication.cpp) | 117 | ||||
-rw-r--r-- | modules/extra/ldap_oper.cpp (renamed from modules/extra/m_ldap_oper.cpp) | 55 | ||||
-rw-r--r-- | modules/extra/m_regex_pcre.cpp | 83 | ||||
-rw-r--r-- | modules/extra/m_regex_posix.cpp | 84 | ||||
-rw-r--r-- | modules/extra/m_regex_tre.cpp | 85 | ||||
-rw-r--r-- | modules/extra/m_sql_oper.cpp | 180 | ||||
-rw-r--r-- | modules/extra/m_sqlite.cpp | 335 | ||||
-rw-r--r-- | modules/extra/mysql.cpp (renamed from modules/extra/m_mysql.cpp) | 287 | ||||
-rw-r--r-- | modules/extra/rest.cpp | 426 | ||||
-rw-r--r-- | modules/extra/sasl_dh-aes.cpp | 184 | ||||
-rw-r--r-- | modules/extra/sasl_dh-blowfish.cpp | 194 | ||||
-rw-r--r-- | modules/extra/sql_authentication.cpp (renamed from modules/extra/m_sql_authentication.cpp) | 56 | ||||
-rw-r--r-- | modules/extra/sql_log.cpp (renamed from modules/extra/m_sql_log.cpp) | 44 | ||||
-rw-r--r-- | modules/extra/sql_oper.cpp | 170 | ||||
-rw-r--r-- | modules/extra/ssl_gnutls.cpp (renamed from modules/extra/m_ssl_gnutls.cpp) | 54 | ||||
-rw-r--r-- | modules/extra/ssl_openssl.cpp (renamed from modules/extra/m_ssl_openssl.cpp) | 57 | ||||
-rw-r--r-- | modules/extra/stats/chanstats.cpp (renamed from modules/extra/stats/m_chanstats.cpp) | 96 | ||||
-rw-r--r-- | modules/extra/stats/cs_fantasy_stats.cpp | 24 | ||||
-rw-r--r-- | modules/extra/stats/cs_fantasy_top.cpp | 22 | ||||
-rw-r--r-- | modules/extra/stats/irc2sql/irc2sql.cpp | 20 | ||||
-rw-r--r-- | modules/extra/stats/irc2sql/irc2sql.h | 50 |
22 files changed, 1520 insertions, 1154 deletions
diff --git a/modules/extra/m_ldap.cpp b/modules/extra/ldap.cpp index 27bb3ef50..b5c37d7cf 100644 --- a/modules/extra/m_ldap.cpp +++ b/modules/extra/ldap.cpp @@ -1,12 +1,20 @@ /* + * Anope IRC Services * - * (C) 2011-2016 Anope Team - * Contact us at team@anope.org + * Copyright (C) 2011-2016 Anope Team <team@anope.org> * - * Please read COPYING and README for further details. + * This file is part of Anope. Anope 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. * - * Based on the original code of Epona by Lara. - * Based on the original code of Services by Andy Church. + * 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 see <http://www.gnu.org/licenses/>. */ /* RequiredLibraries: ldap_r,lber */ @@ -270,18 +278,18 @@ class LDAPService : public LDAPProvider, public Thread, public Condition ldap_unbind_ext(this->con, NULL, NULL); } - void BindAsAdmin(LDAPInterface *i) anope_override + void BindAsAdmin(LDAPInterface *i) override { this->Bind(i, this->admin_binddn, this->admin_pass); } - void Bind(LDAPInterface *i, const Anope::string &who, const Anope::string &pass) anope_override + void Bind(LDAPInterface *i, const Anope::string &who, const Anope::string &pass) override { LDAPBind *b = new LDAPBind(this, i, who, pass); QueueRequest(b); } - void Search(LDAPInterface *i, const Anope::string &base, const Anope::string &filter) anope_override + void Search(LDAPInterface *i, const Anope::string &base, const Anope::string &filter) override { if (i == NULL) throw LDAPException("No interface"); @@ -290,7 +298,7 @@ class LDAPService : public LDAPProvider, public Thread, public Condition QueueRequest(s); } - void Add(LDAPInterface *i, const Anope::string &dn, LDAPMods &attributes) anope_override + void Add(LDAPInterface *i, const Anope::string &dn, LDAPMods &attributes) override { LDAPAdd *add = new LDAPAdd(this, i, dn, attributes); QueueRequest(add); @@ -430,6 +438,7 @@ class LDAPService : public LDAPProvider, public Thread, public Condition }; class ModuleLDAP : public Module, public Pipe + , public EventHook<Event::ModuleUnload> { std::map<Anope::string, LDAPService *> LDAPServices; @@ -452,7 +461,7 @@ class ModuleLDAP : public Module, public Pipe LDAPServices.clear(); } - void OnReload(Configuration::Conf *config) anope_override + void OnReload(Configuration::Conf *config) override { Configuration::Block *conf = config->GetModule(this); @@ -465,12 +474,12 @@ class ModuleLDAP : public Module, public Pipe ++it; for (i = 0; i < conf->CountBlock("ldap"); ++i) - if (conf->GetBlock("ldap", i)->Get<const Anope::string>("name", "ldap/main") == cname) + if (conf->GetBlock("ldap", i)->Get<Anope::string>("name", "ldap/main") == cname) break; if (i == conf->CountBlock("ldap")) { - Log(LOG_NORMAL, "ldap") << "LDAP: Removing server connection " << cname; + Log(LogType::NORMAL, "ldap") << "LDAP: Removing server connection " << cname; s->SetExitState(); s->Wakeup(); @@ -484,13 +493,13 @@ class ModuleLDAP : public Module, public Pipe { Configuration::Block *ldap = conf->GetBlock("ldap", i); - const Anope::string &connname = ldap->Get<const Anope::string>("name", "ldap/main"); + const Anope::string &connname = ldap->Get<Anope::string>("name", "ldap/main"); if (this->LDAPServices.find(connname) == this->LDAPServices.end()) { - const Anope::string &server = ldap->Get<const Anope::string>("server", "127.0.0.1"); - const Anope::string &admin_binddn = ldap->Get<const Anope::string>("admin_binddn"); - const Anope::string &admin_password = ldap->Get<const Anope::string>("admin_password"); + const Anope::string &server = ldap->Get<Anope::string>("server", "127.0.0.1"); + const Anope::string &admin_binddn = ldap->Get<Anope::string>("admin_binddn"); + const Anope::string &admin_password = ldap->GetAnope::string>("admin_password"); try { @@ -498,17 +507,17 @@ class ModuleLDAP : public Module, public Pipe ss->Start(); this->LDAPServices.insert(std::make_pair(connname, ss)); - Log(LOG_NORMAL, "ldap") << "LDAP: Successfully initialized server " << connname << " (" << server << ")"; + Log(LogType::NORMAL, "ldap") << "LDAP: Successfully initialized server " << connname << " (" << server << ")"; } catch (const LDAPException &ex) { - Log(LOG_NORMAL, "ldap") << "LDAP: " << ex.GetReason(); + Log(LogType::NORMAL, "ldap") << "LDAP: " << ex.GetReason(); } } } } - void OnModuleUnload(User *, Module *m) anope_override + void OnModuleUnload(User *, Module *m) override { for (std::map<Anope::string, LDAPService *>::iterator it = this->LDAPServices.begin(); it != this->LDAPServices.end(); ++it) { @@ -545,7 +554,7 @@ class ModuleLDAP : public Module, public Pipe } } - void OnNotify() anope_override + void OnNotify() override { for (std::map<Anope::string, LDAPService *>::iterator it = this->LDAPServices.begin(); it != this->LDAPServices.end(); ++it) { @@ -575,7 +584,7 @@ class ModuleLDAP : public Module, public Pipe delete req; } - } + } } }; diff --git a/modules/extra/m_ldap_authentication.cpp b/modules/extra/ldap_authentication.cpp index 0f18916b6..722284fb4 100644 --- a/modules/extra/m_ldap_authentication.cpp +++ b/modules/extra/ldap_authentication.cpp @@ -1,13 +1,25 @@ /* + * Anope IRC Services * - * (C) 2011-2016 Anope Team - * Contact us at team@anope.org + * Copyright (C) 2011-2016 Anope Team <team@anope.org> * - * Please read COPYING and README for further details. + * This file is part of Anope. Anope 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 see <http://www.gnu.org/licenses/>. */ #include "module.h" #include "modules/ldap.h" +#include "modules/nickserv.h" static Module *me; @@ -29,7 +41,7 @@ struct IdentifyInfo { req->Hold(me); } - + ~IdentifyInfo() { req->Release(me); @@ -53,7 +65,7 @@ class IdentifyInterface : public LDAPInterface delete this; } - void OnResult(const LDAPResult &r) anope_override + void OnResult(const LDAPResult &r) override { if (!ii->lprov) return; @@ -68,7 +80,7 @@ class IdentifyInterface : public LDAPInterface { const LDAPAttributes &attr = r.get(0); ii->dn = attr.get("dn"); - Log(LOG_DEBUG) << "m_ldap_authenticationn: binding as " << ii->dn; + Log(LogType::DEBUG) << "m_ldap_authenticationn: binding as " << ii->dn; ii->lprov->Bind(new IdentifyInterface(this->owner, ii), ii->dn, ii->req->GetPassword()); ii = NULL; @@ -87,7 +99,7 @@ class IdentifyInterface : public LDAPInterface Anope::string sf = search_filter.replace_all_cs("%account", ii->req->GetAccount()).replace_all_cs("%object_class", object_class); try { - Log(LOG_DEBUG) << "m_ldap_authentication: searching for " << sf; + Log(LogType::DEBUG) << "m_ldap_authentication: searching for " << sf; ii->lprov->Search(new IdentifyInterface(this->owner, ii), basedn, sf); ii->admin_bind = false; ii = NULL; @@ -99,20 +111,20 @@ class IdentifyInterface : public LDAPInterface } else { - NickAlias *na = NickAlias::Find(ii->req->GetAccount()); + NickServ::Nick *na = NickServ::FindNick(ii->req->GetAccount()); if (na == NULL) { - na = new NickAlias(ii->req->GetAccount(), new NickCore(ii->req->GetAccount())); - na->last_realname = ii->user ? ii->user->realname : ii->req->GetAccount(); - FOREACH_MOD(OnNickRegister, (ii->user, na, ii->req->GetPassword())); - BotInfo *NickServ = Config->GetClient("NickServ"); + na = new NickServ::Nick(ii->req->GetAccount(), new NickServ::Account(ii->req->GetAccount())); + na->SetLastRealname(ii->user ? ii->user->realname : ii->req->GetAccount()); + NickServ::EventManager::Get()->Dispatch(&NickServ::Event::NickRegister::OnNickRegister, ii->user, na, ii->req->GetPassword());; + ServiceBot *NickServ = Config->GetClient("NickServ"); if (ii->user && NickServ) - ii->user->SendMessage(NickServ, _("Your account \002%s\002 has been successfully created."), na->nick.c_str()); + ii->user->SendMessage(NickServ, _("Your account \002%s\002 has been successfully created."), na->GetNick().c_str()); } // encrypt and store the password in the nickcore - Anope::Encrypt(ii->req->GetPassword(), na->nc->pass); + Anope::Encrypt(ii->req->GetPassword(), na->GetAccount()->pass); - na->nc->Extend<Anope::string>("m_ldap_authentication_dn", ii->dn); + na->GetAccount()->Extend<Anope::string>("m_ldap_authentication_dn", ii->dn); ii->req->Success(me); } break; @@ -122,7 +134,7 @@ class IdentifyInterface : public LDAPInterface } } - void OnError(const LDAPResult &r) anope_override + void OnError(const LDAPResult &r) override { } }; @@ -139,7 +151,7 @@ class OnIdentifyInterface : public LDAPInterface delete this; } - void OnResult(const LDAPResult &r) anope_override + void OnResult(const LDAPResult &r) override { User *u = User::Find(uid); @@ -151,13 +163,13 @@ class OnIdentifyInterface : public LDAPInterface const LDAPAttributes &attr = r.get(0); Anope::string email = attr.get(email_attribute); - if (!email.equals_ci(u->Account()->email)) + if (!email.equals_ci(u->Account()->GetEmail())) { - u->Account()->email = email; - BotInfo *NickServ = Config->GetClient("NickServ"); + u->Account()->GetEmail() = email; + ServiceBot *NickServ = Config->GetClient("NickServ"); if (NickServ) u->SendMessage(NickServ, _("Your email has been updated to \002%s\002"), email.c_str()); - Log(this->owner) << "Updated email address for " << u->nick << " (" << u->Account()->display << ") to " << email; + Log(this->owner) << "Updated email address for " << u->nick << " (" << u->Account()->GetDisplay() << ") to " << email; } } catch (const LDAPException &ex) @@ -166,7 +178,7 @@ class OnIdentifyInterface : public LDAPInterface } } - void OnError(const LDAPResult &r) anope_override + void OnError(const LDAPResult &r) override { Log(this->owner) << r.error; } @@ -177,18 +189,22 @@ class OnRegisterInterface : public LDAPInterface public: OnRegisterInterface(Module *m) : LDAPInterface(m) { } - void OnResult(const LDAPResult &r) anope_override + void OnResult(const LDAPResult &r) override { Log(this->owner) << "Successfully added newly created account to LDAP"; } - void OnError(const LDAPResult &r) anope_override + void OnError(const LDAPResult &r) override { Log(this->owner) << "Error adding newly created account to LDAP: " << r.getError(); } }; class ModuleLDAPAuthentication : public Module + , public EventHook<Event::PreCommand> + , public EventHook<Event::CheckAuthentication> + , public EventHook<Event::NickIdentify> + , public EventHook<NickServ::Event::NickRegister> { ServiceReference<LDAPProvider> ldap; OnRegisterInterface orinterface; @@ -198,38 +214,39 @@ class ModuleLDAPAuthentication : public Module Anope::string password_attribute; Anope::string disable_register_reason; Anope::string disable_email_reason; + public: - ModuleLDAPAuthentication(const Anope::string &modname, const Anope::string &creator) : - Module(modname, creator, EXTRA | VENDOR), ldap("LDAPProvider", "ldap/main"), orinterface(this), - dn(this, "m_ldap_authentication_dn") + ModuleLDAPAuthentication(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, EXTRA | VENDOR) + , EventHook<Event::PreCommand>("OnPreCommand", EventHook<Event::PreCommand>::Priority::FIRST) + , EventHook<Event::CheckAuthentication>("OnCheckAuthentication", EventHook<Event::CheckAuthentication>::Priority::FIRST) + , EventHook<Event::NickIdentify>("OnNickIdentify", EventHook<Event::NickIdentify>::Priority::FIRST) + , EventHook<NickServ::Event::NickRegister>("OnNickRegister", EventHook<NickServ::Event::NickRegister>::Priority::FIRST) + , ldap("LDAPProvider", "ldap/main") + , orinterface(this) + , dn(this, "m_ldap_authentication_dn") { me = this; } - void Prioritize() anope_override - { - ModuleManager::SetPriority(this, PRIORITY_FIRST); - } - - void OnReload(Configuration::Conf *config) anope_override + void OnReload(Configuration::Conf *config) override { Configuration::Block *conf = Config->GetModule(this); - basedn = conf->Get<const Anope::string>("basedn"); - search_filter = conf->Get<const Anope::string>("search_filter"); - object_class = conf->Get<const Anope::string>("object_class"); - username_attribute = conf->Get<const Anope::string>("username_attribute"); - this->password_attribute = conf->Get<const Anope::string>("password_attribute"); - email_attribute = conf->Get<const Anope::string>("email_attribute"); - this->disable_register_reason = conf->Get<const Anope::string>("disable_register_reason"); - this->disable_email_reason = conf->Get<const Anope::string>("disable_email_reason"); + basedn = conf->Get<Anope::string>("basedn"); + search_filter = conf->Get<Anope::string>("search_filter"); + object_class = conf->Get<Anope::string>("object_class"); + username_attribute = conf->Get<Anope::string>("username_attribute"); + this->password_attribute = conf->Get<Anope::string>("password_attribute"); + email_attribute = conf->Get<Anope::string>("email_attribute"); + this->disable_register_reason = conf->Get<Anope::string>("disable_register_reason"); + this->disable_email_reason = conf->Get<Anope::string>("disable_email_reason"); if (!email_attribute.empty()) /* Don't complain to users about how they need to update their email, we will do it for them */ - config->GetModule("nickserv")->Set("forceemail", "false"); + config->GetModule("nickserv/main")->Set("forceemail", "false"); } - EventReturn OnPreCommand(CommandSource &source, Command *command, std::vector<Anope::string> ¶ms) anope_override + EventReturn OnPreCommand(CommandSource &source, Command *command, std::vector<Anope::string> ¶ms) override { if (!this->disable_register_reason.empty()) { @@ -249,7 +266,7 @@ class ModuleLDAPAuthentication : public Module return EVENT_CONTINUE; } - void OnCheckAuthentication(User *u, IdentifyRequest *req) anope_override + void OnCheckAuthentication(User *u, IdentifyRequest *req) override { if (!this->ldap) return; @@ -258,7 +275,7 @@ class ModuleLDAPAuthentication : public Module this->ldap->BindAsAdmin(new IdentifyInterface(this, ii)); } - void OnNickIdentify(User *u) anope_override + void OnNickIdentify(User *u) override { if (email_attribute.empty() || !this->ldap) return; @@ -270,7 +287,7 @@ class ModuleLDAPAuthentication : public Module this->ldap->Search(new OnIdentifyInterface(this, u->GetUID()), *d, "(" + email_attribute + "=*)"); } - void OnNickRegister(User *, NickAlias *na, const Anope::string &pass) anope_override + void OnNickRegister(User *, NickServ::Nick *na, const Anope::string &pass) override { if (!this->disable_register_reason.empty() || !this->ldap) return; @@ -285,18 +302,18 @@ class ModuleLDAPAuthentication : public Module attributes[0].values.push_back(object_class); attributes[1].name = username_attribute; - attributes[1].values.push_back(na->nick); + attributes[1].values.push_back(na->GetNick()); - if (!na->nc->email.empty()) + if (!na->GetAccount()->GetEmail().empty()) { attributes[2].name = email_attribute; - attributes[2].values.push_back(na->nc->email); + attributes[2].values.push_back(na->GetAccount()->GetEmail()); } attributes[3].name = this->password_attribute; attributes[3].values.push_back(pass); - Anope::string new_dn = username_attribute + "=" + na->nick + "," + basedn; + Anope::string new_dn = username_attribute + "=" + na->GetNick() + "," + basedn; this->ldap->Add(&this->orinterface, new_dn, attributes); } }; diff --git a/modules/extra/m_ldap_oper.cpp b/modules/extra/ldap_oper.cpp index 23ebf1a6b..5157a6f10 100644 --- a/modules/extra/m_ldap_oper.cpp +++ b/modules/extra/ldap_oper.cpp @@ -1,9 +1,20 @@ /* + * Anope IRC Services * - * (C) 2011-2016 Anope Team - * Contact us at team@anope.org + * Copyright (C) 2011-2016 Anope Team <team@anope.org> * - * Please read COPYING and README for further details. + * This file is part of Anope. Anope 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 see <http://www.gnu.org/licenses/>. */ #include "module.h" @@ -21,12 +32,12 @@ class IdentifyInterface : public LDAPInterface { } - void OnResult(const LDAPResult &r) anope_override + void OnResult(const LDAPResult &r) override { if (!u || !u->Account()) return; - NickCore *nc = u->Account(); + NickServ::Account *nc = u->Account(); try { @@ -46,7 +57,8 @@ class IdentifyInterface : public LDAPInterface o = new Oper(u->nick, ot); my_opers.insert(o); nc->o = o; - Log(this->owner) << "Tied " << u->nick << " (" << nc->display << ") to opertype " << ot->GetName(); + + Log(this->owner) << "Tied " << u->nick << " (" << nc->GetDisplay() << ") to opertype " << ot->GetName(); } } catch (const LDAPException &ex) @@ -60,12 +72,12 @@ class IdentifyInterface : public LDAPInterface } nc->o = NULL; - Log(this->owner) << "Removed services operator from " << u->nick << " (" << nc->display << ")"; + Log(this->owner) << "Removed services operator from " << u->nick << " (" << nc->GetDisplay() << ")"; } } } - void OnError(const LDAPResult &r) anope_override + void OnError(const LDAPResult &r) override { } @@ -76,6 +88,8 @@ class IdentifyInterface : public LDAPInterface }; class LDAPOper : public Module + , public EventHook<Event::NickIdentify> + , public EventHook<Event::DelCore> { ServiceReference<LDAPProvider> ldap; @@ -84,28 +98,29 @@ class LDAPOper : public Module Anope::string basedn; Anope::string filter; public: - LDAPOper(const Anope::string &modname, const Anope::string &creator) : - Module(modname, creator, EXTRA | VENDOR), ldap("LDAPProvider", "ldap/main") + LDAPOper(const Anope::string &modname, const Anope::string &creator) + : Module(modname, creator, EXTRA | VENDOR) + , ldap("LDAPProvider", "ldap/main") { } - void OnReload(Configuration::Conf *conf) anope_override + void OnReload(Configuration::Conf *conf) override { Configuration::Block *config = Config->GetModule(this); - this->binddn = config->Get<const Anope::string>("binddn"); - this->password = config->Get<const Anope::string>("password"); - this->basedn = config->Get<const Anope::string>("basedn"); - this->filter = config->Get<const Anope::string>("filter"); - opertype_attribute = config->Get<const Anope::string>("opertype_attribute"); + this->binddn = config->Get<Anope::string>("binddn"); + this->password = config->Get<Anope::string>("password"); + this->basedn = config->Get<Anope::string>("basedn"); + this->filter = config->Get<Anope::string>("filter"); + opertype_attribute = config->Get<Anope::string>("opertype_attribute"); for (std::set<Oper *>::iterator it = my_opers.begin(), it_end = my_opers.end(); it != it_end; ++it) delete *it; my_opers.clear(); } - void OnNickIdentify(User *u) anope_override + void OnNickIdentify(User *u) override { try { @@ -115,8 +130,8 @@ class LDAPOper : public Module throw LDAPException("Could not search LDAP for opertype settings, invalid configuration."); if (!this->binddn.empty()) - this->ldap->Bind(NULL, this->binddn.replace_all_cs("%a", u->Account()->display), this->password.c_str()); - this->ldap->Search(new IdentifyInterface(this, u), this->basedn, this->filter.replace_all_cs("%a", u->Account()->display)); + this->ldap->Bind(NULL, this->binddn.replace_all_cs("%a", u->Account()->GetDisplay()), this->password.c_str()); + this->ldap->Search(new IdentifyInterface(this, u), this->basedn, this->filter.replace_all_cs("%a", u->Account()->GetDisplay())); } catch (const LDAPException &ex) { @@ -124,7 +139,7 @@ class LDAPOper : public Module } } - void OnDelCore(NickCore *nc) anope_override + void OnDelCore(NickServ::Account *nc) override { if (nc->o != NULL && my_opers.count(nc->o) > 0) { diff --git a/modules/extra/m_regex_pcre.cpp b/modules/extra/m_regex_pcre.cpp deleted file mode 100644 index fa804c14e..000000000 --- a/modules/extra/m_regex_pcre.cpp +++ /dev/null @@ -1,83 +0,0 @@ -/* - * - * (C) 2012-2016 Anope Team - * Contact us at team@anope.org - * - * Please read COPYING and README for further details. - */ - -/* RequiredLibraries: pcre */ -/* RequiredWindowsLibraries: libpcre */ - -#include "module.h" -#include <pcre.h> - -class PCRERegex : public Regex -{ - pcre *regex; - - public: - PCRERegex(const Anope::string &expr) : Regex(expr) - { - const char *error; - int erroffset; - this->regex = pcre_compile(expr.c_str(), PCRE_CASELESS, &error, &erroffset, NULL); - if (!this->regex) - throw RegexException("Error in regex " + expr + " at offset " + stringify(erroffset) + ": " + error); - } - - ~PCRERegex() - { - pcre_free(this->regex); - } - - bool Matches(const Anope::string &str) - { - return pcre_exec(this->regex, NULL, str.c_str(), str.length(), 0, 0, NULL, 0) > -1; - } -}; - -class PCRERegexProvider : public RegexProvider -{ - public: - PCRERegexProvider(Module *creator) : RegexProvider(creator, "regex/pcre") { } - - Regex *Compile(const Anope::string &expression) anope_override - { - return new PCRERegex(expression); - } -}; - -class ModuleRegexPCRE : public Module -{ - PCRERegexProvider pcre_regex_provider; - - public: - ModuleRegexPCRE(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, EXTRA | VENDOR), - pcre_regex_provider(this) - { - this->SetPermanent(true); - } - - ~ModuleRegexPCRE() - { - for (std::list<XLineManager *>::iterator it = XLineManager::XLineManagers.begin(); it != XLineManager::XLineManagers.end(); ++it) - { - XLineManager *xlm = *it; - const std::vector<XLine *> &xlines = xlm->GetList(); - - for (unsigned int i = 0; i < xlines.size(); ++i) - { - XLine *x = xlines[i]; - - if (x->regex && dynamic_cast<PCRERegex *>(x->regex)) - { - delete x->regex; - x->regex = NULL; - } - } - } - } -}; - -MODULE_INIT(ModuleRegexPCRE) diff --git a/modules/extra/m_regex_posix.cpp b/modules/extra/m_regex_posix.cpp deleted file mode 100644 index 2486ddd70..000000000 --- a/modules/extra/m_regex_posix.cpp +++ /dev/null @@ -1,84 +0,0 @@ -/* - * - * (C) 2012-2016 Anope Team - * Contact us at team@anope.org - * - * Please read COPYING and README for further details. - */ - -#include "module.h" -#include <sys/types.h> -#include <regex.h> - -class POSIXRegex : public Regex -{ - regex_t regbuf; - - public: - POSIXRegex(const Anope::string &expr) : Regex(expr) - { - int err = regcomp(&this->regbuf, expr.c_str(), REG_EXTENDED | REG_NOSUB); - if (err) - { - char buf[BUFSIZE]; - regerror(err, &this->regbuf, buf, sizeof(buf)); - regfree(&this->regbuf); - throw RegexException("Error in regex " + expr + ": " + buf); - } - } - - ~POSIXRegex() - { - regfree(&this->regbuf); - } - - bool Matches(const Anope::string &str) - { - return regexec(&this->regbuf, str.c_str(), 0, NULL, 0) == 0; - } -}; - -class POSIXRegexProvider : public RegexProvider -{ - public: - POSIXRegexProvider(Module *creator) : RegexProvider(creator, "regex/posix") { } - - Regex *Compile(const Anope::string &expression) anope_override - { - return new POSIXRegex(expression); - } -}; - -class ModuleRegexPOSIX : public Module -{ - POSIXRegexProvider posix_regex_provider; - - public: - ModuleRegexPOSIX(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, EXTRA | VENDOR), - posix_regex_provider(this) - { - this->SetPermanent(true); - } - - ~ModuleRegexPOSIX() - { - for (std::list<XLineManager *>::iterator it = XLineManager::XLineManagers.begin(); it != XLineManager::XLineManagers.end(); ++it) - { - XLineManager *xlm = *it; - const std::vector<XLine *> &xlines = xlm->GetList(); - - for (unsigned int i = 0; i < xlines.size(); ++i) - { - XLine *x = xlines[i]; - - if (x->regex && dynamic_cast<POSIXRegex *>(x->regex)) - { - delete x->regex; - x->regex = NULL; - } - } - } - } -}; - -MODULE_INIT(ModuleRegexPOSIX) diff --git a/modules/extra/m_regex_tre.cpp b/modules/extra/m_regex_tre.cpp deleted file mode 100644 index 66411280c..000000000 --- a/modules/extra/m_regex_tre.cpp +++ /dev/null @@ -1,85 +0,0 @@ -/* - * - * (C) 2012-2016 Anope Team - * Contact us at team@anope.org - * - * Please read COPYING and README for further details. - */ - -/* RequiredLibraries: tre */ - -#include "module.h" -#include <tre/regex.h> - -class TRERegex : public Regex -{ - regex_t regbuf; - - public: - TRERegex(const Anope::string &expr) : Regex(expr) - { - int err = regcomp(&this->regbuf, expr.c_str(), REG_EXTENDED | REG_NOSUB); - if (err) - { - char buf[BUFSIZE]; - regerror(err, &this->regbuf, buf, sizeof(buf)); - regfree(&this->regbuf); - throw RegexException("Error in regex " + expr + ": " + buf); - } - } - - ~TRERegex() - { - regfree(&this->regbuf); - } - - bool Matches(const Anope::string &str) - { - return regexec(&this->regbuf, str.c_str(), 0, NULL, 0) == 0; - } -}; - -class TRERegexProvider : public RegexProvider -{ - public: - TRERegexProvider(Module *creator) : RegexProvider(creator, "regex/tre") { } - - Regex *Compile(const Anope::string &expression) anope_override - { - return new TRERegex(expression); - } -}; - -class ModuleRegexTRE : public Module -{ - TRERegexProvider tre_regex_provider; - - public: - ModuleRegexTRE(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, EXTRA | VENDOR), - tre_regex_provider(this) - { - this->SetPermanent(true); - } - - ~ModuleRegexTRE() - { - for (std::list<XLineManager *>::iterator it = XLineManager::XLineManagers.begin(); it != XLineManager::XLineManagers.end(); ++it) - { - XLineManager *xlm = *it; - const std::vector<XLine *> &xlines = xlm->GetList(); - - for (unsigned int i = 0; i < xlines.size(); ++i) - { - XLine *x = xlines[i]; - - if (x->regex && dynamic_cast<TRERegex *>(x->regex)) - { - delete x->regex; - x->regex = NULL; - } - } - } - } -}; - -MODULE_INIT(ModuleRegexTRE) diff --git a/modules/extra/m_sql_oper.cpp b/modules/extra/m_sql_oper.cpp deleted file mode 100644 index b2b2f2d1e..000000000 --- a/modules/extra/m_sql_oper.cpp +++ /dev/null @@ -1,180 +0,0 @@ -/* - * - * (C) 2012-2016 Anope Team - * Contact us at team@anope.org - * - * Please read COPYING and README for further details. - */ - -#include "module.h" -#include "modules/sql.h" - -struct SQLOper : Oper -{ - SQLOper(const Anope::string &n, OperType *o) : Oper(n, o) { } -}; - -class SQLOperResult : public SQL::Interface -{ - Reference<User> user; - - struct SQLOperResultDeleter - { - SQLOperResult *res; - SQLOperResultDeleter(SQLOperResult *r) : res(r) { } - ~SQLOperResultDeleter() { delete res; } - }; - - void Deoper() - { - if (user->Account() && user->Account()->o && dynamic_cast<SQLOper *>(user->Account()->o)) - { - delete user->Account()->o; - user->Account()->o = NULL; - - Log(this->owner) << "m_sql_oper: Removed services operator from " << user->nick << " (" << user->Account()->display << ")"; - - BotInfo *OperServ = Config->GetClient("OperServ"); - user->RemoveMode(OperServ, "OPER"); // Probably not set, just incase - } - } - - public: - SQLOperResult(Module *m, User *u) : SQL::Interface(m), user(u) { } - - void OnResult(const SQL::Result &r) anope_override - { - SQLOperResultDeleter d(this); - - if (!user || !user->Account()) - return; - - if (r.Rows() == 0) - { - Log(LOG_DEBUG) << "m_sql_oper: Got 0 rows for " << user->nick; - Deoper(); - return; - } - - Anope::string opertype; - try - { - opertype = r.Get(0, "opertype"); - } - catch (const SQL::Exception &) - { - Log(this->owner) << "Expected column named \"opertype\" but one was not found"; - return; - } - - Log(LOG_DEBUG) << "m_sql_oper: Got result for " << user->nick << ", opertype " << opertype; - - Anope::string modes; - try - { - modes = r.Get(0, "modes"); - } - catch (const SQL::Exception &) - { - // Common case here is an exception, but this probably doesn't get this far often - } - - BotInfo *OperServ = Config->GetClient("OperServ"); - if (opertype.empty()) - { - Deoper(); - return; - } - - OperType *ot = OperType::Find(opertype); - if (ot == NULL) - { - Log(this->owner) << "m_sql_oper: Oper " << user->nick << " has type " << opertype << ", but this opertype does not exist?"; - return; - } - - if (user->Account()->o && !dynamic_cast<SQLOper *>(user->Account()->o)) - { - Log(this->owner) << "Oper " << user->Account()->display << " has type " << opertype << ", but is already configured as an oper of type " << user->Account()->o->ot->GetName(); - return; - } - - if (!user->Account()->o || user->Account()->o->ot != ot) - { - Log(this->owner) << "m_sql_oper: Tieing oper " << user->nick << " to type " << opertype; - - delete user->Account()->o; - user->Account()->o = new SQLOper(user->Account()->display, ot); - } - - if (!user->HasMode("OPER")) - { - IRCD->SendOper(user); - - if (!modes.empty()) - user->SetModes(OperServ, "%s", modes.c_str()); - } - } - - void OnError(const SQL::Result &r) anope_override - { - SQLOperResultDeleter d(this); - Log(this->owner) << "m_sql_oper: Error executing query " << r.GetQuery().query << ": " << r.GetError(); - } -}; - -class ModuleSQLOper : public Module -{ - Anope::string engine; - Anope::string query; - - ServiceReference<SQL::Provider> SQL; - - public: - ModuleSQLOper(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, EXTRA | VENDOR) - { - } - - ~ModuleSQLOper() - { - for (nickcore_map::const_iterator it = NickCoreList->begin(), it_end = NickCoreList->end(); it != it_end; ++it) - { - NickCore *nc = it->second; - - if (nc->o && dynamic_cast<SQLOper *>(nc->o)) - { - delete nc->o; - nc->o = NULL; - } - } - } - - void OnReload(Configuration::Conf *conf) anope_override - { - Configuration::Block *config = conf->GetModule(this); - - this->engine = config->Get<const Anope::string>("engine"); - this->query = config->Get<const Anope::string>("query"); - - this->SQL = ServiceReference<SQL::Provider>("SQL::Provider", this->engine); - } - - void OnNickIdentify(User *u) anope_override - { - if (!this->SQL) - { - Log() << "Unable to find SQL engine"; - return; - } - - SQL::Query q(this->query); - q.SetValue("a", u->Account()->display); - q.SetValue("i", u->ip.addr()); - - this->SQL->Run(new SQLOperResult(this, u), q); - - Log(LOG_DEBUG) << "m_sql_oper: Checking authentication for " << u->Account()->display; - } -}; - -MODULE_INIT(ModuleSQLOper) diff --git a/modules/extra/m_sqlite.cpp b/modules/extra/m_sqlite.cpp deleted file mode 100644 index 0699ee3eb..000000000 --- a/modules/extra/m_sqlite.cpp +++ /dev/null @@ -1,335 +0,0 @@ -/* - * - * (C) 2011-2016 Anope Team - * Contact us at team@anope.org - * - * Please read COPYING and README for further details. - */ - -/* RequiredLibraries: sqlite3 */ -/* RequiredWindowsLibraries: sqlite3 */ - -#include "module.h" -#include "modules/sql.h" -#include <sqlite3.h> - -using namespace SQL; - -/* SQLite3 API, based from InspiRCd */ - -/** A SQLite result - */ -class SQLiteResult : public Result -{ - public: - SQLiteResult(unsigned int i, const Query &q, const Anope::string &fq) : Result(i, q, fq) - { - } - - SQLiteResult(const Query &q, const Anope::string &fq, const Anope::string &err) : Result(0, q, fq, err) - { - } - - void AddRow(const std::map<Anope::string, Anope::string> &data) - { - this->entries.push_back(data); - } -}; - -/** A SQLite database, there can be multiple - */ -class SQLiteService : public Provider -{ - std::map<Anope::string, std::set<Anope::string> > active_schema; - - Anope::string database; - - sqlite3 *sql; - - Anope::string Escape(const Anope::string &query); - - public: - SQLiteService(Module *o, const Anope::string &n, const Anope::string &d); - - ~SQLiteService(); - - void Run(Interface *i, const Query &query) anope_override; - - Result RunQuery(const Query &query); - - std::vector<Query> CreateTable(const Anope::string &table, const Data &data) anope_override; - - Query BuildInsert(const Anope::string &table, unsigned int id, Data &data); - - Query GetTables(const Anope::string &prefix); - - Anope::string BuildQuery(const Query &q); - - Anope::string FromUnixtime(time_t); -}; - -class ModuleSQLite : public Module -{ - /* SQL connections */ - std::map<Anope::string, SQLiteService *> SQLiteServices; - public: - ModuleSQLite(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, EXTRA | VENDOR) - { - } - - ~ModuleSQLite() - { - for (std::map<Anope::string, SQLiteService *>::iterator it = this->SQLiteServices.begin(); it != this->SQLiteServices.end(); ++it) - delete it->second; - SQLiteServices.clear(); - } - - void OnReload(Configuration::Conf *conf) anope_override - { - Configuration::Block *config = conf->GetModule(this); - - for (std::map<Anope::string, SQLiteService *>::iterator it = this->SQLiteServices.begin(); it != this->SQLiteServices.end();) - { - const Anope::string &cname = it->first; - SQLiteService *s = it->second; - int i, num; - ++it; - - for (i = 0, num = config->CountBlock("sqlite"); i < num; ++i) - if (config->GetBlock("sqlite", i)->Get<const Anope::string>("name", "sqlite/main") == cname) - break; - - if (i == num) - { - Log(LOG_NORMAL, "sqlite") << "SQLite: Removing server connection " << cname; - - delete s; - this->SQLiteServices.erase(cname); - } - } - - for (int i = 0; i < config->CountBlock("sqlite"); ++i) - { - Configuration::Block *block = config->GetBlock("sqlite", i); - Anope::string connname = block->Get<const Anope::string>("name", "sqlite/main"); - - if (this->SQLiteServices.find(connname) == this->SQLiteServices.end()) - { - Anope::string database = Anope::DataDir + "/" + block->Get<const Anope::string>("database", "anope"); - - try - { - SQLiteService *ss = new SQLiteService(this, connname, database); - this->SQLiteServices[connname] = ss; - - Log(LOG_NORMAL, "sqlite") << "SQLite: Successfully added database " << database; - } - catch (const SQL::Exception &ex) - { - Log(LOG_NORMAL, "sqlite") << "SQLite: " << ex.GetReason(); - } - } - } - } -}; - -SQLiteService::SQLiteService(Module *o, const Anope::string &n, const Anope::string &d) -: Provider(o, n), database(d), sql(NULL) -{ - int db = sqlite3_open_v2(database.c_str(), &this->sql, SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE, 0); - if (db != SQLITE_OK) - { - Anope::string exstr = "Unable to open SQLite database " + database; - if (this->sql) - { - exstr += ": "; - exstr += sqlite3_errmsg(this->sql); - sqlite3_close(this->sql); - } - throw SQL::Exception(exstr); - } -} - -SQLiteService::~SQLiteService() -{ - sqlite3_interrupt(this->sql); - sqlite3_close(this->sql); -} - -void SQLiteService::Run(Interface *i, const Query &query) -{ - Result res = this->RunQuery(query); - if (!res.GetError().empty()) - i->OnError(res); - else - i->OnResult(res); -} - -Result SQLiteService::RunQuery(const Query &query) -{ - Anope::string real_query = this->BuildQuery(query); - sqlite3_stmt *stmt; - int err = sqlite3_prepare_v2(this->sql, real_query.c_str(), real_query.length(), &stmt, NULL); - if (err != SQLITE_OK) - return SQLiteResult(query, real_query, sqlite3_errmsg(this->sql)); - - std::vector<Anope::string> columns; - int cols = sqlite3_column_count(stmt); - columns.resize(cols); - for (int i = 0; i < cols; ++i) - columns[i] = sqlite3_column_name(stmt, i); - - SQLiteResult result(0, query, real_query); - - while ((err = sqlite3_step(stmt)) == SQLITE_ROW) - { - std::map<Anope::string, Anope::string> items; - for (int i = 0; i < cols; ++i) - { - const char *data = reinterpret_cast<const char *>(sqlite3_column_text(stmt, i)); - if (data && *data) - items[columns[i]] = data; - } - result.AddRow(items); - } - - result.id = sqlite3_last_insert_rowid(this->sql); - - sqlite3_finalize(stmt); - - if (err != SQLITE_DONE) - return SQLiteResult(query, real_query, sqlite3_errmsg(this->sql)); - - return result; -} - -std::vector<Query> SQLiteService::CreateTable(const Anope::string &table, const Data &data) -{ - std::vector<Query> queries; - std::set<Anope::string> &known_cols = this->active_schema[table]; - - if (known_cols.empty()) - { - Log(LOG_DEBUG) << "m_sqlite: Fetching columns for " << table; - - Result columns = this->RunQuery("PRAGMA table_info(" + table + ")"); - for (int i = 0; i < columns.Rows(); ++i) - { - const Anope::string &column = columns.Get(i, "name"); - - Log(LOG_DEBUG) << "m_sqlite: Column #" << i << " for " << table << ": " << column; - known_cols.insert(column); - } - } - - if (known_cols.empty()) - { - Anope::string query_text = "CREATE TABLE `" + table + "` (`id` INTEGER PRIMARY KEY, `timestamp` timestamp DEFAULT CURRENT_TIMESTAMP"; - - for (Data::Map::const_iterator it = data.data.begin(), it_end = data.data.end(); it != it_end; ++it) - { - known_cols.insert(it->first); - - query_text += ", `" + it->first + "` "; - if (data.GetType(it->first) == Serialize::Data::DT_INT) - query_text += "int(11)"; - else - query_text += "text"; - } - - query_text += ")"; - - queries.push_back(query_text); - - query_text = "CREATE UNIQUE INDEX `" + table + "_id_idx` ON `" + table + "` (`id`)"; - queries.push_back(query_text); - - query_text = "CREATE INDEX `" + table + "_timestamp_idx` ON `" + table + "` (`timestamp`)"; - queries.push_back(query_text); - - query_text = "CREATE TRIGGER `" + table + "_trigger` AFTER UPDATE ON `" + table + "` FOR EACH ROW BEGIN UPDATE `" + table + "` SET `timestamp` = CURRENT_TIMESTAMP WHERE `id` = `old.id`; end;"; - queries.push_back(query_text); - } - else - for (Data::Map::const_iterator it = data.data.begin(), it_end = data.data.end(); it != it_end; ++it) - { - if (known_cols.count(it->first) > 0) - continue; - - known_cols.insert(it->first); - - Anope::string query_text = "ALTER TABLE `" + table + "` ADD `" + it->first + "` "; - if (data.GetType(it->first) == Serialize::Data::DT_INT) - query_text += "int(11)"; - else - query_text += "text"; - - queries.push_back(query_text); - } - - return queries; -} - -Query SQLiteService::BuildInsert(const Anope::string &table, unsigned int id, Data &data) -{ - /* Empty columns not present in the data set */ - const std::set<Anope::string> &known_cols = this->active_schema[table]; - for (std::set<Anope::string>::iterator it = known_cols.begin(), it_end = known_cols.end(); it != it_end; ++it) - if (*it != "id" && *it != "timestamp" && data.data.count(*it) == 0) - data[*it] << ""; - - Anope::string query_text = "REPLACE INTO `" + table + "` ("; - if (id > 0) - query_text += "`id`,"; - for (Data::Map::const_iterator it = data.data.begin(), it_end = data.data.end(); it != it_end; ++it) - query_text += "`" + it->first + "`,"; - query_text.erase(query_text.length() - 1); - query_text += ") VALUES ("; - if (id > 0) - query_text += stringify(id) + ","; - for (Data::Map::const_iterator it = data.data.begin(), it_end = data.data.end(); it != it_end; ++it) - query_text += "@" + it->first + "@,"; - query_text.erase(query_text.length() - 1); - query_text += ")"; - - Query query(query_text); - for (Data::Map::const_iterator it = data.data.begin(), it_end = data.data.end(); it != it_end; ++it) - { - Anope::string buf; - *it->second >> buf; - query.SetValue(it->first, buf); - } - - return query; -} - -Query SQLiteService::GetTables(const Anope::string &prefix) -{ - return Query("SELECT name FROM sqlite_master WHERE type='table' AND name LIKE '" + prefix + "%';"); -} - -Anope::string SQLiteService::Escape(const Anope::string &query) -{ - char *e = sqlite3_mprintf("%q", query.c_str()); - Anope::string buffer = e; - sqlite3_free(e); - return buffer; -} - -Anope::string SQLiteService::BuildQuery(const Query &q) -{ - Anope::string real_query = q.query; - - for (std::map<Anope::string, QueryData>::const_iterator it = q.parameters.begin(), it_end = q.parameters.end(); it != it_end; ++it) - real_query = real_query.replace_all_cs("@" + it->first + "@", (it->second.escape ? ("'" + this->Escape(it->second.data) + "'") : it->second.data)); - - return real_query; -} - -Anope::string SQLiteService::FromUnixtime(time_t t) -{ - return "datetime('" + stringify(t) + "', 'unixepoch')"; -} - -MODULE_INIT(ModuleSQLite) - diff --git a/modules/extra/m_mysql.cpp b/modules/extra/mysql.cpp index 06cce3143..a61181f37 100644 --- a/modules/extra/m_mysql.cpp +++ b/modules/extra/mysql.cpp @@ -1,9 +1,20 @@ /* + * Anope IRC Services * - * (C) 2010-2016 Anope Team - * Contact us at team@anope.org + * Copyright (C) 2010-2016 Anope Team <team@anope.org> * - * Please read COPYING and README for further details. + * This file is part of Anope. Anope 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 see <http://www.gnu.org/licenses/>. */ /* RequiredLibraries: mysqlclient */ @@ -66,31 +77,35 @@ class MySQLResult : public Result public: MySQLResult(unsigned int i, const Query &q, const Anope::string &fq, MYSQL_RES *r) : Result(i, q, fq), res(r) { - unsigned num_fields = res ? mysql_num_fields(res) : 0; + if (!res) + return; - /* It is not thread safe to log anything here using Log(this->owner) now :( */ + unsigned num_fields = mysql_num_fields(res); + MYSQL_FIELD *fields = mysql_fetch_fields(res); - if (!num_fields) + /* It is not thread safe to log anything here using the loggers now :( */ + + if (!num_fields || !fields) return; + for (unsigned field_count = 0; field_count < num_fields; ++field_count) + columns.push_back(fields[field_count].name ? fields[field_count].name : ""); + for (MYSQL_ROW row; (row = mysql_fetch_row(res));) { - MYSQL_FIELD *fields = mysql_fetch_fields(res); + std::vector<Value> values; - if (fields) + for (unsigned field_count = 0; field_count < num_fields; ++field_count) { - std::map<Anope::string, Anope::string> items; + const char *data = row[field_count]; - for (unsigned field_count = 0; field_count < num_fields; ++field_count) - { - Anope::string column = (fields[field_count].name ? fields[field_count].name : ""); - Anope::string data = (row[field_count] ? row[field_count] : ""); - - items[column] = data; - } - - this->entries.push_back(items); + Value v; + v.null = !data; + v.value = data ? data : ""; + values.push_back(v); } + + this->values.push_back(values); } } @@ -109,7 +124,7 @@ class MySQLResult : public Result */ class MySQLService : public Provider { - std::map<Anope::string, std::set<Anope::string> > active_schema; + std::map<Anope::string, std::set<Anope::string> > active_schema, indexes; Anope::string database; Anope::string server; @@ -135,23 +150,29 @@ class MySQLService : public Provider ~MySQLService(); - void Run(Interface *i, const Query &query) anope_override; + void Run(Interface *i, const Query &query) override; - Result RunQuery(const Query &query) anope_override; + Result RunQuery(const Query &query) override; - std::vector<Query> CreateTable(const Anope::string &table, const Data &data) anope_override; + std::vector<Query> InitSchema(const Anope::string &prefix) override; + std::vector<Query> Replace(const Anope::string &table, const Query &, const std::set<Anope::string> &) override; + std::vector<Query> CreateTable(const Anope::string &prefix, Serialize::TypeBase *) override; + std::vector<Query> AlterTable(const Anope::string &, Serialize::TypeBase *, Serialize::FieldBase *) override; + std::vector<Query> CreateIndex(const Anope::string &table, const Anope::string &field) override; + Query SelectFind(const Anope::string &table, const Anope::string &field) override; - Query BuildInsert(const Anope::string &table, unsigned int id, Data &data) anope_override; + Query BeginTransaction() override; + Query Commit() override; - Query GetTables(const Anope::string &prefix) anope_override; + Serialize::ID GetID(const Anope::string &prefix, const Anope::string &type) override; + + Query GetTables(const Anope::string &prefix) override; void Connect(); bool CheckConnection(); Anope::string BuildQuery(const Query &q); - - Anope::string FromUnixtime(time_t); }; /** The SQL thread used to execute queries @@ -161,12 +182,14 @@ class DispatcherThread : public Thread, public Condition public: DispatcherThread() : Thread() { } - void Run() anope_override; + void Run() override; }; class ModuleSQL; static ModuleSQL *me; -class ModuleSQL : public Module, public Pipe +class ModuleSQL : public Module + , public Pipe + , public EventHook<Event::ModuleUnload> { /* SQL connections */ std::map<Anope::string, MySQLService *> MySQLServices; @@ -179,6 +202,7 @@ class ModuleSQL : public Module, public Pipe DispatcherThread *DThread; ModuleSQL(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, EXTRA | VENDOR) + , EventHook<Event::ModuleUnload>(this) { me = this; @@ -199,7 +223,7 @@ class ModuleSQL : public Module, public Pipe delete DThread; } - void OnReload(Configuration::Conf *conf) anope_override + void OnReload(Configuration::Conf *conf) override { Configuration::Block *config = conf->GetModule(this); @@ -212,12 +236,12 @@ class ModuleSQL : public Module, public Pipe ++it; for (i = 0; i < config->CountBlock("mysql"); ++i) - if (config->GetBlock("mysql", i)->Get<const Anope::string>("name", "mysql/main") == cname) + if (config->GetBlock("mysql", i)->Get<Anope::string>("name", "mysql/main") == cname) break; if (i == config->CountBlock("mysql")) { - Log(LOG_NORMAL, "mysql") << "MySQL: Removing server connection " << cname; + logger.Log("Removing server connection {0}", cname); delete s; this->MySQLServices.erase(cname); @@ -227,14 +251,14 @@ class ModuleSQL : public Module, public Pipe for (int i = 0; i < config->CountBlock("mysql"); ++i) { Configuration::Block *block = config->GetBlock("mysql", i); - const Anope::string &connname = block->Get<const Anope::string>("name", "mysql/main"); + const Anope::string &connname = block->Get<Anope::string>("name", "mysql/main"); if (this->MySQLServices.find(connname) == this->MySQLServices.end()) { - const Anope::string &database = block->Get<const Anope::string>("database", "anope"); - const Anope::string &server = block->Get<const Anope::string>("server", "127.0.0.1"); - const Anope::string &user = block->Get<const Anope::string>("username", "anope"); - const Anope::string &password = block->Get<const Anope::string>("password"); + const Anope::string &database = block->Get<Anope::string>("database", "anope"); + const Anope::string &server = block->Get<Anope::string>("server", "127.0.0.1"); + const Anope::string &user = block->Get<Anope::string>("username", "anope"); + const Anope::string &password = block->Get<Anope::string>("password"); int port = block->Get<int>("port", "3306"); try @@ -242,17 +266,17 @@ class ModuleSQL : public Module, public Pipe MySQLService *ss = new MySQLService(this, connname, database, server, user, password, port); this->MySQLServices.insert(std::make_pair(connname, ss)); - Log(LOG_NORMAL, "mysql") << "MySQL: Successfully connected to server " << connname << " (" << server << ")"; + logger.Log(_("Successfully connected to server {0} ({1})"), connname, server); } catch (const SQL::Exception &ex) { - Log(LOG_NORMAL, "mysql") << "MySQL: " << ex.GetReason(); + logger.Log(ex.GetReason()); } } } } - void OnModuleUnload(User *, Module *m) anope_override + void OnModuleUnload(User *, Module *m) override { this->DThread->Lock(); @@ -277,7 +301,7 @@ class ModuleSQL : public Module, public Pipe this->OnNotify(); } - void OnNotify() anope_override + void OnNotify() override { this->DThread->Lock(); std::deque<QueryResult> finishedRequests = this->FinishedRequests; @@ -366,90 +390,124 @@ Result MySQLService::RunQuery(const Query &query) } } -std::vector<Query> MySQLService::CreateTable(const Anope::string &table, const Data &data) +std::vector<Query> MySQLService::InitSchema(const Anope::string &prefix) { std::vector<Query> queries; - std::set<Anope::string> &known_cols = this->active_schema[table]; - if (known_cols.empty()) - { - Log(LOG_DEBUG) << "m_mysql: Fetching columns for " << table; + return queries; +} - Result columns = this->RunQuery("SHOW COLUMNS FROM `" + table + "`"); - for (int i = 0; i < columns.Rows(); ++i) - { - const Anope::string &column = columns.Get(i, "Field"); +std::vector<Query> MySQLService::Replace(const Anope::string &table, const Query &q, const std::set<Anope::string> &keys) +{ + std::vector<Query> queries; - Log(LOG_DEBUG) << "m_mysql: Column #" << i << " for " << table << ": " << column; - known_cols.insert(column); - } + Anope::string query_text = "INSERT INTO `" + table + "` ("; + for (const std::pair<Anope::string, QueryData> &p : q.parameters) + query_text += "`" + p.first + "`,"; + query_text.erase(query_text.length() - 1); + query_text += ") VALUES ("; + for (const std::pair<Anope::string, QueryData> &p : q.parameters) + query_text += "@" + p.first + "@,"; + query_text.erase(query_text.length() - 1); + query_text += ") ON DUPLICATE KEY UPDATE "; + for (const std::pair<Anope::string, QueryData> &p : q.parameters) + if (!keys.count(p.first)) + query_text += "`" + p.first + "` = VALUES(`" + p.first + "`),"; + query_text.erase(query_text.length() - 1); + + Query query(query_text); + query.parameters = q.parameters; + + queries.push_back(query); + + return queries; +} + +std::vector<Query> MySQLService::CreateTable(const Anope::string &prefix, Serialize::TypeBase *base) +{ + std::vector<Query> queries; + + if (active_schema.find(prefix + base->GetName()) == active_schema.end()) + { + Query t = "CREATE TABLE IF NOT EXISTS `" + prefix + base->GetName() + "` (`id` bigint(20) NOT NULL AUTO_INCREMENT, PRIMARY KEY (`id`)) ENGINE=InnoDB"; + queries.push_back(t); + + active_schema[prefix + base->GetName()]; } - if (known_cols.empty()) + return queries; +} + +std::vector<Query> MySQLService::AlterTable(const Anope::string &prefix, Serialize::TypeBase *type, Serialize::FieldBase *field) +{ + const Anope::string &table = type->GetName(); + + std::vector<Query> queries; + std::set<Anope::string> &s = active_schema[prefix + table]; + + if (!s.count(field->serialize_name)) { - Anope::string query_text = "CREATE TABLE `" + table + "` (`id` int(10) unsigned NOT NULL AUTO_INCREMENT," - " `timestamp` timestamp NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP"; - for (Data::Map::const_iterator it = data.data.begin(), it_end = data.data.end(); it != it_end; ++it) + Anope::string buf = "ALTER TABLE `" + prefix + table + "` ADD COLUMN `" + field->serialize_name + "` "; + + if (!field->is_object) { - known_cols.insert(it->first); + buf += "TINYTEXT"; + } + else + { + buf += "bigint(20), ADD CONSTRAINT `" + table + "_" + field->serialize_name + "_fk` FOREIGN KEY (`" + field->serialize_name + "`) REFERENCES `" + prefix + field->GetTypeName() + "` (`id`) ON DELETE "; - query_text += ", `" + it->first + "` "; - if (data.GetType(it->first) == Serialize::Data::DT_INT) - query_text += "int(11)"; + if (field->depends) + buf += "CASCADE"; else - query_text += "text"; + buf += "SET NULL"; } - query_text += ", PRIMARY KEY (`id`), KEY `timestamp_idx` (`timestamp`))"; - queries.push_back(query_text); + + queries.push_back(Query(buf)); + s.insert(field->serialize_name); } - else - for (Data::Map::const_iterator it = data.data.begin(), it_end = data.data.end(); it != it_end; ++it) - { - if (known_cols.count(it->first) > 0) - continue; - known_cols.insert(it->first); + return queries; +} - Anope::string query_text = "ALTER TABLE `" + table + "` ADD `" + it->first + "` "; - if (data.GetType(it->first) == Serialize::Data::DT_INT) - query_text += "int(11)"; - else - query_text += "text"; +std::vector<Query> MySQLService::CreateIndex(const Anope::string &table, const Anope::string &field) +{ + std::vector<Query> queries; - queries.push_back(query_text); - } + if (indexes[table].count(field)) + return queries; + + Query t = "ALTER TABLE `" + table + "` ADD KEY `idx_" + field + "` (`" + field + "`(512))"; + queries.push_back(t); + + indexes[table].insert(field); return queries; } -Query MySQLService::BuildInsert(const Anope::string &table, unsigned int id, Data &data) +Query MySQLService::SelectFind(const Anope::string &table, const Anope::string &field) { - /* Empty columns not present in the data set */ - const std::set<Anope::string> &known_cols = this->active_schema[table]; - for (std::set<Anope::string>::iterator it = known_cols.begin(), it_end = known_cols.end(); it != it_end; ++it) - if (*it != "id" && *it != "timestamp" && data.data.count(*it) == 0) - data[*it] << ""; - - Anope::string query_text = "INSERT INTO `" + table + "` (`id`"; - for (Data::Map::const_iterator it = data.data.begin(), it_end = data.data.end(); it != it_end; ++it) - query_text += ",`" + it->first + "`"; - query_text += ") VALUES (" + stringify(id); - for (Data::Map::const_iterator it = data.data.begin(), it_end = data.data.end(); it != it_end; ++it) - query_text += ",@" + it->first + "@"; - query_text += ") ON DUPLICATE KEY UPDATE "; - for (Data::Map::const_iterator it = data.data.begin(), it_end = data.data.end(); it != it_end; ++it) - query_text += "`" + it->first + "`=VALUES(`" + it->first + "`),"; - query_text.erase(query_text.end() - 1); + return Query("SELECT `id` FROM `" + table + "` WHERE `" + field + "` = @value@"); +} - Query query(query_text); - for (Data::Map::const_iterator it = data.data.begin(), it_end = data.data.end(); it != it_end; ++it) - { - Anope::string buf; - *it->second >> buf; - query.SetValue(it->first, buf); - } - - return query; +Query MySQLService::BeginTransaction() +{ + return Query("START TRANSACTION WITH CONSISTENT SNAPSHOT"); +} + +Query MySQLService::Commit() +{ + return Query("COMMIT"); +} + +Serialize::ID MySQLService::GetID(const Anope::string &prefix, const Anope::string &type) +{ + Query query = "INSERT INTO `" + prefix + type + "` VALUES ()"; + Result res = RunQuery(query); + + Serialize::ID id = res.GetID(); + + return id; } Query MySQLService::GetTables(const Anope::string &prefix) @@ -467,9 +525,9 @@ void MySQLService::Connect() bool connect = mysql_real_connect(this->sql, this->server.c_str(), this->user.c_str(), this->password.c_str(), this->database.c_str(), this->port, NULL, CLIENT_MULTI_RESULTS); if (!connect) - throw SQL::Exception("Unable to connect to MySQL service " + this->name + ": " + mysql_error(this->sql)); - - Log(LOG_DEBUG) << "Successfully connected to MySQL service " << this->name << " at " << this->server << ":" << this->port; + throw SQL::Exception("Unable to connect to MySQL service " + this->GetName() + ": " + mysql_error(this->sql)); + + this->GetOwner()->logger.Debug("Successfully connected to MySQL service {0} at {1}:{2}", this->GetName(), this->server, this->port); } @@ -502,14 +560,21 @@ Anope::string MySQLService::BuildQuery(const Query &q) Anope::string real_query = q.query; for (std::map<Anope::string, QueryData>::const_iterator it = q.parameters.begin(), it_end = q.parameters.end(); it != it_end; ++it) - real_query = real_query.replace_all_cs("@" + it->first + "@", (it->second.escape ? ("'" + this->Escape(it->second.data) + "'") : it->second.data)); + { + const QueryData& qd = it->second; + Anope::string replacement; - return real_query; -} + if (qd.null) + replacement = "NULL"; + else if (!qd.escape) + replacement = qd.data; + else + replacement = "'" + this->Escape(qd.data) + "'"; -Anope::string MySQLService::FromUnixtime(time_t t) -{ - return "FROM_UNIXTIME(" + stringify(t) + ")"; + real_query = real_query.replace_all_cs("@" + it->first + "@", replacement); + } + + return real_query; } void DispatcherThread::Run() diff --git a/modules/extra/rest.cpp b/modules/extra/rest.cpp new file mode 100644 index 000000000..187b2147f --- /dev/null +++ b/modules/extra/rest.cpp @@ -0,0 +1,426 @@ +/* + * Anope IRC Services + * + * Copyright (C) 2016 Anope Team <team@anope.org> + * + * This file is part of Anope. Anope 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 see <http://www.gnu.org/licenses/>. + */ + +#include "module.h" +#include "modules/httpd.h" + +#include <boost/property_tree/ptree.hpp> +#include <boost/property_tree/json_parser.hpp> + +class RESTService : public HTTPPage +{ + public: + RESTService(Module *creator, const Anope::string &sname) : HTTPPage("/rest", "application/json") + { + } + + bool OnRequest(HTTPProvider *provider, const Anope::string &page_name, HTTPClient *client, HTTPMessage &message, HTTPReply &reply) override + { + sepstream sep(page_name, '/'); + Anope::string token; + + sep.GetToken(token); // /rest + sep.GetToken(token); // type + + if (token == "types") + { + GetTypes(provider, client, message, reply); + return true; + } + + Serialize::TypeBase *type = Serialize::TypeBase::Find(token); + if (type == nullptr) + { + reply.error = HTTP_PAGE_NOT_FOUND; + reply.Write("Unknown type"); + return true; + } + + if (message.method == httpd::Method::POST) + { + Post(provider, client, message, reply, type, sep); + } + else if (message.method == httpd::Method::GET) + { + Get(provider, client, message, reply, type, sep); + } + else if (message.method == httpd::Method::PUT) + { + Put(provider, client, message, reply, type, sep); + } + else if (message.method == httpd::Method::DELETE) + { + Delete(provider, client, message, reply, type, sep); + } + else + { + reply.error = HTTP_NOT_SUPPORTED; + reply.Write("Not Supported"); + } + + return true; + } + + private: + /** Get all object type names + */ + void GetTypes(HTTPProvider *provider, HTTPClient *client, HTTPMessage &message, HTTPReply &reply) + { + boost::property_tree::ptree tree, children; + + for (Serialize::TypeBase *stype : Serialize::TypeBase::GetTypes()) + { + boost::property_tree::ptree child; + child.put("", stype->GetName().str()); + children.push_back(std::make_pair("", child)); + } + + tree.add_child("types", children); + + std::stringstream ss; + boost::property_tree::write_json(ss, tree); + + reply.Write(ss.str()); + } + + void Post(HTTPProvider *provider, HTTPClient *client, HTTPMessage &message, HTTPReply &reply, Serialize::TypeBase *type, sepstream &sep) + { + boost::property_tree::ptree tree; + std::stringstream ss(message.content.str()); + + try + { + boost::property_tree::read_json(ss, tree); + } + catch (const boost::property_tree::json_parser::json_parser_error &) + { + reply.error = HTTP_BAD_REQUEST; + reply.Write("Unable to parse JSON"); + return; + } + + for (auto &p : tree) + { + const std::string &key = p.first; + + Serialize::FieldBase *field = type->GetField(key); + if (field == nullptr) + { + reply.error = HTTP_BAD_REQUEST; + reply.Write("No such field " + field->serialize_name); + return; + } + } + + Serialize::Object *object = type->Create(); + if (object == nullptr) + { + reply.error = HTTP_INTERNAL_SERVER_ERROR; + reply.Write("Unable to create new object"); + return; + } + + for (auto &p : tree) + { + const std::string &key = p.first; + const boost::property_tree::ptree &pt = p.second; + + Serialize::FieldBase *field = type->GetField(key); + if (field == nullptr) + { + reply.error = HTTP_INTERNAL_SERVER_ERROR; + reply.Write("Missing field"); + return; + } + + field->UnserializeFromString(object, pt.get_value<std::string>()); + } + + reply.error = HTTP_CREATED; + reply.Write(stringify(object->id)); + } + + void Get(HTTPProvider *provider, HTTPClient *client, HTTPMessage &message, HTTPReply &reply, Serialize::TypeBase *type, sepstream &sep) + { + Anope::string token; + sep.GetToken(token); + + if (token.empty()) + { + GetList(reply, type); + return; + } + + if (token.is_pos_number_only()) + { + GetID(message, reply, type, token); + return; + } + + GetField(reply, type, token, sep); + } + + boost::property_tree::ptree ToJson(Serialize::Object *object) + { + boost::property_tree::ptree tree; + + for (Serialize::FieldBase *field : object->GetSerializableType()->GetFields()) + { + if (field->HasFieldS(object)) // for ext + tree.put(field->serialize_name.str(), field->SerializeToString(object).str()); + } + + tree.put("id", object->id); + return tree; + } + + /** Get a list of all objects of a type + */ + void GetList(HTTPReply &reply, Serialize::TypeBase *type) + { + boost::property_tree::ptree tree, children; + + for (Serialize::Object *object : Serialize::GetObjects_<Serialize::Object *>(type)) + { + boost::property_tree::ptree child = ToJson(object);; + children.push_back(std::make_pair("", child)); + } + + tree.add_child(type->GetName().str(), children); + + std::stringstream ss; + boost::property_tree::write_json(ss, tree); + + reply.Write(ss.str()); + } + + /** Get object by id + */ + void GetID(HTTPMessage &message, HTTPReply &reply, Serialize::TypeBase *type, const Anope::string &token) + { + Serialize::ID id; + try + { + id = convertTo<Serialize::ID>(token); + } + catch (const ConvertException &ex) + { + reply.error = HTTP_BAD_REQUEST; + reply.Write("Invalid id"); + return; + } + + if (message.get_data.count("refs") > 0) + { + Serialize::TypeBase *ref_type = Serialize::TypeBase::Find(message.get_data["refs"]); + + if (ref_type == nullptr) + { + reply.error = HTTP_PAGE_NOT_FOUND; + reply.Write("Unknown reference type"); + return; + } + + GetRefs(reply, type, id, ref_type); + return; + } + + GetID(reply, type, id); + } + + void GetID(HTTPReply &reply, Serialize::TypeBase *type, Serialize::ID id) + { + Serialize::Object *object = type->Require(id); + if (object == nullptr) + { + /* This has to be a cached object with type/id mismatch */ + reply.error = HTTP_PAGE_NOT_FOUND; + reply.Write("Type/id mismatch"); + return; + } + + boost::property_tree::ptree tree = ToJson(object); + + std::stringstream ss; + boost::property_tree::write_json(ss, tree); + + reply.Write(ss.str()); + } + + /** Get object by field and value + */ + void GetField(HTTPReply &reply, Serialize::TypeBase *type, const Anope::string &token, sepstream &sep) + { + Serialize::FieldBase *field = type->GetField(token); + if (field == nullptr) + { + reply.error = HTTP_PAGE_NOT_FOUND; + reply.Write("No such field"); + return; + } + + Anope::string value; + sep.GetToken(value); + + Serialize::ID id; + EventReturn result = EventManager::Get()->Dispatch(&Event::SerializeEvents::OnSerializeFind, type, field, value, id); + if (result != EVENT_ALLOW) + { + reply.error = HTTP_PAGE_NOT_FOUND; + reply.Write("Not found"); + return; + } + + GetID(reply, type, id); + } + + /** Find refs of type ref_type to object id of type type + */ + void GetRefs(HTTPReply &reply, Serialize::TypeBase *type, Serialize::ID id, Serialize::TypeBase *ref_type) + { + Serialize::Object *object = type->Require(id); + if (object == nullptr) + { + reply.error = HTTP_PAGE_NOT_FOUND; + reply.Write("Type/id mismatch"); + return; + } + + boost::property_tree::ptree tree, children; + + for (Serialize::Object *ref : object->GetRefs(ref_type)) + { + boost::property_tree::ptree child = ToJson(ref); + children.push_back(std::make_pair("", child)); + } + + tree.add_child(type->GetName().str(), children); + + std::stringstream ss; + boost::property_tree::write_json(ss, tree); + + reply.Write(ss.str()); + } + + void Put(HTTPProvider *provider, HTTPClient *client, HTTPMessage &message, HTTPReply &reply, Serialize::TypeBase *type, sepstream &sep) + { + Anope::string token; + Anope::string fieldname; + + if (!sep.GetToken(token) || !sep.GetToken(fieldname)) + { + reply.error = HTTP_BAD_REQUEST; + reply.Write("No id and/or field"); + return; + } + + Serialize::ID id; + try + { + id = convertTo<Serialize::ID>(token); + } + catch (const ConvertException &ex) + { + reply.error = HTTP_BAD_REQUEST; + reply.Write("Invalid id"); + return; + } + + Serialize::Object *object = type->Require(id); + if (object == nullptr) + { + reply.error = HTTP_PAGE_NOT_FOUND; + reply.Write("Type/id mismatch"); + return; + } + + Serialize::FieldBase *field = type->GetField(fieldname); + if (field == nullptr) + { + reply.error = HTTP_BAD_REQUEST; + reply.Write("No such field"); + return; + } + + field->UnserializeFromString(object, message.content); + } + + void Delete(HTTPProvider *provider, HTTPClient *client, HTTPMessage &message, HTTPReply &reply, Serialize::TypeBase *type, sepstream &sep) + { + Anope::string token; + sep.GetToken(token); + + Serialize::ID id; + try + { + id = convertTo<Serialize::ID>(token); + } + catch (const ConvertException &ex) + { + reply.error = HTTP_BAD_REQUEST; + reply.Write("Invalid id"); + return; + } + + Serialize::Object *object = type->Require(id); + if (object == nullptr) + { + reply.error = HTTP_PAGE_NOT_FOUND; + reply.Write("Type/id mismatch"); + return; + } + + object->Delete(); + } +}; + +class ModuleREST : public Module +{ + ServiceReference<HTTPProvider> httpref; + + public: + RESTService restinterface; + + ModuleREST(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, EXTRA | VENDOR) + , restinterface(this, "rest") + { + + } + + ~ModuleREST() + { + if (httpref) + httpref->UnregisterPage(&restinterface); + } + + void OnReload(Configuration::Conf *conf) override + { + if (httpref) + httpref->UnregisterPage(&restinterface); + + this->httpref = ServiceReference<HTTPProvider>(conf->GetModule(this)->Get<Anope::string>("server", "httpd/main")); + + if (!httpref) + throw ConfigException("Unable to find http reference, is m_httpd loaded?"); + + httpref->RegisterPage(&restinterface); + } +}; + +MODULE_INIT(ModuleREST) diff --git a/modules/extra/sasl_dh-aes.cpp b/modules/extra/sasl_dh-aes.cpp new file mode 100644 index 000000000..b4920aeb4 --- /dev/null +++ b/modules/extra/sasl_dh-aes.cpp @@ -0,0 +1,184 @@ +/* RequiredLibraries: ssl,crypto */ +/* RequiredWindowsLibraries: ssleay32,libeay32 */ + +#include "module.h" +#include "modules/sasl.h" + +#include <openssl/bn.h> +#include <openssl/dh.h> +#include <openssl/aes.h> + +using namespace SASL; + +class DHAES : public Mechanism +{ + void Err(Session* sess, BIGNUM* key = NULL) + { + if (key) + BN_free(key); + + sasl->Fail(sess); + delete sess; + } + + public: + struct DHAESSession : SASL::Session + { + DH* dh; + DHAESSession(Mechanism *m, const Anope::string &u, DH* dh_params) : SASL::Session(m, u) + { + if (!(dh = DH_new())) + return; + + dh->g = BN_dup(dh_params->g); + dh->p = BN_dup(dh_params->p); + + if (!DH_generate_key(dh)) + { + DH_free(dh); + dh = NULL; + } + } + + ~DHAESSession() + { + if (dh) + DH_free(dh); + } + }; + + DH* dh_params; + const size_t keysize; + SASL::Session* CreateSession(const Anope::string &uid) override + { + return new DHAESSession(this, uid, dh_params); + } + + DHAES(Module *o) : Mechanism(o, "DH-AES"), keysize(256 / 8) + { + if (!(dh_params = DH_new())) + throw ModuleException("DH_new() failed!"); + + if (!DH_generate_parameters_ex(dh_params, keysize * 8, 5, NULL)) + { + DH_free(dh_params); + throw ModuleException("Could not generate DH-params"); + } + } + + ~DHAES() + { + DH_free(dh_params); + } + + void ProcessMessage(SASL::Session *session, const SASL::Message &m) override + { + DHAESSession *sess = anope_dynamic_static_cast<DHAESSession *>(session); + + if (!sess->dh) + { + sasl->SendMessage(sess, "D", "A"); + delete sess; + return; + } + + if (m.type == "S") + { + // Format: [ss]<p>[ss]<g>[ss]<pub_key> + // Where ss is a unsigned short with the size of the key + const BIGNUM* dhval[] = { sess->dh->p, sess->dh->g, sess->dh->pub_key }; + + // Find the size of our buffer - initialized at 6 because of string size data + size_t size = 6; + for (size_t i = 0; i < 3; i++) + size += BN_num_bytes(dhval[i]); + + // Fill in the DH data + std::vector<unsigned char> buffer(size); + for (size_t i = 0, pos = 0; i < 3; i++) + { + *reinterpret_cast<uint16_t*>(&buffer[pos]) = htons(BN_num_bytes(dhval[i])); + pos += 2; + BN_bn2bin(dhval[i], &buffer[pos]); + pos += BN_num_bytes(dhval[i]); + } + + Anope::string encoded; + Anope::B64Encode(Anope::string(buffer.begin(), buffer.end()), encoded); + sasl->SendMessage(sess, "C", encoded); + } + else if (m.type == "C") + { + // Make sure we have some data - actual size check is done later + if (m.data.length() < 10) + return Err(sess); + + // Format: [ss]<key>[ss]<iv>[ss]<encrypted> + // <encrypted> = <username>\0<password>\0 + + Anope::string decoded; + Anope::B64Decode(m.data, decoded); + + // Make sure we have an IV and at least one encrypted block + if ((decoded.length() < keysize + 2 + (AES_BLOCK_SIZE * 2)) || ((decoded.length() - keysize - 2) % AES_BLOCK_SIZE)) + return Err(sess); + + const unsigned char* data = reinterpret_cast<const unsigned char*>(decoded.data()); + + // Control the size of the key + if (ntohs(*reinterpret_cast<const uint16_t*>(&data[0])) != keysize) + return Err(sess); + + // Convert pubkey from binary + size_t pos = 2; + BIGNUM* pubkey = BN_bin2bn(&data[pos], keysize, NULL); + if (!pubkey) + return Err(sess); + + // Find shared key + std::vector<unsigned char> secretkey(keysize); + if (DH_compute_key(&secretkey[0], pubkey, sess->dh) != static_cast<int>(keysize)) + return Err(sess, pubkey); + + // Set decryption key + AES_KEY AESKey; + AES_set_decrypt_key(&secretkey[0], keysize * 8, &AESKey); + + // Fetch IV + pos += keysize; + std::vector<unsigned char> IV(data + pos, data + pos + AES_BLOCK_SIZE); + + // Find encrypted blocks, and decrypt + pos += AES_BLOCK_SIZE; + size_t size = decoded.length() - pos; + std::vector<char> decrypted(size + 2, 0); + AES_cbc_encrypt(&data[pos], reinterpret_cast<unsigned char*>(&decrypted[0]), size, &AESKey, &IV[0], AES_DECRYPT); + + std::string username = &decrypted[0]; + std::string password = &decrypted[username.length() + 1]; + + if (username.empty() || password.empty() || !IRCD->IsNickValid(username) || password.find_first_of("\r\n") != Anope::string::npos) + return Err(sess, pubkey); + + SASL::IdentifyRequest* req = new SASL::IdentifyRequest(this->owner, m.source, username, password); + EventManager::Get()->Dispatch(&Event::CheckAuthentication::OnCheckAuthentication, nullptr, req); + req->Dispatch(); + + BN_free(pubkey); + } + } +}; + + +class ModuleSASLDHAES : public Module +{ + DHAES dhaes; + + public: + ModuleSASLDHAES(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR | EXTRA) + , dhaes(this) + { + } +}; + +MODULE_INIT(ModuleSASLDHAES) diff --git a/modules/extra/sasl_dh-blowfish.cpp b/modules/extra/sasl_dh-blowfish.cpp new file mode 100644 index 000000000..e3e0eb4f9 --- /dev/null +++ b/modules/extra/sasl_dh-blowfish.cpp @@ -0,0 +1,194 @@ +/* RequiredLibraries: ssl,crypto */ +/* RequiredWindowsLibraries: ssleay32,libeay32 */ + +#include "module.h" +#include "modules/sasl.h" + +#include <openssl/bn.h> +#include <openssl/dh.h> +#include <openssl/blowfish.h> + +using namespace SASL; + +class DHBS : public Mechanism +{ + void Err(Session* sess, BIGNUM* key = NULL) + { + if (key) + BN_free(key); + + sasl->Fail(sess); + delete sess; + } + + public: + struct DHBSSession : SASL::Session + { + DH* dh; + DHBSSession(Mechanism *m, const Anope::string &u, DH* dh_params) : SASL::Session(m, u) + { + if (!(dh = DH_new())) + return; + + dh->g = BN_dup(dh_params->g); + dh->p = BN_dup(dh_params->p); + + if (!DH_generate_key(dh)) + { + DH_free(dh); + dh = NULL; + } + } + + ~DHBSSession() + { + if (dh) + DH_free(dh); + } + }; + + DH* dh_params; + const size_t keysize; + SASL::Session* CreateSession(const Anope::string &uid) override + { + return new DHBSSession(this, uid, dh_params); + } + + DHBS(Module *o) : Mechanism(o, "DH-BLOWFISH"), keysize(256 / 8) + { + if (!(dh_params = DH_new())) + throw ModuleException("DH_new() failed!"); + + if (!DH_generate_parameters_ex(dh_params, keysize * 8, 5, NULL)) + { + DH_free(dh_params); + throw ModuleException("Could not generate DH-params"); + } + } + + ~DHBS() + { + DH_free(dh_params); + } + + void ProcessMessage(SASL::Session *session, const SASL::Message &m) override + { + DHBSSession *sess = anope_dynamic_static_cast<DHBSSession *>(session); + + if (!sess->dh) + { + sasl->SendMessage(sess, "D", "A"); + delete sess; + return; + } + + if (m.type == "S") + { + // Format: [ss]<p>[ss]<g>[ss]<pub_key> + // Where ss is a unsigned short with the size of the key + const BIGNUM* dhval[] = { sess->dh->p, sess->dh->g, sess->dh->pub_key }; + + // Find the size of our buffer - initialized at 6 because of string size data + size_t size = 6; + for (size_t i = 0; i < 3; i++) + size += BN_num_bytes(dhval[i]); + + // Fill in the DH data + std::vector<unsigned char> buffer(size); + for (size_t i = 0, pos = 0; i < 3; i++) + { + *reinterpret_cast<uint16_t*>(&buffer[pos]) = htons(BN_num_bytes(dhval[i])); + pos += 2; + BN_bn2bin(dhval[i], &buffer[pos]); + pos += BN_num_bytes(dhval[i]); + } + + Anope::string encoded; + Anope::B64Encode(Anope::string(buffer.begin(), buffer.end()), encoded); + sasl->SendMessage(sess, "C", encoded); + } + else if (m.type == "C") + { + // Make sure we have some data - actual size check is done later + if (m.data.length() < 10) + return Err(sess); + + // Format: [ss]<key><username><\0><encrypted> + + Anope::string decoded; + Anope::B64Decode(m.data, decoded); + + // As we rely on the client giving us a null terminator at the right place, + // let's add one extra in case the client tries to crash us + const size_t decodedlen = decoded.length(); + decoded.push_back('\0'); + + // Make sure we have enough data for at least the key, a one letter username, and a block of data + if (decodedlen < keysize + 2 + 2 + 8) + return Err(sess); + + const unsigned char* data = reinterpret_cast<const unsigned char*>(decoded.data()); + + // Control the size of the key + if (ntohs(*reinterpret_cast<const uint16_t*>(&data[0])) != keysize) + return Err(sess); + + // Convert pubkey from binary + size_t pos = 2; + BIGNUM* pubkey = BN_bin2bn(&data[pos], keysize, NULL); + if (!pubkey) + return Err(sess); + + // Find shared key + std::vector<unsigned char> secretkey(DH_size(sess->dh) + 1, 0); + if (DH_compute_key(&secretkey[0], pubkey, sess->dh) != static_cast<int>(keysize)) + return Err(sess, pubkey); + + // Set decryption key + BF_KEY BFKey; + BF_set_key(&BFKey, keysize, &secretkey[0]); + + pos += keysize; + const Anope::string username = reinterpret_cast<const char*>(&data[pos]); + // Check that the username is valid, and that we have at least one block of data + // 2 + 1 + 8 = uint16_t size for keylen, \0 for username, 8 for one block of data + if (username.empty() || username.length() + keysize + 2 + 1 + 8 > decodedlen || !IRCD->IsNickValid(username)) + return Err(sess, pubkey); + + pos += username.length() + 1; + size_t size = decodedlen - pos; + + // Blowfish data blocks are 64 bits wide - valid format? + if (size % 8) + return Err(sess, pubkey); + + std::vector<char> decrypted(size + 1, 0); + for (size_t i = 0; i < size; i += 8) + BF_ecb_encrypt(&data[pos + i], reinterpret_cast<unsigned char*>(&decrypted[i]), &BFKey, BF_DECRYPT); + + std::string password = &decrypted[0]; + if (password.empty() || password.find_first_of("\r\n") != Anope::string::npos) + return Err(sess, pubkey); + + SASL::IdentifyRequest* req = new SASL::IdentifyRequest(this->owner, m.source, username, password); + EventManager::Get()->Dispatch(&Event::CheckAuthentication::OnCheckAuthentication, nullptr, req); + req->Dispatch(); + + BN_free(pubkey); + } + } +}; + + +class ModuleSASLDHBS : public Module +{ + DHBS dhbs; + + public: + ModuleSASLDHBS(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR | EXTRA) + , dhbs(this) + { + } +}; + +MODULE_INIT(ModuleSASLDHBS) diff --git a/modules/extra/m_sql_authentication.cpp b/modules/extra/sql_authentication.cpp index a742af096..0ea457ea3 100644 --- a/modules/extra/m_sql_authentication.cpp +++ b/modules/extra/sql_authentication.cpp @@ -1,13 +1,25 @@ /* + * Anope IRC Services * - * (C) 2012-2016 Anope Team - * Contact us at team@anope.org + * Copyright (C) 2012-2016 Anope Team <team@anope.org> * - * Please read COPYING and README for further details. + * This file is part of Anope. Anope 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 see <http://www.gnu.org/licenses/>. */ #include "module.h" #include "modules/sql.h" +#include "modules/nickserv.h" static Module *me; @@ -27,16 +39,16 @@ class SQLAuthenticationResult : public SQL::Interface req->Release(me); } - void OnResult(const SQL::Result &r) anope_override + void OnResult(const SQL::Result &r) override { if (r.Rows() == 0) { - Log(LOG_DEBUG) << "m_sql_authentication: Unsuccessful authentication for " << req->GetAccount(); + Log(LogType::DEBUG) << "m_sql_authentication: Unsuccessful authentication for " << req->GetAccount(); delete this; return; } - Log(LOG_DEBUG) << "m_sql_authentication: Successful authentication for " << req->GetAccount(); + Log(LogType::DEBUG) << "m_sql_authentication: Successful authentication for " << req->GetAccount(); Anope::string email; try @@ -45,19 +57,19 @@ class SQLAuthenticationResult : public SQL::Interface } catch (const SQL::Exception &) { } - NickAlias *na = NickAlias::Find(req->GetAccount()); - BotInfo *NickServ = Config->GetClient("NickServ"); + NickServ::Nick *na = NickServ::FindNick(req->GetAccount()); + ServiceBot *NickServ = Config->GetClient("NickServ"); if (na == NULL) { - na = new NickAlias(req->GetAccount(), new NickCore(req->GetAccount())); - FOREACH_MOD(OnNickRegister, (user, na, "")); + na = new NickServ::Nick(req->GetAccount(), new NickServ::Account(req->GetAccount())); + NickServ::EventManager::Get()->Dispatch(&NickServ::Event::NickRegister::OnNickRegister, user, na, ""); if (user && NickServ) - user->SendMessage(NickServ, _("Your account \002%s\002 has been successfully created."), na->nick.c_str()); + user->SendMessage(NickServ, _("Your account \002%s\002 has been successfully created."), na->GetNick().c_str()); } - if (!email.empty() && email != na->nc->email) + if (!email.empty() && email != na->GetAccount()->GetEmail()) { - na->nc->email = email; + na->GetAccount()->GetEmail() = email; if (user && NickServ) user->SendMessage(NickServ, _("Your email has been updated to \002%s\002."), email.c_str()); } @@ -66,7 +78,7 @@ class SQLAuthenticationResult : public SQL::Interface delete this; } - void OnError(const SQL::Result &r) anope_override + void OnError(const SQL::Result &r) override { Log(this->owner) << "m_sql_authentication: Error executing query " << r.GetQuery().query << ": " << r.GetError(); delete this; @@ -74,6 +86,8 @@ class SQLAuthenticationResult : public SQL::Interface }; class ModuleSQLAuthentication : public Module + , public EventHook<Event::PreCommand> + , public EventHook<Event::CheckAuthentication> { Anope::string engine; Anope::string query; @@ -88,18 +102,18 @@ class ModuleSQLAuthentication : public Module } - void OnReload(Configuration::Conf *conf) anope_override + void OnReload(Configuration::Conf *conf) override { Configuration::Block *config = conf->GetModule(this); - this->engine = config->Get<const Anope::string>("engine"); - this->query = config->Get<const Anope::string>("query"); - this->disable_reason = config->Get<const Anope::string>("disable_reason"); + this->engine = config->Get<Anope::string>("engine"); + this->query = config->Get<Anope::string>("query"); + this->disable_reason = config->Get<Anope::string>("disable_reason"); this->disable_email_reason = config->Get<Anope::string>("disable_email_reason"); this->SQL = ServiceReference<SQL::Provider>("SQL::Provider", this->engine); } - EventReturn OnPreCommand(CommandSource &source, Command *command, std::vector<Anope::string> ¶ms) anope_override + EventReturn OnPreCommand(CommandSource &source, Command *command, std::vector<Anope::string> ¶ms) override { if (!this->disable_reason.empty() && (command->name == "nickserv/register" || command->name == "nickserv/group")) { @@ -116,7 +130,7 @@ class ModuleSQLAuthentication : public Module return EVENT_CONTINUE; } - void OnCheckAuthentication(User *u, IdentifyRequest *req) anope_override + void OnCheckAuthentication(User *u, IdentifyRequest *req) override { if (!this->SQL) { @@ -141,7 +155,7 @@ class ModuleSQLAuthentication : public Module this->SQL->Run(new SQLAuthenticationResult(u, req), q); - Log(LOG_DEBUG) << "m_sql_authentication: Checking authentication for " << req->GetAccount(); + Log(LogType::DEBUG) << "m_sql_authentication: Checking authentication for " << req->GetAccount(); } }; diff --git a/modules/extra/m_sql_log.cpp b/modules/extra/sql_log.cpp index 3dd6c936f..d561a0fb2 100644 --- a/modules/extra/m_sql_log.cpp +++ b/modules/extra/sql_log.cpp @@ -1,15 +1,27 @@ /* + * Anope IRC Services * - * (C) 2003-2016 Anope Team - * Contact us at team@anope.org + * Copyright (C) 2014-2016 Anope Team <team@anope.org> * - * Please read COPYING and README for further details. + * This file is part of Anope. Anope 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 see <http://www.gnu.org/licenses/>. */ #include "module.h" #include "modules/sql.h" class SQLLog : public Module + , public EventHook<Event::LogMessage> { std::set<Anope::string> inited; Anope::string table; @@ -19,13 +31,13 @@ class SQLLog : public Module { } - void OnReload(Configuration::Conf *conf) anope_override + void OnReload(Configuration::Conf *conf) override { Configuration::Block *config = conf->GetModule(this); - this->table = config->Get<const Anope::string>("table", "logs"); + this->table = config->Get<Anope::string>("table", "logs"); } - void OnLogMessage(LogInfo *li, const Log *l, const Anope::string &msg) anope_override + void OnLogMessage(LogInfo *li, const Log *l, const Anope::string &msg) override { Anope::string ref_name; ServiceReference<SQL::Provider> SQL; @@ -67,28 +79,28 @@ class SQLLog : public Module switch (l->type) { - case LOG_ADMIN: + case LogType::ADMIN: insert.SetValue("type", "ADMIN"); break; - case LOG_OVERRIDE: + case LogType::OVERRIDE: insert.SetValue("type", "OVERRIDE"); break; - case LOG_COMMAND: + case LogType::COMMAND: insert.SetValue("type", "COMMAND"); break; - case LOG_SERVER: + case LogType::SERVER: insert.SetValue("type", "SERVER"); break; - case LOG_CHANNEL: + case LogType::CHANNEL: insert.SetValue("type", "CHANNEL"); break; - case LOG_USER: + case LogType::USER: insert.SetValue("type", "USER"); break; - case LOG_MODULE: + case LogType::MODULE: insert.SetValue("type", "MODULE"); break; - case LOG_NORMAL: + case LogType::NORMAL: insert.SetValue("type", "NORMAL"); break; default: @@ -96,9 +108,9 @@ class SQLLog : public Module } insert.SetValue("user", l->u ? l->u->nick : ""); - insert.SetValue("acc", l->nc ? l->nc->display : ""); + insert.SetValue("acc", l->nc ? l->nc->GetDisplay() : ""); insert.SetValue("command", l->c ? l->c->name : ""); - insert.SetValue("channel", l->ci ? l->ci->name : ""); + insert.SetValue("channel", l->ci ? l->ci->GetName() : ""); insert.SetValue("msg", msg); SQL->Run(NULL, insert); diff --git a/modules/extra/sql_oper.cpp b/modules/extra/sql_oper.cpp new file mode 100644 index 000000000..4beb3d39f --- /dev/null +++ b/modules/extra/sql_oper.cpp @@ -0,0 +1,170 @@ +/* + * Anope IRC Services + * + * Copyright (C) 2012-2016 Anope Team <team@anope.org> + * + * This file is part of Anope. Anope 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 see <http://www.gnu.org/licenses/>. + */ + +#include "module.h" +#include "modules/sql.h" + +class SQLOperResult : public SQL::Interface +{ + Reference<User> user; + + struct SQLOperResultDeleter + { + SQLOperResult *res; + SQLOperResultDeleter(SQLOperResult *r) : res(r) { } + ~SQLOperResultDeleter() { delete res; } + }; + + void Deoper() + { + Oper *oper = user->Account()->GetOper(); + if (oper != nullptr) + { + oper->Delete(); + + Log(this->owner) << "Removed services operator from " << user->nick << " (" << user->Account()->GetDisplay() << ")"; + user->RemoveMode(Config->GetClient("OperServ"), "OPER"); // Probably not set, just incase + } + } + + public: + SQLOperResult(Module *m, User *u) : SQL::Interface(m), user(u) { } + + void OnResult(const SQL::Result &r) override + { + SQLOperResultDeleter d(this); + + if (!user || !user->Account()) + return; + + if (r.Rows() == 0) + { + Log(LogType::DEBUG) << "m_sql_oper: Got 0 rows for " << user->nick; + Deoper(); + return; + } + + Anope::string opertype; + try + { + opertype = r.Get(0, "opertype"); + } + catch (const SQL::Exception &) + { + Log(this->owner) << "Expected column named \"opertype\" but one was not found"; + return; + } + + Log(LogType::DEBUG) << "m_sql_oper: Got result for " << user->nick << ", opertype " << opertype; + + Anope::string modes; + try + { + modes = r.Get(0, "modes"); + } + catch (const SQL::Exception &) { } + + ServiceBot *OperServ = Config->GetClient("OperServ"); + if (opertype.empty()) + { + Deoper(); + return; + } + + OperType *ot = OperType::Find(opertype); + if (ot == NULL) + { + Log(this->owner) << "m_sql_oper: Oper " << user->nick << " has type " << opertype << ", but this opertype does not exist?"; + return; + } + + Oper *oper = user->Account()->GetOper(); + if (oper == nullptr || oper->GetType() != ot) + { + Log(this->owner) << "m_sql_oper: Tieing oper " << user->nick << " to type " << opertype; + + if (oper) + oper->Delete(); + + oper = Serialize::New<Oper *>(); + oper->SetName(user->Account()->GetDisplay()); + oper->SetType(ot); + + user->Account()->SetOper(oper); + } + + if (!user->HasMode("OPER")) + { + IRCD->SendOper(user); + + if (!modes.empty()) + user->SetModes(OperServ, "%s", modes.c_str()); + } + } + + void OnError(const SQL::Result &r) override + { + SQLOperResultDeleter d(this); + Log(this->owner) << "m_sql_oper: Error executing query " << r.GetQuery().query << ": " << r.GetError(); + } +}; + +class ModuleSQLOper : public Module + , public EventHook<Event::NickIdentify> +{ + Anope::string engine; + Anope::string query; + + ServiceReference<SQL::Provider> SQL; + + public: + ModuleSQLOper(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, EXTRA | VENDOR), + EventHook<Event::NickIdentify>(this) + { + } + + void OnReload(Configuration::Conf *conf) override + { + Configuration::Block *config = conf->GetModule(this); + + this->engine = config->Get<Anope::string>("engine"); + this->query = config->Get<Anope::string>("query"); + + this->SQL = ServiceReference<SQL::Provider>(engine); + } + + void OnNickIdentify(User *u) override + { + if (!this->SQL) + { + Log() << "Unable to find SQL engine: " << engine; + return; + } + + SQL::Query q(this->query); + q.SetValue("a", u->Account()->GetDisplay()); + q.SetValue("i", u->ip.addr()); + + this->SQL->Run(new SQLOperResult(this, u), q); + + Log(LogType::DEBUG) << "m_sql_oper: Checking authentication for " << u->Account()->GetDisplay(); + } +}; + +MODULE_INIT(ModuleSQLOper) diff --git a/modules/extra/m_ssl_gnutls.cpp b/modules/extra/ssl_gnutls.cpp index 318efe650..eecd6825e 100644 --- a/modules/extra/m_ssl_gnutls.cpp +++ b/modules/extra/ssl_gnutls.cpp @@ -1,10 +1,21 @@ /* + * Anope IRC Services * - * (C) 2014 Attila Molnar <attilamolnar@hush.com> - * (C) 2014-2016 Anope Team - * Contact us at team@anope.org + * Copyright (C) 2014 Attila Molnar <attilamolnar@hush.com> + * Copyright (C) 2014-2016 Anope Team <team@anope.org> * - * Please read COPYING and README for further details. + * This file is part of Anope. Anope 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 see <http://www.gnu.org/licenses/>. */ /* RequiredLibraries: gnutls */ @@ -30,7 +41,7 @@ class MySSLService : public SSLService /** Initialize a socket to use SSL * @param s The socket */ - void Init(Socket *s) anope_override; + void Init(Socket *s) override; }; class SSLSocketIO : public SocketIO @@ -49,43 +60,43 @@ class SSLSocketIO : public SocketIO * @param sz How much to read * @return Number of bytes received */ - int Recv(Socket *s, char *buf, size_t sz) anope_override; + int Recv(Socket *s, char *buf, size_t sz) override; /** Write something to the socket * @param s The socket * @param buf The data to write * @param size The length of the data */ - int Send(Socket *s, const char *buf, size_t sz) anope_override; + int Send(Socket *s, const char *buf, size_t sz) override; /** Accept a connection from a socket * @param s The socket * @return The new socket */ - ClientSocket *Accept(ListenSocket *s) anope_override; + ClientSocket *Accept(ListenSocket *s) override; /** Finished accepting a connection from a socket * @param s The socket * @return SF_ACCEPTED if accepted, SF_ACCEPTING if still in process, SF_DEAD on error */ - SocketFlag FinishAccept(ClientSocket *cs) anope_override; + SocketFlag FinishAccept(ClientSocket *cs) override; /** Connect the socket * @param s THe socket * @param target IP to connect to * @param port to connect to */ - void Connect(ConnectionSocket *s, const Anope::string &target, int port) anope_override; + void Connect(ConnectionSocket *s, const Anope::string &target, int port) override; /** Called to potentially finish a pending connection * @param s The socket * @return SF_CONNECTED on success, SF_CONNECTING if still pending, and SF_DEAD on error. */ - SocketFlag FinishConnect(ConnectionSocket *s) anope_override; + SocketFlag FinishConnect(ConnectionSocket *s) override; /** Called when the socket is destructing */ - void Destroy() anope_override; + void Destroy() override; }; namespace GnuTLS @@ -295,6 +306,7 @@ namespace GnuTLS } class GnuTLSModule : public Module + , public EventHook<Event::PreServerConnect> { GnuTLS::Init libinit; @@ -302,7 +314,9 @@ class GnuTLSModule : public Module GnuTLS::X509CertCredentials *cred; MySSLService service; - GnuTLSModule(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, EXTRA | VENDOR), cred(NULL), service(this, "ssl") + GnuTLSModule(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, EXTRA | VENDOR) + , cred(NULL) + , service(this, "ssl") { me = this; this->SetPermanent(true); @@ -332,13 +346,13 @@ class GnuTLSModule : public Module } } - void OnReload(Configuration::Conf *conf) anope_override + void OnReload(Configuration::Conf *conf) override { Configuration::Block *config = conf->GetModule(this); - const Anope::string certfile = config->Get<const Anope::string>("cert", "data/anope.crt"); - const Anope::string keyfile = config->Get<const Anope::string>("key", "data/anope.key"); - const Anope::string dhfile = config->Get<const Anope::string>("dh", "data/dhparams.pem"); + const Anope::string certfile = config->Get<Anope::string>("cert", "data/anope.crt"); + const Anope::string keyfile = config->Get<Anope::string>("key", "data/anope.key"); + const Anope::string dhfile = config->Get<Anope::string>("dh", "data/dhparams.pem"); CheckFile(certfile); CheckFile(keyfile); @@ -357,7 +371,7 @@ class GnuTLSModule : public Module delete newcred; throw; } - Log(LOG_DEBUG) << "m_ssl_gnutls: Successfully loaded DH parameters from " << dhfile; + Log(LogType::DEBUG) << "m_ssl_gnutls: Successfully loaded DH parameters from " << dhfile; } if (cred) @@ -365,10 +379,10 @@ class GnuTLSModule : public Module cred = newcred; cred->incrref(); - Log(LOG_DEBUG) << "m_ssl_gnutls: Successfully loaded certificate " << certfile << " and private key " << keyfile; + Log(LogType::DEBUG) << "m_ssl_gnutls: Successfully loaded certificate " << certfile << " and private key " << keyfile; } - void OnPreServerConnect() anope_override + void OnPreServerConnect() override { Configuration::Block *config = Config->GetBlock("uplink", Anope::CurrentUplink); diff --git a/modules/extra/m_ssl_openssl.cpp b/modules/extra/ssl_openssl.cpp index bdc3a5624..20673b5ef 100644 --- a/modules/extra/m_ssl_openssl.cpp +++ b/modules/extra/ssl_openssl.cpp @@ -1,9 +1,20 @@ /* + * Anope IRC Services * - * (C) 2010-2016 Anope Team - * Contact us at team@anope.org + * Copyright (C) 2010-2016 Anope Team <team@anope.org> * - * Please read COPYING and README for further details. + * This file is part of Anope. Anope 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 see <http://www.gnu.org/licenses/>. */ /* RequiredLibraries: ssl,crypto */ @@ -29,7 +40,7 @@ class MySSLService : public SSLService /** Initialize a socket to use SSL * @param s The socket */ - void Init(Socket *s) anope_override; + void Init(Socket *s) override; }; class SSLSocketIO : public SocketIO @@ -48,55 +59,57 @@ class SSLSocketIO : public SocketIO * @param sz How much to read * @return Number of bytes received */ - int Recv(Socket *s, char *buf, size_t sz) anope_override; + int Recv(Socket *s, char *buf, size_t sz) override; /** Write something to the socket * @param s The socket * @param buf The data to write * @param size The length of the data */ - int Send(Socket *s, const char *buf, size_t sz) anope_override; + int Send(Socket *s, const char *buf, size_t sz) override; /** Accept a connection from a socket * @param s The socket * @return The new socket */ - ClientSocket *Accept(ListenSocket *s) anope_override; + ClientSocket *Accept(ListenSocket *s) override; /** Finished accepting a connection from a socket * @param s The socket * @return SF_ACCEPTED if accepted, SF_ACCEPTING if still in process, SF_DEAD on error */ - SocketFlag FinishAccept(ClientSocket *cs) anope_override; + SocketFlag FinishAccept(ClientSocket *cs) override; /** Connect the socket * @param s THe socket * @param target IP to connect to * @param port to connect to */ - void Connect(ConnectionSocket *s, const Anope::string &target, int port) anope_override; + void Connect(ConnectionSocket *s, const Anope::string &target, int port) override; /** Called to potentially finish a pending connection * @param s The socket * @return SF_CONNECTED on success, SF_CONNECTING if still pending, and SF_DEAD on error. */ - SocketFlag FinishConnect(ConnectionSocket *s) anope_override; + SocketFlag FinishConnect(ConnectionSocket *s) override; /** Called when the socket is destructing */ - void Destroy() anope_override; + void Destroy() override; }; class SSLModule; static SSLModule *me; class SSLModule : public Module + , public EventHook<Event::PreServerConnect> { Anope::string certfile, keyfile; public: MySSLService service; - SSLModule(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, EXTRA | VENDOR), service(this, "ssl") + SSLModule(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, EXTRA | VENDOR) + , service(this, "ssl") { me = this; @@ -138,19 +151,19 @@ class SSLModule : public Module SSL_CTX_free(server_ctx); } - void OnReload(Configuration::Conf *conf) anope_override + void OnReload(Configuration::Conf *conf) override { Configuration::Block *config = conf->GetModule(this); - this->certfile = config->Get<const Anope::string>("cert", "data/anope.crt"); - this->keyfile = config->Get<const Anope::string>("key", "data/anope.key"); + this->certfile = config->Get<Anope::string>("cert", "data/anope.crt"); + this->keyfile = config->Get<Anope::string>("key", "data/anope.key"); if (Anope::IsFile(this->certfile.c_str())) { if (!SSL_CTX_use_certificate_chain_file(client_ctx, this->certfile.c_str()) || !SSL_CTX_use_certificate_chain_file(server_ctx, this->certfile.c_str())) throw ConfigException("Error loading certificate"); else - Log(LOG_DEBUG) << "m_ssl_openssl: Successfully loaded certificate " << this->certfile; + Log(LogType::DEBUG) << "m_ssl_openssl: Successfully loaded certificate " << this->certfile; } else Log() << "Unable to open certificate " << this->certfile; @@ -160,7 +173,7 @@ class SSLModule : public Module if (!SSL_CTX_use_PrivateKey_file(client_ctx, this->keyfile.c_str(), SSL_FILETYPE_PEM) || !SSL_CTX_use_PrivateKey_file(server_ctx, this->keyfile.c_str(), SSL_FILETYPE_PEM)) throw ConfigException("Error loading private key"); else - Log(LOG_DEBUG) << "m_ssl_openssl: Successfully loaded private key " << this->keyfile; + Log(LogType::DEBUG) << "m_ssl_openssl: Successfully loaded private key " << this->keyfile; } else { @@ -186,7 +199,7 @@ class SSLModule : public Module } } - void OnPreServerConnect() anope_override + void OnPreServerConnect() override { Configuration::Block *config = Config->GetBlock("uplink", Anope::CurrentUplink); @@ -205,7 +218,7 @@ void MySSLService::Init(Socket *s) { if (s->io != &NormalSocketIO) throw CoreException("Socket initializing SSL twice"); - + s->io = new SSLSocketIO(); } @@ -283,7 +296,7 @@ ClientSocket *SSLSocketIO::Accept(ListenSocket *s) newsocket->flags[SF_ACCEPTING] = true; this->FinishAccept(newsocket); - + return newsocket; } @@ -297,7 +310,7 @@ SocketFlag SSLSocketIO::FinishAccept(ClientSocket *cs) throw SocketException("SSLSocketIO::FinishAccept called for a socket not accepted nor accepting?"); SSLSocketIO *io = anope_dynamic_static_cast<SSLSocketIO *>(cs->io); - + int ret = SSL_accept(io->sslsock); if (ret <= 0) { @@ -378,7 +391,7 @@ SocketFlag SSLSocketIO::FinishConnect(ConnectionSocket *s) if (!SSL_set_fd(io->sslsock, s->GetFD())) throw SocketException("Unable to set SSL fd"); } - + int ret = SSL_connect(io->sslsock); if (ret <= 0) { diff --git a/modules/extra/stats/m_chanstats.cpp b/modules/extra/stats/chanstats.cpp index e21b3641d..adc002c8c 100644 --- a/modules/extra/stats/m_chanstats.cpp +++ b/modules/extra/stats/chanstats.cpp @@ -10,9 +10,9 @@ class CommandCSSetChanstats : public Command this->SetSyntax(_("\037channel\037 {ON | OFF}")); } - void Execute(CommandSource &source, const std::vector<Anope::string> ¶ms) anope_override + void Execute(CommandSource &source, const std::vector<Anope::string> ¶ms) override { - ChannelInfo *ci = ChannelInfo::Find(params[0]); + ChanServ::Channel *ci = ChanServ::Find(params[0]); if (!ci) { source.Reply(CHAN_X_NOT_REGISTERED, params[0].c_str()); @@ -20,7 +20,7 @@ class CommandCSSetChanstats : public Command } EventReturn MOD_RESULT; - FOREACH_RESULT(OnSetChannelOption, MOD_RESULT, (source, this, ci, params[1])); + MOD_RESULT = EventManager::Get()->Dispatch(&Event::SetChannelOption::OnSetChannelOption, source, this, ci, params[1]); if (MOD_RESULT == EVENT_STOP) return; @@ -34,11 +34,11 @@ class CommandCSSetChanstats : public Command { ci->Extend<bool>("CS_STATS"); source.Reply(_("Chanstats statistics are now enabled for this channel.")); - Log(source.AccessFor(ci).HasPriv("SET") ? LOG_COMMAND : LOG_OVERRIDE, source, this, ci) << "to enable chanstats"; + Log(source.AccessFor(ci).HasPriv("SET") ? LogType::COMMAND : LogType::OVERRIDE, source, this, ci) << "to enable chanstats"; } else if (params[1].equals_ci("OFF")) { - Log(source.AccessFor(ci).HasPriv("SET") ? LOG_COMMAND : LOG_OVERRIDE, source, this, ci) << "to disable chanstats"; + Log(source.AccessFor(ci).HasPriv("SET") ? LogType::COMMAND : LogType::OVERRIDE, source, this, ci) << "to disable chanstats"; ci->Shrink<bool>("CS_STATS"); source.Reply(_("Chanstats statistics are now disabled for this channel.")); } @@ -46,7 +46,7 @@ class CommandCSSetChanstats : public Command this->OnSyntaxError(source, ""); } - bool OnHelp(CommandSource &source, const Anope::string &) anope_override + bool OnHelp(CommandSource &source, const Anope::string &) override { this->SendSyntax(source); source.Reply(" "); @@ -65,7 +65,7 @@ class CommandNSSetChanstats : public Command } void Run(CommandSource &source, const Anope::string &user, const Anope::string ¶m, bool saset = false) { - NickAlias *na = NickAlias::Find(user); + NickServ::Nick *na = NickServ::FindNick(user); if (!na) { source.Reply(NICK_X_NOT_REGISTERED, user.c_str()); @@ -73,25 +73,25 @@ class CommandNSSetChanstats : public Command } EventReturn MOD_RESULT; - FOREACH_RESULT(OnSetNickOption, MOD_RESULT, (source, this, na->nc, param)); + MOD_RESULT = EventManager::Get()->Dispatch(&Event::SetNickOption::OnSetNickOption, source, this, na->GetAccount(), param); if (MOD_RESULT == EVENT_STOP) return; if (param.equals_ci("ON")) { - Log(na->nc == source.GetAccount() ? LOG_COMMAND : LOG_ADMIN, source, this) << "to enable chanstats for " << na->nc->display; - na->nc->Extend<bool>("NS_STATS"); + Log(na->GetAccount() == source.GetAccount() ? LogType::COMMAND : LogType::ADMIN, source, this) << "to enable chanstats for " << na->GetAccount()->GetDisplay(); + na->GetAccount()->Extend<bool>("NS_STATS"); if (saset) - source.Reply(_("Chanstats statistics are now enabled for %s"), na->nc->display.c_str()); + source.Reply(_("Chanstats statistics are now enabled for %s"), na->GetAccount()->GetDisplay().c_str()); else source.Reply(_("Chanstats statistics are now enabled for your nick.")); } else if (param.equals_ci("OFF")) { - Log(na->nc == source.GetAccount() ? LOG_COMMAND : LOG_ADMIN, source, this) << "to disable chanstats for " << na->nc->display; - na->nc->Shrink<bool>("NS_STATS"); + Log(na->GetAccount() == source.GetAccount() ? LogType::COMMAND : LogType::ADMIN, source, this) << "to disable chanstats for " << na->GetAccount()->GetDisplay(); + na->GetAccount()->Shrink<bool>("NS_STATS"); if (saset) - source.Reply(_("Chanstats statistics are now disabled for %s"), na->nc->display.c_str()); + source.Reply(_("Chanstats statistics are now disabled for %s"), na->GetAccount()->GetDisplay().c_str()); else source.Reply(_("Chanstats statistics are now disabled for your nick.")); } @@ -99,12 +99,12 @@ class CommandNSSetChanstats : public Command this->OnSyntaxError(source, "CHANSTATS"); } - void Execute(CommandSource &source, const std::vector<Anope::string> ¶ms) anope_override + void Execute(CommandSource &source, const std::vector<Anope::string> ¶ms) override { - this->Run(source, source.nc->display, params[0]); + this->Run(source, source.nc->GetDisplay(), params[0]); } - - bool OnHelp(CommandSource &source, const Anope::string &) anope_override + + bool OnHelp(CommandSource &source, const Anope::string &) override { this->SendSyntax(source); source.Reply(" "); @@ -122,12 +122,12 @@ class CommandNSSASetChanstats : public CommandNSSetChanstats this->SetSyntax(_("\037nickname\037 {ON | OFF}")); } - void Execute(CommandSource &source, const std::vector<Anope::string> ¶ms) anope_override + void Execute(CommandSource &source, const std::vector<Anope::string> ¶ms) override { this->Run(source, params[0], params[1], true); } - bool OnHelp(CommandSource &source, const Anope::string &) anope_override + bool OnHelp(CommandSource &source, const Anope::string &) override { this->SendSyntax(source); source.Reply(" "); @@ -141,22 +141,22 @@ class MySQLInterface : public SQL::Interface public: MySQLInterface(Module *o) : SQL::Interface(o) { } - void OnResult(const SQL::Result &r) anope_override + void OnResult(const SQL::Result &r) override { } - void OnError(const SQL::Result &r) anope_override + void OnError(const SQL::Result &r) override { if (!r.GetQuery().query.empty()) - Log(LOG_DEBUG) << "Chanstats: Error executing query " << r.finished_query << ": " << r.GetError(); + Log(LogType::DEBUG) << "Chanstats: Error executing query " << r.finished_query << ": " << r.GetError(); else - Log(LOG_DEBUG) << "Chanstats: Error executing query: " << r.GetError(); + Log(LogType::DEBUG) << "Chanstats: Error executing query: " << r.GetError(); } }; class MChanstats : public Module { - SerializableExtensibleItem<bool> cs_stats, ns_stats; + Serialize::Field<bool> cs_stats, ns_stats; CommandCSSetChanstats commandcssetchanstats; @@ -200,7 +200,7 @@ class MChanstats : public Module const Anope::string GetDisplay(User *u) { if (u && u->Account() && ns_stats.HasExt(u->Account())) - return u->Account()->display; + return u->Account()->GetDisplay(); else return ""; } @@ -484,16 +484,16 @@ class MChanstats : public Module { } - void OnReload(Configuration::Conf *conf) anope_override + void OnReload(Configuration::Conf *conf) override { Configuration::Block *block = conf->GetModule(this); - prefix = block->Get<const Anope::string>("prefix", "anope_"); - SmileysHappy = block->Get<const Anope::string>("SmileysHappy"); - SmileysSad = block->Get<const Anope::string>("SmileysSad"); - SmileysOther = block->Get<const Anope::string>("SmileysOther"); + prefix = block->Get<Anope::string>("prefix", "anope_"); + SmileysHappy = block->Get<Anope::string>("SmileysHappy"); + SmileysSad = block->Get<Anope::string>("SmileysSad"); + SmileysOther = block->Get<Anope::string>("SmileysOther"); NSDefChanstats = block->Get<bool>("ns_def_chanstats"); CSDefChanstats = block->Get<bool>("cs_def_chanstats"); - Anope::string engine = block->Get<const Anope::string>("engine"); + Anope::string engine = block->Get<Anope::string>("engine"); this->sql = ServiceReference<SQL::Provider>("SQL::Provider", engine); if (sql) this->CheckTables(); @@ -501,7 +501,7 @@ class MChanstats : public Module Log(this) << "no database connection to " << engine; } - void OnChanInfo(CommandSource &source, ChannelInfo *ci, InfoFormatter &info, bool show_all) anope_override + void OnChanInfo(CommandSource &source, ChanServ::Channel *ci, InfoFormatter &info, bool show_all) override { if (!show_all) return; @@ -509,15 +509,15 @@ class MChanstats : public Module info.AddOption(_("Chanstats")); } - void OnNickInfo(CommandSource &source, NickAlias *na, InfoFormatter &info, bool show_hidden) anope_override + void OnNickInfo(CommandSource &source, NickServ::Nick *na, InfoFormatter &info, bool show_hidden) override { if (!show_hidden) return; - if (ns_stats.HasExt(na->nc)) + if (ns_stats.HasExt(na->GetAccount())) info.AddOption(_("Chanstats")); } - void OnTopicUpdated(User *source, Channel *c, const Anope::string &user, const Anope::string &topic) anope_override + void OnTopicUpdated(User *source, Channel *c, const Anope::string &user, const Anope::string &topic) override { if (!source || !source->Account() || !c->ci || !cs_stats.HasExt(c->ci)) return; @@ -527,13 +527,13 @@ class MChanstats : public Module this->RunQuery(query); } - EventReturn OnChannelModeSet(Channel *c, MessageSource &setter, ChannelMode *mode, const Anope::string ¶m) anope_override + EventReturn OnChannelModeSet(Channel *c, const MessageSource &setter, ChannelMode *mode, const Anope::string ¶m) override { this->OnModeChange(c, setter.GetUser()); return EVENT_CONTINUE; } - EventReturn OnChannelModeUnset(Channel *c, MessageSource &setter, ChannelMode *, const Anope::string ¶m) anope_override + EventReturn OnChannelModeUnset(Channel *c, const MessageSource &setter, ChannelMode *, const Anope::string ¶m) override { this->OnModeChange(c, setter.GetUser()); return EVENT_CONTINUE; @@ -552,7 +552,7 @@ class MChanstats : public Module } public: - void OnPreUserKicked(const MessageSource &source, ChanUserContainer *cu, const Anope::string &kickmsg) anope_override + void OnPreUserKicked(const MessageSource &source, ChanUserContainer *cu, const Anope::string &kickmsg) override { if (!cu->chan->ci || !cs_stats.HasExt(cu->chan->ci)) return; @@ -568,7 +568,7 @@ class MChanstats : public Module this->RunQuery(query); } - void OnPrivmsg(User *u, Channel *c, Anope::string &msg) anope_override + void OnPrivmsg(User *u, Channel *c, Anope::string &msg) override { if (!c->ci || !cs_stats.HasExt(c->ci)) return; @@ -609,29 +609,29 @@ class MChanstats : public Module this->RunQuery(query); } - void OnDelCore(NickCore *nc) anope_override + void OnDelCore(NickServ::Account *nc) override { query = "DELETE FROM `" + prefix + "chanstats` WHERE `nick` = @nick@;"; - query.SetValue("nick", nc->display); + query.SetValue("nick", nc->GetDisplay()); this->RunQuery(query); } - void OnChangeCoreDisplay(NickCore *nc, const Anope::string &newdisplay) anope_override + void OnChangeCoreDisplay(NickServ::Account *nc, const Anope::string &newdisplay) override { query = "CALL " + prefix + "chanstats_proc_chgdisplay(@old_display@, @new_display@);"; - query.SetValue("old_display", nc->display); + query.SetValue("old_display", nc->GetDisplay()); query.SetValue("new_display", newdisplay); this->RunQuery(query); } - void OnDelChan(ChannelInfo *ci) anope_override + void OnDelChan(ChanServ::Channel *ci) override { query = "DELETE FROM `" + prefix + "chanstats` WHERE `chan` = @channel@;"; - query.SetValue("channel", ci->name); + query.SetValue("channel", ci->GetName()); this->RunQuery(query); } - void OnChanRegistered(ChannelInfo *ci) + void OnChanRegistered(ChanServ::Channel *ci) { if (CSDefChanstats) ci->Extend<bool>("CS_STATS"); @@ -640,7 +640,7 @@ class MChanstats : public Module void OnNickRegister(User *user, NickAlias *na, const Anope::string &) { if (NSDefChanstats) - na->nc->Extend<bool>("NS_STATS"); + na->GetAccount()->Extend<bool>("NS_STATS"); } }; diff --git a/modules/extra/stats/cs_fantasy_stats.cpp b/modules/extra/stats/cs_fantasy_stats.cpp index 37830abb1..1cbc4cd15 100644 --- a/modules/extra/stats/cs_fantasy_stats.cpp +++ b/modules/extra/stats/cs_fantasy_stats.cpp @@ -1,6 +1,6 @@ /* Chanstats core functions * - * (C) 2003-2016 Anope Team + * (C) 2003-2014 Anope Team * Contact us at team@anope.org * * Please read COPYING and README for further details. @@ -17,16 +17,16 @@ class MySQLInterface : public SQL::Interface public: MySQLInterface(Module *o) : SQL::Interface(o) { } - void OnResult(const SQL::Result &r) anope_override + void OnResult(const SQL::Result &r) override { } - void OnError(const SQL::Result &r) anope_override + void OnError(const SQL::Result &r) override { if (!r.GetQuery().query.empty()) - Log(LOG_DEBUG) << "Chanstats: Error executing query " << r.finished_query << ": " << r.GetError(); + Log(LogType::DEBUG) << "Chanstats: Error executing query " << r.finished_query << ": " << r.GetError(); else - Log(LOG_DEBUG) << "Chanstats: Error executing query: " << r.GetError(); + Log(LogType::DEBUG) << "Chanstats: Error executing query: " << r.GetError(); } }; @@ -73,10 +73,10 @@ class CSStats : public Module } - void OnReload(Configuration::Conf *conf) anope_override + void OnReload(Configuration::Conf *conf) override { - prefix = conf->GetModule("m_chanstats")->Get<const Anope::string>("prefix", "anope_"); - this->sql = ServiceReference<SQL::Provider>("SQL::Provider", conf->GetModule("m_chanstats")->Get<const Anope::string>("engine")); + prefix = conf->GetModule("chanstats")->Get<Anope::string>("prefix", "anope_"); + this->sql = ServiceReference<SQL::Provider>("SQL::Provider", conf->GetModule("chanstats")->Get<Anope::string>("engine")); } SQL::Result RunQuery(const SQL::Query &query) @@ -113,8 +113,8 @@ class CSStats : public Module channel = params[0]; else { - if (NickAlias *na = NickAlias::Find(params[0])) - display = na->nc->display; + if (NickServ::Nick *na = NickServ::FindNick(params[0])) + display = na->GetAccount()->GetDisplay(); else { source.Reply(_("%s not found."), params[0].c_str()); @@ -125,7 +125,7 @@ class CSStats : public Module } if (display.empty()) - display = source.nc->display; + display = source.nc->GetDisplay(); try { @@ -157,7 +157,7 @@ class CSStats : public Module } catch (const SQL::Exception &ex) { - Log(LOG_DEBUG) << ex.GetReason(); + Log(LogType::DEBUG) << ex.GetReason(); } } diff --git a/modules/extra/stats/cs_fantasy_top.cpp b/modules/extra/stats/cs_fantasy_top.cpp index 0de75d855..2be1d2f1c 100644 --- a/modules/extra/stats/cs_fantasy_top.cpp +++ b/modules/extra/stats/cs_fantasy_top.cpp @@ -1,6 +1,6 @@ /* Chanstats core functions * - * (C) 2003-2016 Anope Team + * (C) 2003-2014 Anope Team * Contact us at team@anope.org * * Please read COPYING and README for further details. @@ -17,16 +17,16 @@ class MySQLInterface : public SQL::Interface public: MySQLInterface(Module *o) : SQL::Interface(o) { } - void OnResult(const SQL::Result &r) anope_override + void OnResult(const SQL::Result &r) override { } - void OnError(const SQL::Result &r) anope_override + void OnError(const SQL::Result &r) override { if (!r.GetQuery().query.empty()) - Log(LOG_DEBUG) << "Chanstats: Error executing query " << r.finished_query << ": " << r.GetError(); + Log(LogType::DEBUG) << "Chanstats: Error executing query " << r.finished_query << ": " << r.GetError(); else - Log(LOG_DEBUG) << "Chanstats: Error executing query: " << r.GetError(); + Log(LogType::DEBUG) << "Chanstats: Error executing query: " << r.GetError(); } }; @@ -98,10 +98,10 @@ class CSTop : public Module } - void OnReload(Configuration::Conf *conf) anope_override + void OnReload(Configuration::Conf *conf) override { - prefix = conf->GetModule("m_chanstats")->Get<const Anope::string>("prefix", "anope_"); - this->sql = ServiceReference<SQL::Provider>("SQL::Provider", conf->GetModule("m_chanstats")->Get<const Anope::string>("engine")); + prefix = conf->GetModule("chanstats")->Get<Anope::string>("prefix", "anope_"); + this->sql = ServiceReference<SQL::Provider>("SQL::Provider", conf->GetModule("chanstats")->Get<Anope::string>("engine")); } SQL::Result RunQuery(const SQL::Query &query) @@ -122,7 +122,7 @@ class CSTop : public Module if (!params.empty()) channel = params[0]; else if (source.c && source.c->ci) - channel = source.c->ci->name; + channel = source.c->ci->GetName(); if (!is_global && channel.empty()) is_global = true; @@ -151,7 +151,7 @@ class CSTop : public Module { source.Reply(_("%2lu \002%-16s\002 letters: %s, words: %s, lines: %s, smileys: %s, actions: %s"), i+1, res.Get(i, "nick").c_str(), res.Get(i, "letters").c_str(), - res.Get(i, "words").c_str(), res.Get(i, "line").c_str(), + res.Get(i, "words").c_str(), res.Get(i, "line").c_str(), res.Get(i, "smileys").c_str(), res.Get(i, "actions").c_str()); } } @@ -160,7 +160,7 @@ class CSTop : public Module } catch (const SQL::Exception &ex) { - Log(LOG_DEBUG) << ex.GetReason(); + Log(LogType::DEBUG) << ex.GetReason(); } } }; diff --git a/modules/extra/stats/irc2sql/irc2sql.cpp b/modules/extra/stats/irc2sql/irc2sql.cpp index a00181304..e0c03edbd 100644 --- a/modules/extra/stats/irc2sql/irc2sql.cpp +++ b/modules/extra/stats/irc2sql/irc2sql.cpp @@ -11,21 +11,21 @@ void IRC2SQL::OnShutdown() void IRC2SQL::OnReload(Configuration::Conf *conf) { Configuration::Block *block = Config->GetModule(this); - prefix = block->Get<const Anope::string>("prefix", "anope_"); - GeoIPDB = block->Get<const Anope::string>("geoip_database"); + prefix = block->Get<Anope::string>("prefix", "anope_"); + GeoIPDB = block->Get<Anope::string>("geoip_database"); ctcpuser = block->Get<bool>("ctcpuser", "no"); ctcpeob = block->Get<bool>("ctcpeob", "yes"); - Anope::string engine = block->Get<const Anope::string>("engine"); + Anope::string engine = block->Get<Anope::string>("engine"); this->sql = ServiceReference<SQL::Provider>("SQL::Provider", engine); if (sql) this->CheckTables(); else Log() << "IRC2SQL: no database connection to " << engine; - const Anope::string &snick = block->Get<const Anope::string>("client"); + const Anope::string &snick = block->Get<Anope::string>("client"); if (snick.empty()) throw ConfigException(Module::name + ": <client> must be defined"); - StatServ = BotInfo::Find(snick, true); + StatServ = ServiceBot::Find(snick, true); if (!StatServ) throw ConfigException(Module::name + ": no bot named " + snick); @@ -99,7 +99,7 @@ void IRC2SQL::OnUserConnect(User *u, bool &exempt) query.SetValue("ident", u->GetIdent()); query.SetValue("vident", u->GetVIdent()); query.SetValue("secure", u->HasMode("SSL") || u->HasExt("ssl") ? "Y" : "N"); - query.SetValue("account", u->Account() ? u->Account()->display : ""); + query.SetValue("account", u->Account() ? u->Account()->GetDisplay() : ""); query.SetValue("fingerprint", u->fingerprint); query.SetValue("signon", u->signon); query.SetValue("server", u->server->GetName()); @@ -167,7 +167,7 @@ void IRC2SQL::OnUserLogin(User *u) { query = "UPDATE `" + prefix + "user` SET account=@account@ WHERE nick=@nick@"; query.SetValue("nick", u->nick); - query.SetValue("account", u->Account() ? u->Account()->display : ""); + query.SetValue("account", u->Account() ? u->Account()->GetDisplay() : ""); this->RunQuery(query); } @@ -221,7 +221,7 @@ void IRC2SQL::OnJoinChannel(User *u, Channel *c) this->RunQuery(query); } -EventReturn IRC2SQL::OnChannelModeSet(Channel *c, MessageSource &setter, ChannelMode *mode, const Anope::string ¶m) +EventReturn IRC2SQL::OnChannelModeSet(Channel *c, const MessageSource &setter, ChannelMode *mode, const Anope::string ¶m) { query = "UPDATE `" + prefix + "chan` SET modes=@modes@ WHERE channel=@channel@"; query.SetValue("channel", c->name); @@ -230,7 +230,7 @@ EventReturn IRC2SQL::OnChannelModeSet(Channel *c, MessageSource &setter, Channel return EVENT_CONTINUE; } -EventReturn IRC2SQL::OnChannelModeUnset(Channel *c, MessageSource &setter, ChannelMode *mode, const Anope::string ¶m) +EventReturn IRC2SQL::OnChannelModeUnset(Channel *c, const MessageSource &setter, ChannelMode *mode, const Anope::string ¶m) { this->OnChannelModeSet(c, setter, mode, param); return EVENT_CONTINUE; @@ -264,7 +264,7 @@ void IRC2SQL::OnTopicUpdated(User *source, Channel *c, const Anope::string &user this->RunQuery(query); } -void IRC2SQL::OnBotNotice(User *u, BotInfo *bi, Anope::string &message) +void IRC2SQL::OnBotNotice(User *u, ServiceBot *bi, Anope::string &message) { Anope::string versionstr; if (bi != StatServ) diff --git a/modules/extra/stats/irc2sql/irc2sql.h b/modules/extra/stats/irc2sql/irc2sql.h index a7396fcf0..b73e95cf1 100644 --- a/modules/extra/stats/irc2sql/irc2sql.h +++ b/modules/extra/stats/irc2sql/irc2sql.h @@ -6,11 +6,11 @@ class MySQLInterface : public SQL::Interface public: MySQLInterface(Module *o) : SQL::Interface(o) { } - void OnResult(const SQL::Result &r) anope_override + void OnResult(const SQL::Result &r) override { } - void OnError(const SQL::Result &r) anope_override + void OnError(const SQL::Result &r) override { if (!r.GetQuery().query.empty()) Log(LOG_DEBUG) << "m_irc2sql: Error executing query " << r.finished_query << ": " << r.GetError(); @@ -27,7 +27,7 @@ class IRC2SQL : public Module std::vector<Anope::string> TableList, ProcedureList, EventList; Anope::string prefix, GeoIPDB; bool quitting, introduced_myself, ctcpuser, ctcpeob, firstrun; - BotInfo *StatServ; + ServiceBot *StatServ; PrimitiveExtensibleItem<bool> versionreply; void RunQuery(const SQL::Query &q); @@ -48,31 +48,31 @@ class IRC2SQL : public Module introduced_myself = false; } - void OnShutdown() anope_override; - void OnReload(Configuration::Conf *config) anope_override; - void OnNewServer(Server *server) anope_override; - void OnServerQuit(Server *server) anope_override; - void OnUserConnect(User *u, bool &exempt) anope_override; - void OnUserQuit(User *u, const Anope::string &msg) anope_override; - void OnUserNickChange(User *u, const Anope::string &oldnick) anope_override; - void OnUserAway(User *u, const Anope::string &message) anope_override; - void OnFingerprint(User *u) anope_override; - void OnUserModeSet(const MessageSource &setter, User *u, const Anope::string &mname) anope_override; - void OnUserModeUnset(const MessageSource &setter, User *u, const Anope::string &mname) anope_override; - void OnUserLogin(User *u) anope_override; - void OnNickLogout(User *u) anope_override; - void OnSetDisplayedHost(User *u) anope_override; + void OnShutdown() override; + void OnReload(Configuration::Conf *config) override; + void OnNewServer(Server *server) override; + void OnServerQuit(Server *server) override; + void OnUserConnect(User *u, bool &exempt) override; + void OnUserQuit(User *u, const Anope::string &msg) override; + void OnUserNickChange(User *u, const Anope::string &oldnick) override; + void OnUserAway(User *u, const Anope::string &message) override; + void OnFingerprint(User *u) override; + void OnUserModeSet(const MessageSource &setter, User *u, const Anope::string &mname) override; + void OnUserModeUnset(const MessageSource &setter, User *u, const Anope::string &mname) override; + void OnUserLogin(User *u) override; + void OnNickLogout(User *u) override; + void OnSetDisplayedHost(User *u) override; - void OnChannelCreate(Channel *c) anope_override; - void OnChannelDelete(Channel *c) anope_override; - void OnLeaveChannel(User *u, Channel *c) anope_override; - void OnJoinChannel(User *u, Channel *c) anope_override; - EventReturn OnChannelModeSet(Channel *c, MessageSource &setter, ChannelMode *mode, const Anope::string ¶m) anope_override; - EventReturn OnChannelModeUnset(Channel *c, MessageSource &setter, ChannelMode *mode, const Anope::string ¶m) anope_override; + void OnChannelCreate(Channel *c) override; + void OnChannelDelete(Channel *c) override; + void OnLeaveChannel(User *u, Channel *c) override; + void OnJoinChannel(User *u, Channel *c) override; + EventReturn OnChannelModeSet(Channel *c, const MessageSource &setter, ChannelMode *mode, const Anope::string ¶m) override; + EventReturn OnChannelModeUnset(Channel *c, const MessageSource &setter, ChannelMode *mode, const Anope::string ¶m) override; - void OnTopicUpdated(User *source, Channel *c, const Anope::string &user, const Anope::string &topic) anope_override; + void OnTopicUpdated(User *source, Channel *c, const Anope::string &user, const Anope::string &topic) override; - void OnBotNotice(User *u, BotInfo *bi, Anope::string &message) anope_override; + void OnBotNotice(User *u, ServiceBot *bi, Anope::string &message) override; }; |