diff options
author | Sadie Powell <sadie@witchery.services> | 2025-04-11 12:05:18 +0100 |
---|---|---|
committer | Sadie Powell <sadie@witchery.services> | 2025-04-19 12:38:32 +0100 |
commit | 452e62c05021b29b4f0641245cafa6ae115e2198 (patch) | |
tree | e5bf110189f06b7c7afaa8e58ed3b2b03e5220be /modules | |
parent | 4916e1dbfcbea01830d16b27ec90930c875bc335 (diff) |
Add support for local password comparison in sql_authentication.
Diffstat (limited to 'modules')
-rw-r--r-- | modules/sql_authentication.cpp | 43 |
1 files changed, 39 insertions, 4 deletions
diff --git a/modules/sql_authentication.cpp b/modules/sql_authentication.cpp index a524a43fc..9c3605ed9 100644 --- a/modules/sql_authentication.cpp +++ b/modules/sql_authentication.cpp @@ -7,16 +7,29 @@ */ #include "module.h" +#include "modules/encryption.h" #include "modules/sql.h" -static Module *me; +namespace +{ + Module *me; + ServiceReference<Encryption::Provider> encryption; + Anope::string password_hash, password_field; +} class SQLAuthenticationResult final : public SQL::Interface { Reference<User> user; IdentifyRequest *req; + void OnFail(const Anope::string &reason) + { + Log(LOG_DEBUG) << "sql_authentication: Unsuccessful authentication for " << req->GetAccount() << ": " << reason; + delete this; + return; + } + public: SQLAuthenticationResult(User *u, IdentifyRequest *r) : SQL::Interface(me), user(u), req(r) { @@ -31,10 +44,25 @@ public: void OnResult(const SQL::Result &r) override { if (r.Rows() == 0) + return OnFail("no rows"); + + if (!password_hash.empty()) { - Log(LOG_DEBUG) << "sql_authentication: Unsuccessful authentication for " << req->GetAccount(); - delete this; - return; + if (!encryption) + return OnFail("encryption provider not loaded"); + + auto success = false; + for (auto i = 0; i < r.Rows(); ++i) + { + if (encryption->Compare(r.Get(i, password_field), req->GetPassword())) + { + success = true; + break; + } + } + + if (!success) + return OnFail("no matching passwords"); } Log(LOG_DEBUG) << "sql_authentication: Successful authentication for " << req->GetAccount(); @@ -99,6 +127,13 @@ public: this->disable_email_reason = config.Get<Anope::string>("disable_email_reason"); this->SQL = ServiceReference<SQL::Provider>("SQL::Provider", this->engine); + + password_hash = config.Get<const Anope::string>("password_hash"); + if (!password_hash.empty()) + { + password_field = config.Get<const Anope::string>("password_field", "password"); + encryption = ServiceReference<Encryption::Provider>("Encryption::Provider", password_hash); + } } EventReturn OnPreCommand(CommandSource &source, Command *command, std::vector<Anope::string> ¶ms) override |