summaryrefslogtreecommitdiff
path: root/modules
diff options
context:
space:
mode:
authorSadie Powell <sadie@witchery.services>2025-04-11 12:05:18 +0100
committerSadie Powell <sadie@witchery.services>2025-04-19 12:38:32 +0100
commit452e62c05021b29b4f0641245cafa6ae115e2198 (patch)
treee5bf110189f06b7c7afaa8e58ed3b2b03e5220be /modules
parent4916e1dbfcbea01830d16b27ec90930c875bc335 (diff)
Add support for local password comparison in sql_authentication.
Diffstat (limited to 'modules')
-rw-r--r--modules/sql_authentication.cpp43
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> &params) override