diff options
| author | 2022-12-11 08:37:25 +0000 | |
|---|---|---|
| committer | 2022-12-11 08:49:44 +0000 | |
| commit | cd6329d4b08bcfc9853948fc89310013b112dd53 (patch) | |
| tree | 70ae5692bee40c022a36d0952adafbd6fd8302a4 /src | |
| parent | Update 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.cpp | 54 | ||||
| -rw-r--r-- | src/coremods/core_oper/core_oper.cpp | 2 | ||||
| -rw-r--r-- | src/modules/m_account.cpp | 2 | ||||
| -rw-r--r-- | src/modules/m_sslinfo.cpp | 8 |
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; } |
