aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorGravatar Sadie Powell2022-12-11 08:37:25 +0000
committerGravatar Sadie Powell2022-12-11 08:49:44 +0000
commitcd6329d4b08bcfc9853948fc89310013b112dd53 (patch)
tree70ae5692bee40c022a36d0952adafbd6fd8302a4 /src
parentUpdate some references to services_account that were missed. (diff)
Improve the oper login flow and error messages.
Diffstat (limited to 'src')
-rw-r--r--src/coremods/core_oper/cmd_oper.cpp54
-rw-r--r--src/coremods/core_oper/core_oper.cpp2
-rw-r--r--src/modules/m_account.cpp2
-rw-r--r--src/modules/m_sslinfo.cpp8
4 files changed, 42 insertions, 24 deletions
diff --git a/src/coremods/core_oper/cmd_oper.cpp b/src/coremods/core_oper/cmd_oper.cpp
index 770d12bf3..3ed4a1e03 100644
--- a/src/coremods/core_oper/cmd_oper.cpp
+++ b/src/coremods/core_oper/cmd_oper.cpp
@@ -28,6 +28,17 @@
#include "inspircd.h"
#include "core_oper.h"
+namespace
+{
+ CmdResult FailedOper(LocalUser* user, const std::string& name)
+ {
+ user->WriteNumeric(ERR_NOOPERHOST, InspIRCd::Format("Failed to log into the \x02%s\x02 oper account (check the server log for details).",
+ name.c_str()));
+ user->CommandFloodPenalty += 10'000;
+ return CmdResult::FAILURE;
+ }
+}
+
CommandOper::CommandOper(Module* parent)
: SplitCommand(parent, "OPER", 2, 2)
{
@@ -36,33 +47,28 @@ CommandOper::CommandOper(Module* parent)
CmdResult CommandOper::HandleLocal(LocalUser* user, const Params& parameters)
{
- bool match_user = false;
- bool match_pass = false;
-
- auto i = ServerInstance->Config->OperAccounts.find(parameters[0]);
- if (i != ServerInstance->Config->OperAccounts.end())
+ // Check whether the account exists.
+ auto it = ServerInstance->Config->OperAccounts.find(parameters[0]);
+ if (it == ServerInstance->Config->OperAccounts.end())
{
- std::shared_ptr<OperAccount> ifo = i->second;
- match_user = true;
- match_pass = ifo->CheckPassword(parameters[1]);
-
- if (match_pass && user->OperLogin(ifo))
- return CmdResult::SUCCESS;
+ ServerInstance->SNO.WriteGlobalSno('o', "%s (%s) [%s] failed to log into the \x02%s\x02 oper account because no account with that name exists.",
+ user->nick.c_str(), user->MakeHost().c_str(), user->GetIPString().c_str(), parameters[0].c_str());
+ return FailedOper(user, parameters[0]);
}
- std::string fields;
- if (!match_user)
- fields.append("username ");
- if (!match_pass)
- fields.append("password ");
- if (fields.empty())
- fields.append("module ");
- fields.erase(fields.length() - 1, 1);
+ // Check whether the password is correct.
+ auto account = it->second;
+ if (!account->CheckPassword(parameters[1]))
+ {
+ ServerInstance->SNO.WriteGlobalSno('o', "%s (%s) [%s] failed to log into the \x02%s\x02 oper account because they specified the wrong password.",
+ user->nick.c_str(), user->MakeHost().c_str(), user->GetIPString().c_str(), parameters[0].c_str());
+ return FailedOper(user, parameters[0]);
+ }
- // Tell them they failed (generically) and lag them up to help prevent brute-force attacks
- user->WriteNumeric(ERR_NOOPERHOST, "Invalid oper credentials");
- user->CommandFloodPenalty += 10000;
+ // Attempt to log the user into the account (modules will log if this fails).
+ if (!user->OperLogin(account))
+ return FailedOper(user, parameters[0]);
- ServerInstance->SNO.WriteGlobalSno('o', "WARNING! Failed oper attempt by %s using login '%s': The following fields do not match: %s", user->GetFullRealHost().c_str(), parameters[0].c_str(), fields.c_str());
- return CmdResult::FAILURE;
+ // If they have reached this point then the login succeeded,
+ return CmdResult::SUCCESS;
}
diff --git a/src/coremods/core_oper/core_oper.cpp b/src/coremods/core_oper/core_oper.cpp
index a43eb1034..9c52e286b 100644
--- a/src/coremods/core_oper/core_oper.cpp
+++ b/src/coremods/core_oper/core_oper.cpp
@@ -69,6 +69,8 @@ public:
if (InspIRCd::MatchMask(hosts, user->MakeHost(), user->MakeHostIP()))
return MOD_RES_PASSTHRU; // Host matches.
+ ServerInstance->SNO.WriteGlobalSno('o', "%s (%s) [%s] failed to log into the \x02%s\x02 oper account because they are connecting from the wrong user@host.",
+ user->nick.c_str(), user->MakeHost().c_str(), user->GetIPString().c_str(), oper->GetName().c_str());
return MOD_RES_DENY; // Host does not match.
}
diff --git a/src/modules/m_account.cpp b/src/modules/m_account.cpp
index 3c446dffc..d9251f04f 100644
--- a/src/modules/m_account.cpp
+++ b/src/modules/m_account.cpp
@@ -357,6 +357,8 @@ public:
return MOD_RES_PASSTHRU; // Matches on account name.
}
+ ServerInstance->SNO.WriteGlobalSno('o', "%s (%s) [%s] failed to log into the \x02%s\x02 oper account because they are not logged into the correct user account.",
+ user->nick.c_str(), user->MakeHost().c_str(), user->GetIPString().c_str(), oper->GetName().c_str());
return MOD_RES_DENY; // Account required but it does not match.
}
diff --git a/src/modules/m_sslinfo.cpp b/src/modules/m_sslinfo.cpp
index 2f3d4d0c8..d89f74006 100644
--- a/src/modules/m_sslinfo.cpp
+++ b/src/modules/m_sslinfo.cpp
@@ -327,11 +327,19 @@ public:
{
auto cert = cmd.sslapi.GetCertificate(user);
if (oper->GetConfig()->getBool("sslonly") && !cert)
+ {
+ ServerInstance->SNO.WriteGlobalSno('o', "%s (%s) [%s] failed to log into the \x02%s\x02 oper account because they are not connected using TLS.",
+ user->nick.c_str(), user->MakeHost().c_str(), user->GetIPString().c_str(), oper->GetName().c_str());
return MOD_RES_DENY;
+ }
const std::string fingerprint = oper->GetConfig()->getString("fingerprint");
if (!fingerprint.empty() && (!cert || !MatchFP(cert, fingerprint)))
+ {
+ ServerInstance->SNO.WriteGlobalSno('o', "%s (%s) [%s] failed to log into the \x02%s\x02 oper account because they are not using the correct TLS client certificate.",
+ user->nick.c_str(), user->MakeHost().c_str(), user->GetIPString().c_str(), oper->GetName().c_str());
return MOD_RES_DENY;
+ }
return MOD_RES_PASSTHRU;
}