mgmt,rib: check command length before accessing verb

refs: #2151

Change-Id: I0e67fd4b4df10d842648797ed42771af7c53a938
diff --git a/daemon/mgmt/face-manager.cpp b/daemon/mgmt/face-manager.cpp
index c88329c..03e2f42 100644
--- a/daemon/mgmt/face-manager.cpp
+++ b/daemon/mgmt/face-manager.cpp
@@ -844,10 +844,18 @@
 {
   const Name& command = request.getName();
   const size_t commandNComps = command.size();
-  const Name::Component& verb = command.get(COMMAND_PREFIX.size());
 
-  UnsignedVerbDispatchTable::const_iterator unsignedVerbProcessor =
-    m_unsignedVerbDispatch.find(verb);
+  if (commandNComps <= COMMAND_PREFIX.size())
+    {
+      // command is too short to have a verb
+      NFD_LOG_DEBUG("command result: malformed");
+      sendResponse(command, 400, "Malformed command");
+      return;
+    }
+
+  const Name::Component& verb = command.at(COMMAND_PREFIX.size());
+
+  const auto unsignedVerbProcessor = m_unsignedVerbDispatch.find(verb);
   if (unsignedVerbProcessor != m_unsignedVerbDispatch.end())
     {
       NFD_LOG_DEBUG("command result: processing verb: " << verb);
diff --git a/daemon/mgmt/fib-manager.cpp b/daemon/mgmt/fib-manager.cpp
index 5c91547..3db26e7 100644
--- a/daemon/mgmt/fib-manager.cpp
+++ b/daemon/mgmt/fib-manager.cpp
@@ -104,9 +104,18 @@
 {
   const Name& command = request.getName();
   const size_t commandNComps = command.size();
-  const Name::Component& verb = command.get(COMMAND_PREFIX.size());
 
-  UnsignedVerbDispatchTable::const_iterator unsignedVerbProcessor = m_unsignedVerbDispatch.find(verb);
+  if (commandNComps <= COMMAND_PREFIX.size())
+    {
+      // command is too short to have a verb
+      NFD_LOG_DEBUG("command result: malformed");
+      sendResponse(command, 400, "Malformed command");
+      return;
+    }
+
+  const Name::Component& verb = command.at(COMMAND_PREFIX.size());
+
+  const auto unsignedVerbProcessor = m_unsignedVerbDispatch.find(verb);
   if (unsignedVerbProcessor != m_unsignedVerbDispatch.end())
     {
       NFD_LOG_DEBUG("command result: processing verb: " << verb);
diff --git a/daemon/mgmt/strategy-choice-manager.cpp b/daemon/mgmt/strategy-choice-manager.cpp
index e93353b..4f2728c 100644
--- a/daemon/mgmt/strategy-choice-manager.cpp
+++ b/daemon/mgmt/strategy-choice-manager.cpp
@@ -72,6 +72,13 @@
       listStrategies(request);
       return;
     }
+  else if (commandNComps <= COMMAND_PREFIX.size())
+    {
+      // command is too short to have a verb
+      NFD_LOG_DEBUG("command result: malformed");
+      sendResponse(command, 400, "Malformed command");
+      return;
+    }
 
   if (COMMAND_UNSIGNED_NCOMPS <= commandNComps &&
       commandNComps < COMMAND_SIGNED_NCOMPS)
@@ -116,7 +123,7 @@
       return;
     }
 
-  const Name::Component& verb = command[COMMAND_PREFIX.size()];
+  const Name::Component& verb = command.at(COMMAND_PREFIX.size());
   ControlResponse response;
   if (verb == VERB_SET)
     {
diff --git a/rib/rib-manager.cpp b/rib/rib-manager.cpp
index e7ea3e9..491739a 100644
--- a/rib/rib-manager.cpp
+++ b/rib/rib-manager.cpp
@@ -200,7 +200,16 @@
 RibManager::onLocalhostRequest(const Interest& request)
 {
   const Name& command = request.getName();
-  const Name::Component& verb = command.get(COMMAND_PREFIX.size());
+
+  if (command.size() <= COMMAND_PREFIX.size())
+    {
+      // command is too short to have a verb
+      NFD_LOG_DEBUG("command result: malformed");
+      sendResponse(command, 400, "Malformed command");
+      return;
+    }
+
+  const Name::Component& verb = command.at(COMMAND_PREFIX.size());
 
   UnsignedVerbDispatchTable::const_iterator unsignedVerbProcessor = m_unsignedVerbDispatch.find(verb);
 
diff --git a/tests/daemon/mgmt/face-manager.cpp b/tests/daemon/mgmt/face-manager.cpp
index 2b2a15e..000a0d6 100644
--- a/tests/daemon/mgmt/face-manager.cpp
+++ b/tests/daemon/mgmt/face-manager.cpp
@@ -793,7 +793,7 @@
 
 #endif // HAVE_LIBPCAP
 
-BOOST_AUTO_TEST_CASE(TestFireInterestFilter)
+BOOST_AUTO_TEST_CASE(ShortName)
 {
   shared_ptr<Interest> command(make_shared<Interest>("/localhost/nfd/faces"));
 
diff --git a/tests/daemon/mgmt/fib-manager.cpp b/tests/daemon/mgmt/fib-manager.cpp
index 22bf276..525dfc8 100644
--- a/tests/daemon/mgmt/fib-manager.cpp
+++ b/tests/daemon/mgmt/fib-manager.cpp
@@ -235,7 +235,7 @@
   return false;
 }
 
-BOOST_AUTO_TEST_CASE(TestFireInterestFilter)
+BOOST_AUTO_TEST_CASE(ShortName)
 {
   shared_ptr<InternalFace> face = getInternalFace();
 
diff --git a/tests/daemon/mgmt/strategy-choice-manager.cpp b/tests/daemon/mgmt/strategy-choice-manager.cpp
index 2ae23c5..570c1d8 100644
--- a/tests/daemon/mgmt/strategy-choice-manager.cpp
+++ b/tests/daemon/mgmt/strategy-choice-manager.cpp
@@ -221,7 +221,7 @@
 BOOST_FIXTURE_TEST_SUITE(MgmtStrategyChoiceManager,
                          AuthorizedCommandFixture<AllStrategiesFixture>)
 
-BOOST_FIXTURE_TEST_CASE(TestFireInterestFilter, AllStrategiesFixture)
+BOOST_FIXTURE_TEST_CASE(ShortName, AllStrategiesFixture)
 {
   shared_ptr<Interest> command(make_shared<Interest>("/localhost/nfd/strategy-choice"));
 
diff --git a/tests/rib/rib-manager.cpp b/tests/rib/rib-manager.cpp
index afef2f3..39a4a5d 100644
--- a/tests/rib/rib-manager.cpp
+++ b/tests/rib/rib-manager.cpp
@@ -71,8 +71,11 @@
 
   void receiveCommandInterest(Name& name, ControlParameters& parameters)
   {
-    name.append(parameters.wireEncode());
+    receiveCommandInterest(name.append(parameters.wireEncode()));
+  }
 
+  void receiveCommandInterest(const Name& name)
+  {
     Interest command(name);
 
     face->receive(command);
@@ -116,6 +119,13 @@
 
 BOOST_FIXTURE_TEST_SUITE(RibManager, RibManagerFixture)
 
+BOOST_FIXTURE_TEST_CASE(ShortName, AuthorizedRibManager)
+{
+  Name commandName("/localhost/nfd/rib");
+  receiveCommandInterest(commandName);
+  // TODO verify error response
+}
+
 BOOST_FIXTURE_TEST_CASE(Basic, AuthorizedRibManager)
 {
   ControlParameters parameters;