aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorGravatar Sadie Powell2024-05-16 12:29:32 +0100
committerGravatar Sadie Powell2024-05-16 12:29:32 +0100
commitc3cff63dca560d0edacc05de37b4495c930d2187 (patch)
treee17396c0482ed46063f98953777265072fb23278 /src
parentDon't allow users to opt-in to older versions of Argon2. (diff)
Make passwords for oper accounts optional.
This allows restricting an oper account based on other data such as TLS fingerprint or services account but without logging them in automatically like autologin.
Diffstat (limited to 'src')
-rw-r--r--src/configreader.cpp9
-rw-r--r--src/coremods/core_oper/cmd_oper.cpp7
-rw-r--r--src/users.cpp10
3 files changed, 17 insertions, 9 deletions
diff --git a/src/configreader.cpp b/src/configreader.cpp
index 1ff31d42f..84bc58853 100644
--- a/src/configreader.cpp
+++ b/src/configreader.cpp
@@ -176,15 +176,18 @@ void ServerConfig::CrossCheckOperBlocks()
for (const auto& [_, tag] : ConfTags("oper"))
{
- const std::string name = tag->getString("name");
+ const auto name = tag->getString("name");
if (name.empty())
throw CoreException("<oper:name> missing from tag at " + tag->source.str());
- const std::string typestr = tag->getString("type");
+ const auto typestr = tag->getString("type");
if (typestr.empty())
throw CoreException("<oper:type> missing from tag at " + tag->source.str());
- auto type = OperTypes.find(typestr);
+ if (tag->getString("password").empty() && !tag->getBool("nopassword"))
+ throw CoreException("<oper:password> missing from tag at " + tag->source.str());
+
+ const auto type = OperTypes.find(typestr);
if (type == OperTypes.end())
throw CoreException("Oper block " + name + " has missing type " + typestr + " at " + tag->source.str());
diff --git a/src/coremods/core_oper/cmd_oper.cpp b/src/coremods/core_oper/cmd_oper.cpp
index d00fed6b1..e3ce7fd51 100644
--- a/src/coremods/core_oper/cmd_oper.cpp
+++ b/src/coremods/core_oper/cmd_oper.cpp
@@ -38,9 +38,9 @@ namespace
}
CommandOper::CommandOper(Module* parent)
- : SplitCommand(parent, "OPER", 2, 2)
+ : SplitCommand(parent, "OPER", 1, 2)
{
- syntax = { "<username> <password>" };
+ syntax = { "<username> [<password>]" };
}
CmdResult CommandOper::HandleLocal(LocalUser* user, const Params& parameters)
@@ -56,7 +56,8 @@ CmdResult CommandOper::HandleLocal(LocalUser* user, const Params& parameters)
// Check whether the password is correct.
auto account = it->second;
- if (!account->CheckPassword(parameters[1]))
+ const auto& password = parameters.size() > 1 ? parameters[1] : "";
+ if (!account->CheckPassword(password))
{
ServerInstance->SNO.WriteGlobalSno('o', "{} ({}) [{}] failed to log into the \x02{}\x02 oper account because they specified the wrong password.",
user->nick, user->GetRealUserHost(), user->GetAddress(), parameters[0]);
diff --git a/src/users.cpp b/src/users.cpp
index 8a67ddf13..e8a2b7a42 100644
--- a/src/users.cpp
+++ b/src/users.cpp
@@ -1294,8 +1294,9 @@ void OperType::MergeTag(const std::shared_ptr<ConfigTag>& tag)
OperAccount::OperAccount(const std::string& n, const std::shared_ptr<OperType>& o, const std::shared_ptr<ConfigTag>& t)
: OperType(n, nullptr)
- , password(t->getString("password"))
- , passwordhash(t->getString("hash", "plaintext", 1))
+ , nopassword(t->getBool("nopassword"))
+ , password(nopassword ? "" : t->getString("password"))
+ , passwordhash(nopassword ? "" : t->getString("hash", "plaintext", 1))
, type(o ? o->GetName() : n)
{
autologin = t->getEnum("autologin", AutoLogin::NEVER, {
@@ -1336,5 +1337,8 @@ bool OperAccount::CanAutoLogin(LocalUser* user) const
bool OperAccount::CheckPassword(const std::string& pw) const
{
- return InspIRCd::CheckPassword(password, passwordhash, pw);
+ if (nopassword)
+ return true; // <oper nopassword="yes">
+
+ return !password.empty() && InspIRCd::CheckPassword(password, passwordhash, pw);
}