mgmt: don't crash if no authorizations are configured
Change-Id: I02d439a73c9b02fcb7141104d62a67aa1fa5aefb
Refs: #4487
diff --git a/daemon/mgmt/command-authenticator.cpp b/daemon/mgmt/command-authenticator.cpp
index 30ee829..6f85fc7 100644
--- a/daemon/mgmt/command-authenticator.cpp
+++ b/daemon/mgmt/command-authenticator.cpp
@@ -1,6 +1,6 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/**
- * Copyright (c) 2014-2017, Regents of the University of California,
+/*
+ * Copyright (c) 2014-2018, Regents of the University of California,
* Arizona Board of Regents,
* Colorado State University,
* University Pierre & Marie Curie, Sorbonne University,
@@ -210,42 +210,46 @@
m_validators[module]; // declares module, so that privilege is recognized
auto self = this->shared_from_this();
- return [=] (const Name& prefix, const Interest& interest,
- const ndn::mgmt::ControlParameters* params,
+ return [=] (const Name&, const Interest& interest,
+ const ndn::mgmt::ControlParameters*,
const ndn::mgmt::AcceptContinuation& accept,
const ndn::mgmt::RejectContinuation& reject) {
- shared_ptr<sec2::Validator> validator = self->m_validators.at(module);
- validator->validate(interest,
- [accept, validator] (const Interest& interest1) {
- auto signer1 = getSignerFromTag(interest1);
- BOOST_ASSERT(signer1 || // signer must be available unless 'certfile any'
- dynamic_cast<sec2::ValidationPolicyAcceptAll*>(&validator->getPolicy()) != nullptr);
- std::string signer = signer1.value_or("*");
- NFD_LOG_DEBUG("accept " << interest1.getName() << " signer=" << signer);
- accept(signer);
- },
- [reject] (const Interest& interest1, const sec2::ValidationError& err) {
- NFD_LOG_DEBUG("reject " << interest1.getName() << " signer=" <<
- getSignerFromTag(interest1).value_or("?") << ' ' << err);
-
- using ndn::mgmt::RejectReply;
- RejectReply reply = RejectReply::STATUS403;
- using ErrCode = sec2::ValidationError::Code;
- switch (err.getCode()) {
- case ErrCode::NO_SIGNATURE:
- case ErrCode::INVALID_KEY_LOCATOR:
- reply = RejectReply::SILENT;
- break;
- case ErrCode::POLICY_ERROR:
- if (interest1.getName().size() < ndn::command_interest::MIN_SIZE) { // "name too short"
- reply = RejectReply::SILENT;
- }
- break;
- default:
- break;
+ auto validator = self->m_validators.at(module);
+ auto successCb = [accept, validator] (const Interest& interest1) {
+ auto signer1 = getSignerFromTag(interest1);
+ BOOST_ASSERT(signer1 || // signer must be available unless 'certfile any'
+ dynamic_cast<sec2::ValidationPolicyAcceptAll*>(&validator->getPolicy()) != nullptr);
+ std::string signer = signer1.value_or("*");
+ NFD_LOG_DEBUG("accept " << interest1.getName() << " signer=" << signer);
+ accept(signer);
+ };
+ auto failureCb = [reject] (const Interest& interest1, const sec2::ValidationError& err) {
+ using ndn::mgmt::RejectReply;
+ RejectReply reply = RejectReply::STATUS403;
+ switch (err.getCode()) {
+ case sec2::ValidationError::NO_SIGNATURE:
+ case sec2::ValidationError::INVALID_KEY_LOCATOR:
+ reply = RejectReply::SILENT;
+ break;
+ case sec2::ValidationError::POLICY_ERROR:
+ if (interest1.getName().size() < ndn::command_interest::MIN_SIZE) { // "name too short"
+ reply = RejectReply::SILENT;
}
- reject(reply);
- });
+ break;
+ }
+ NFD_LOG_DEBUG("reject " << interest1.getName() << " signer=" <<
+ getSignerFromTag(interest1).value_or("?") << " reason=" << err);
+ reject(reply);
+ };
+
+ if (validator) {
+ validator->validate(interest, successCb, failureCb);
+ }
+ else {
+ NFD_LOG_DEBUG("reject " << interest.getName() << " signer=" <<
+ getSignerFromTag(interest).value_or("?") << " reason=Unauthorized");
+ reject(ndn::mgmt::RejectReply::STATUS403);
+ }
};
}
diff --git a/tests/daemon/mgmt/command-authenticator.t.cpp b/tests/daemon/mgmt/command-authenticator.t.cpp
index 469c333..ce4ab53 100644
--- a/tests/daemon/mgmt/command-authenticator.t.cpp
+++ b/tests/daemon/mgmt/command-authenticator.t.cpp
@@ -1,6 +1,6 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
- * Copyright (c) 2014-2017, Regents of the University of California,
+ * Copyright (c) 2014-2018, Regents of the University of California,
* Arizona Board of Regents,
* Colorado State University,
* University Pierre & Marie Curie, Sorbonne University,
@@ -52,8 +52,7 @@
void
loadConfig(const std::string& config)
{
- boost::filesystem::path configPath = boost::filesystem::current_path() /=
- "command-authenticator-test.conf";
+ auto configPath = boost::filesystem::current_path() / "command-authenticator-test.conf";
ConfigFile cf;
authenticator->setConfigFile(cf);
cf.parse(config, false, configPath.c_str());
@@ -64,7 +63,7 @@
const function<void(Interest&)>& modifyInterest = nullptr)
{
Interest interest = this->makeControlCommandRequest(Name("/prefix/" + module + "/verb"),
- ControlParameters(), identity);
+ ControlParameters(), identity);
if (modifyInterest != nullptr) {
modifyInterest(interest);
}
@@ -87,7 +86,7 @@
lastRejectReply = act;
});
- this->advanceClocks(time::milliseconds(1), 10);
+ this->advanceClocks(1_ms, 10);
BOOST_REQUIRE_MESSAGE(isAccepted || isRejected,
"authorization function should invoke one continuation");
return isAccepted;
@@ -356,6 +355,18 @@
BOOST_CHECK(lastRejectReply == ndn::mgmt::RejectReply::STATUS403);
}
+BOOST_FIXTURE_TEST_CASE(MissingAuthorizationsSection, CommandAuthenticatorFixture)
+{
+ Name id0("/localhost/CommandAuthenticator/0");
+ BOOST_REQUIRE(addIdentity(id0));
+
+ makeModules({"module42"});
+ loadConfig("");
+
+ BOOST_CHECK_EQUAL(authorize("module42", id0), false);
+ BOOST_CHECK(lastRejectReply == ndn::mgmt::RejectReply::STATUS403);
+}
+
BOOST_AUTO_TEST_SUITE_END() // Rejects
BOOST_AUTO_TEST_SUITE(BadConfig)