X-Git-Url: https://git.netwichtig.de/gitweb/?a=blobdiff_plain;f=src%2Fmodules%2Fm_sqlauth.cpp;h=0ae51a86eaa339d0bcb79e0bd5b5b3ce3a9e2243;hb=e2b0f3dc9ef4d56c71d7abda13e6139ca092e387;hp=1a5b68dd9206ee0f0d1e6a967bca418d4ecfaa6d;hpb=565544fac966b14e046bb3042ab485f79bcf7c9e;p=user%2Fhenk%2Fcode%2Finspircd.git diff --git a/src/modules/m_sqlauth.cpp b/src/modules/m_sqlauth.cpp index 1a5b68dd9..0ae51a86e 100644 --- a/src/modules/m_sqlauth.cpp +++ b/src/modules/m_sqlauth.cpp @@ -1,7 +1,14 @@ /* * InspIRCd -- Internet Relay Chat Daemon * + * Copyright (C) 2015 Daniel Vassdal + * Copyright (C) 2013, 2017-2019 Sadie Powell + * Copyright (C) 2012-2015 Attila Molnar + * Copyright (C) 2012, 2019 Robby * Copyright (C) 2009-2010 Daniel De Graaf + * Copyright (C) 2007-2008 Robin Burchell + * Copyright (C) 2007 Dennis Friis + * Copyright (C) 2005, 2007-2008, 2010 Craig Edwards * * This file is part of InspIRCd. InspIRCd is free software: you can * redistribute it and/or modify it under the terms of the GNU General Public @@ -28,24 +35,69 @@ enum AuthState { AUTH_STATE_FAIL = 2 }; -class AuthQuery : public SQLQuery +class AuthQuery : public SQL::Query { public: const std::string uid; LocalIntExt& pendingExt; bool verbose; - AuthQuery(Module* me, const std::string& u, LocalIntExt& e, bool v) - : SQLQuery(me), uid(u), pendingExt(e), verbose(v) + const std::string& kdf; + const std::string& pwcolumn; + + AuthQuery(Module* me, const std::string& u, LocalIntExt& e, bool v, const std::string& kd, const std::string& pwcol) + : SQL::Query(me) + , uid(u) + , pendingExt(e) + , verbose(v) + , kdf(kd) + , pwcolumn(pwcol) { } - void OnResult(SQLResult& res) CXX11_OVERRIDE + void OnResult(SQL::Result& res) CXX11_OVERRIDE { - User* user = ServerInstance->FindNick(uid); + LocalUser* user = IS_LOCAL(ServerInstance->FindUUID(uid)); if (!user) return; + if (res.Rows()) { + if (!kdf.empty()) + { + HashProvider* hashprov = ServerInstance->Modules->FindDataService("hash/" + kdf); + if (!hashprov) + { + if (verbose) + ServerInstance->SNO->WriteGlobalSno('a', "Forbidden connection from %s (a provider for %s was not loaded)", user->GetFullRealHost().c_str(), kdf.c_str()); + pendingExt.set(user, AUTH_STATE_FAIL); + return; + } + + size_t colindex = 0; + if (!pwcolumn.empty() && !res.HasColumn(pwcolumn, colindex)) + { + if (verbose) + ServerInstance->SNO->WriteGlobalSno('a', "Forbidden connection from %s (the column specified (%s) was not returned)", user->GetFullRealHost().c_str(), pwcolumn.c_str()); + pendingExt.set(user, AUTH_STATE_FAIL); + return; + } + + SQL::Row row; + while (res.GetRow(row)) + { + if (hashprov->Compare(user->password, row[colindex])) + { + pendingExt.set(user, AUTH_STATE_NONE); + return; + } + } + + if (verbose) + ServerInstance->SNO->WriteGlobalSno('a', "Forbidden connection from %s (password from the SQL query did not match the user provided password)", user->GetFullRealHost().c_str()); + pendingExt.set(user, AUTH_STATE_FAIL); + return; + } + pendingExt.set(user, AUTH_STATE_NONE); } else @@ -56,31 +108,36 @@ class AuthQuery : public SQLQuery } } - void OnError(SQLerror& error) CXX11_OVERRIDE + void OnError(SQL::Error& error) CXX11_OVERRIDE { User* user = ServerInstance->FindNick(uid); if (!user) return; pendingExt.set(user, AUTH_STATE_FAIL); if (verbose) - ServerInstance->SNO->WriteGlobalSno('a', "Forbidden connection from %s (SQL query failed: %s)", user->GetFullRealHost().c_str(), error.Str()); + ServerInstance->SNO->WriteGlobalSno('a', "Forbidden connection from %s (SQL query failed: %s)", user->GetFullRealHost().c_str(), error.ToString()); } }; class ModuleSQLAuth : public Module { LocalIntExt pendingExt; - dynamic_reference SQL; + dynamic_reference SQL; + UserCertificateAPI sslapi; std::string freeformquery; std::string killreason; std::string allowpattern; bool verbose; + std::vector hash_algos; + std::string kdf; + std::string pwcolumn; public: ModuleSQLAuth() : pendingExt("sqlauth-wait", ExtensionItem::EXT_USER, this) , SQL(this, "SQL") + , sslapi(this) { } @@ -96,6 +153,14 @@ class ModuleSQLAuth : public Module killreason = conf->getString("killreason"); allowpattern = conf->getString("allowpattern"); verbose = conf->getBool("verbose"); + kdf = conf->getString("kdf"); + pwcolumn = conf->getString("column"); + + hash_algos.clear(); + irc::commasepstream algos(conf->getString("hash", "md5,sha256")); + std::string algo; + while (algos.GetToken(algo)) + hash_algos.push_back(algo); } ModResult OnUserRegister(LocalUser* user) CXX11_OVERRIDE @@ -113,29 +178,26 @@ class ModuleSQLAuth : public Module if (!SQL) { - ServerInstance->SNO->WriteGlobalSno('a', "Forbiding connection from %s (SQL database not present)", user->GetFullRealHost().c_str()); + ServerInstance->SNO->WriteGlobalSno('a', "Forbidden connection from %s (SQL database not present)", user->GetFullRealHost().c_str()); ServerInstance->Users->QuitUser(user, killreason); return MOD_RES_PASSTHRU; } pendingExt.set(user, AUTH_STATE_BUSY); - ParamM userinfo; - SQL->PopulateUserInfo(user, userinfo); + SQL::ParamMap userinfo; + SQL::PopulateUserInfo(user, userinfo); userinfo["pass"] = user->password; + userinfo["certfp"] = sslapi ? sslapi->GetFingerprint(user) : ""; - HashProvider* md5 = ServerInstance->Modules->FindDataService("hash/md5"); - if (md5) - userinfo["md5pass"] = md5->Generate(user->password); - - HashProvider* sha256 = ServerInstance->Modules->FindDataService("hash/sha256"); - if (sha256) - userinfo["sha256pass"] = sha256->Generate(user->password); - - const std::string certfp = SSLClientCert::GetFingerprint(&user->eh); - userinfo["certfp"] = certfp; + for (std::vector::const_iterator it = hash_algos.begin(); it != hash_algos.end(); ++it) + { + HashProvider* hashprov = ServerInstance->Modules->FindDataService("hash/" + *it); + if (hashprov && !hashprov->IsKDF()) + userinfo[*it + "pass"] = hashprov->Generate(user->password); + } - SQL->submit(new AuthQuery(this, user->uuid, pendingExt, verbose), freeformquery, userinfo); + SQL->Submit(new AuthQuery(this, user->uuid, pendingExt, verbose, kdf, pwcolumn), freeformquery, userinfo); return MOD_RES_PASSTHRU; } @@ -157,7 +219,7 @@ class ModuleSQLAuth : public Module Version GetVersion() CXX11_OVERRIDE { - return Version("Allow/Deny connections based upon an arbitrary SQL table", VF_VENDOR); + return Version("Allows connecting users to be authenticated against an arbitrary SQL table.", VF_VENDOR); } };