From 452e62c05021b29b4f0641245cafa6ae115e2198 Mon Sep 17 00:00:00 2001 From: Sadie Powell Date: Fri, 11 Apr 2025 12:05:18 +0100 Subject: Add support for local password comparison in sql_authentication. --- modules/sql_authentication.cpp | 43 ++++++++++++++++++++++++++++++++++++++---- 1 file changed, 39 insertions(+), 4 deletions(-) (limited to 'modules') 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; + Anope::string password_hash, password_field; +} class SQLAuthenticationResult final : public SQL::Interface { Reference 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("disable_email_reason"); this->SQL = ServiceReference("SQL::Provider", this->engine); + + password_hash = config.Get("password_hash"); + if (!password_hash.empty()) + { + password_field = config.Get("password_field", "password"); + encryption = ServiceReference("Encryption::Provider", password_hash); + } } EventReturn OnPreCommand(CommandSource &source, Command *command, std::vector ¶ms) override -- cgit