security: Adding wildcard support in CommandInterestValidator

Change-Id: I21beb5704f2e2584155377c5b2de59f0ea46c4fa
Refs: #1561
diff --git a/src/security/sec-rule-specific.cpp b/src/security/sec-rule-specific.cpp
index 58bcc26..9b44d83 100644
--- a/src/security/sec-rule-specific.cpp
+++ b/src/security/sec-rule-specific.cpp
@@ -26,6 +26,14 @@
   : SecRule(true)
   , m_dataRegex(dataRegex)
   , m_signerRegex(signerRegex)
+  , m_isExempted(false)
+{
+}
+
+SecRuleSpecific::SecRuleSpecific(shared_ptr<Regex> dataRegex)
+  : SecRule(true)
+  , m_dataRegex(dataRegex)
+  , m_isExempted(true)
 {
 }
 
@@ -33,6 +41,7 @@
   : SecRule(true)
   , m_dataRegex(rule.m_dataRegex)
   , m_signerRegex(rule.m_signerRegex)
+  , m_isExempted(rule.m_isExempted)
 {
 }
 
@@ -45,6 +54,9 @@
 bool
 SecRuleSpecific::matchSignerName(const Data& data)
 {
+  if (m_isExempted)
+    return true;
+
   try
     {
       SignatureSha256WithRsa sig(data.getSignature());
@@ -66,7 +78,8 @@
 bool
 SecRuleSpecific::satisfy(const Name& dataName, const Name& signerName)
 {
-  return (m_dataRegex->match(dataName) && m_signerRegex->match(signerName));
+  bool isSignerMatched = m_isExempted || m_signerRegex->match(signerName);
+  return (m_dataRegex->match(dataName) && isSignerMatched);
 }
 
 } // namespace ndn
diff --git a/src/security/sec-rule-specific.hpp b/src/security/sec-rule-specific.hpp
index 278bbcd..a7bf833 100644
--- a/src/security/sec-rule-specific.hpp
+++ b/src/security/sec-rule-specific.hpp
@@ -28,6 +28,8 @@
   SecRuleSpecific(shared_ptr<Regex> dataRegex,
                   shared_ptr<Regex> signerRegex);
 
+  SecRuleSpecific(shared_ptr<Regex> dataRegex);
+
   SecRuleSpecific(const SecRuleSpecific& rule);
 
   virtual
@@ -45,9 +47,16 @@
   bool
   satisfy(const Name& dataName, const Name& signerName);
 
+  bool
+  isExempted() const
+  {
+    return m_isExempted;
+  }
+
 private:
   shared_ptr<Regex> m_dataRegex;
   shared_ptr<Regex> m_signerRegex;
+  bool m_isExempted;
 };
 
 } // namespace ndn
diff --git a/src/util/command-interest-validator.hpp b/src/util/command-interest-validator.hpp
index 17d264b..6bd3250 100644
--- a/src/util/command-interest-validator.hpp
+++ b/src/util/command-interest-validator.hpp
@@ -45,12 +45,34 @@
   {
   }
 
+  /**
+   * @brief add an Interest rule that allows a specific certificate
+   *
+   * @param regex NDN Regex to match Interest Name
+   * @param certificate trusted certificate
+   */
   void
   addInterestRule(const std::string& regex, const IdentityCertificate& certificate);
 
+  /**
+   * @brief add an Interest rule that allows a specific public key
+   *
+   * @param regex NDN Regex to match Interest Name
+   * @param keyName KeyLocator.Name
+   * @param publicKey public key
+   */
   void
   addInterestRule(const std::string& regex, const Name& keyName, const PublicKey& publicKey);
 
+  /**
+   * @brief add an Interest rule that allows any signer
+   *
+   * @param regex NDN Regex to match Interest Name
+   * @note Command Interest matched by regex that is signed by any key will be accepted.
+   */
+  void
+  addInterestBypassRule(const std::string& regex);
+
 protected:
   virtual void
   checkPolicy(const Data& data,
@@ -97,6 +119,13 @@
 }
 
 inline void
+CommandInterestValidator::addInterestBypassRule(const std::string& regex)
+{
+  shared_ptr<Regex> interestRegex = make_shared<Regex>(regex);
+  m_trustScopeForInterest.push_back(SecRuleSpecific(interestRegex));
+}
+
+inline void
 CommandInterestValidator::checkPolicy(const Interest& interest,
                                       int stepCount,
                                       const OnInterestValidated& onValidated,
@@ -137,6 +166,11 @@
         {
           if (scopeIt->satisfy(interestName, keyName))
             {
+              if (scopeIt->isExempted())
+                {
+                  return onValidated(interest.shared_from_this());
+                }
+
               isInScope = true;
               break;
             }