X-Git-Url: https://git.netwichtig.de/gitweb/?a=blobdiff_plain;ds=inline;f=src%2Fmodules%2Fextra%2Fm_sqloper.cpp;h=f3c32b14047af9057ffb1011eed245272053099c;hb=12427e75fe175fe7a62f388281dd7ab5100c9dda;hp=c9149322c2396330f1b46be7f08d2a737a09df8b;hpb=2ab88037d8d7d6df3fb9686216a0b36f5ece2313;p=user%2Fhenk%2Fcode%2Finspircd.git diff --git a/src/modules/extra/m_sqloper.cpp b/src/modules/extra/m_sqloper.cpp index c9149322c..f3c32b140 100644 --- a/src/modules/extra/m_sqloper.cpp +++ b/src/modules/extra/m_sqloper.cpp @@ -2,11 +2,11 @@ * | Inspire Internet Relay Chat Daemon | * +------------------------------------+ * - * InspIRCd: (C) 2002-2007 InspIRCd Development Team + * InspIRCd: (C) 2002-2008 InspIRCd Development Team * See: http://www.inspircd.org/wiki/index.php/Credits * * This program is free but copyrighted software; see - * the file COPYING for details. + * the file COPYING for details. * * --------------------------------------------------- */ @@ -23,14 +23,18 @@ #include "commands/cmd_oper.h" /* $ModDesc: Allows storage of oper credentials in an SQL table */ -/* $ModDep: m_sqlv2.h m_sqlutils.h */ -/* $CompileFlags: -Wno-variadic-macros */ +/* $ModDep: m_sqlv2.h m_sqlutils.h m_hash.h */ + +typedef std::map hashymodules; class ModuleSQLOper : public Module { Module* SQLutils; - Module* HashModule; std::string databaseid; + irc::string hashtype; + hashymodules hashers; + bool diduseiface; + std::deque names; public: ModuleSQLOper(InspIRCd* Me) @@ -40,38 +44,74 @@ public: ServerInstance->Modules->UseInterface("SQL"); ServerInstance->Modules->UseInterface("HashRequest"); - /* Attempt to locate the md5 service provider, bail if we can't find it */ - HashModule = ServerInstance->Modules->Find("m_md5.so"); - if (!HashModule) - throw ModuleException("Can't find m_md5.so. Please load m_md5.so before m_sqloper.so."); + OnRehash(NULL, ""); + + diduseiface = false; + + /* Find all modules which implement the interface 'HashRequest' */ + modulelist* ml = ServerInstance->Modules->FindInterface("HashRequest"); + + /* Did we find any modules? */ + if (ml) + { + /* Yes, enumerate them all to find out the hashing algorithm name */ + for (modulelist::iterator m = ml->begin(); m != ml->end(); m++) + { + /* Make a request to it for its name, its implementing + * HashRequest so we know its safe to do this + */ + std::string name = HashNameRequest(this, *m).Send(); + /* Build a map of them */ + hashers[name.c_str()] = *m; + names.push_back(name); + } + /* UseInterface doesn't do anything if there are no providers, so we'll have to call it later if a module gets loaded later on. */ + diduseiface = true; + ServerInstance->Modules->UseInterface("HashRequest"); + } SQLutils = ServerInstance->Modules->Find("m_sqlutils.so"); if (!SQLutils) throw ModuleException("Can't find m_sqlutils.so. Please load m_sqlutils.so before m_sqloper.so."); - OnRehash(NULL,""); + Implementation eventlist[] = { I_OnRequest, I_OnRehash, I_OnPreCommand, I_OnLoadModule }; + ServerInstance->Modules->Attach(eventlist, this, 3); + } + + virtual void OnLoadModule(Module* mod, const std::string& name) + { + if (ServerInstance->Modules->ModuleHasInterface(mod, "HashRequest")) + { + ServerInstance->Logs->Log("m_sqloper",DEBUG, "Post-load registering hasher: %s", name.c_str()); + std::string sname = HashNameRequest(this, mod).Send(); + hashers[sname.c_str()] = mod; + names.push_back(sname); + if (!diduseiface) + { + ServerInstance->Modules->UseInterface("HashRequest"); + diduseiface = true; + } + } } virtual ~ModuleSQLOper() { ServerInstance->Modules->DoneWithInterface("SQL"); ServerInstance->Modules->DoneWithInterface("SQLutils"); - ServerInstance->Modules->DoneWithInterface("HashRequest"); + if (diduseiface) + ServerInstance->Modules->DoneWithInterface("HashRequest"); } - void Implements(char* List) - { - List[I_OnRequest] = List[I_OnRehash] = List[I_OnPreCommand] = 1; - } virtual void OnRehash(User* user, const std::string ¶meter) { ConfigReader Conf(ServerInstance); databaseid = Conf.ReadValue("sqloper", "dbid", 0); /* Database ID of a database configured for the service provider module */ + hashtype = assign(Conf.ReadValue("sqloper", "hash", 0)); } - virtual int OnPreCommand(const std::string &command, const char** parameters, int pcnt, User *user, bool validated, const std::string &original_line) + virtual int OnPreCommand(const std::string &command, const std::vector ¶meters, User *user, bool validated, const std::string &original_line) { if ((validated) && (command == "OPER")) { @@ -96,16 +136,20 @@ public: if (target) { + hashymodules::iterator x = hashers.find(hashtype); + if (x == hashers.end()) + return false; + /* Reset hash module first back to MD5 standard state */ - HashResetRequest(this, HashModule).Send(); + HashResetRequest(this, x->second).Send(); /* Make an MD5 hash of the password for using in the query */ - std::string md5_pass_hash = HashSumRequest(this, HashModule, password.c_str()).Send(); + std::string md5_pass_hash = HashSumRequest(this, x->second, password.c_str()).Send(); - /* We generate our own MD5 sum here because some database providers (e.g. SQLite) dont have a builtin md5 function, + /* We generate our own sum here because some database providers (e.g. SQLite) dont have a builtin md5/sha256 function, * also hashing it in the module and only passing a remote query containing a hash is more secure. */ - - SQLrequest req = SQLreq(this, target, databaseid, "SELECT username, password, hostname, type FROM ircd_opers WHERE username = '?' AND password='?'", username, md5_pass_hash); + SQLrequest req = SQLrequest(this, target, databaseid, + SQLquery("SELECT username, password, hostname, type FROM ircd_opers WHERE username = '?' AND password='?'") % username % md5_pass_hash); if (req.Send()) { @@ -130,12 +174,12 @@ public: } else { - ServerInstance->Log(SPARSE, "WARNING: Couldn't find SQL provider module. NOBODY will be able to oper up unless their o:line is statically configured"); + ServerInstance->Logs->Log("m_sqloper",SPARSE, "WARNING: Couldn't find SQL provider module. NOBODY will be able to oper up unless their o:line is statically configured"); return false; } } - virtual char* OnRequest(Request* request) + virtual const char* OnRequest(Request* request) { if (strcmp(SQLRESID, request->GetId()) == 0) { @@ -232,12 +276,14 @@ public: if (oper_command) { - const char* params[] = { username.c_str(), pass.c_str() }; - oper_command->Handle(params, 2, user); + std::vector params; + params.push_back(username); + params.push_back(pass); + oper_command->Handle(params, user); } else { - ServerInstance->Log(DEBUG, "BUG: WHAT?! Why do we have no OPER command?!"); + ServerInstance->Logs->Log("m_sqloper",DEBUG, "BUG: WHAT?! Why do we have no OPER command?!"); } } @@ -260,11 +306,11 @@ public: if (operhost.size()) user->ChangeDisplayedHost(operhost.c_str()); - ServerInstance->SNO->WriteToSnoMask('o',"%s (%s@%s) is now an IRC operator of type %s", user->nick, user->ident, user->host, type.c_str()); - user->WriteServ("381 %s :You are now %s %s",user->nick, strchr("aeiouAEIOU", type[0]) ? "an" : "a", irc::Spacify(type.c_str())); + ServerInstance->SNO->WriteToSnoMask('o',"%s (%s@%s) is now an IRC operator of type %s", user->nick.c_str(), user->ident.c_str(), user->host.c_str(), type.c_str()); + user->WriteNumeric(381, "%s :You are now %s %s",user->nick.c_str(), strchr("aeiouAEIOU", type[0]) ? "an" : "a", irc::Spacify(type.c_str())); if (!user->modes[UM_OPERATOR]) - user->Oper(type); + user->Oper(type, tname); return true; } @@ -275,7 +321,7 @@ public: virtual Version GetVersion() { - return Version(1,1,1,0,VF_VENDOR,API_VERSION); + return Version(1,2,1,0,VF_VENDOR,API_VERSION); } };