add policy checker
Change-Id: I90c50d15b1d9d97832c66ce90e39524729f12a0f
diff --git a/core/conf/key-locator-checker.cpp b/core/conf/key-locator-checker.cpp
new file mode 100644
index 0000000..2fd27bc
--- /dev/null
+++ b/core/conf/key-locator-checker.cpp
@@ -0,0 +1,277 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/**
+ * Copyright (c) 2014, Regents of the University of California
+ *
+ * This file is part of NSL (NDN Signature Logger).
+ * See AUTHORS.md for complete list of NSL authors and contributors.
+ *
+ * NSL is free software: you can redistribute it and/or modify it under the terms
+ * of the GNU General Public License as published by the Free Software Foundation,
+ * either version 3 of the License, or (at your option) any later version.
+ *
+ * NSL is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
+ * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ * PURPOSE. See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * NSL, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * See AUTHORS.md for complete list of nsl authors and contributors.
+ */
+
+#include "key-locator-checker.hpp"
+
+#include <boost/algorithm/string.hpp>
+
+namespace nsl {
+namespace conf {
+
+KeyLocatorChecker::~KeyLocatorChecker()
+{
+}
+
+bool
+KeyLocatorChecker::check(const Data& data, const KeyLocator& keyLocator, std::string& failInfo)
+{
+ return check(data.getName(), keyLocator, failInfo);
+}
+
+bool
+KeyLocatorChecker::checkRelation(const Relation& relation, const Name& name1, const Name& name2)
+{
+ switch (relation) {
+ case RELATION_EQUAL:
+ return (name1 == name2);
+ case RELATION_IS_PREFIX_OF:
+ return name1.isPrefixOf(name2);
+ case RELATION_IS_STRICT_PREFIX_OF:
+ return (name1.isPrefixOf(name2) && name1 != name2);
+ default:
+ return false;
+ }
+}
+
+RelationKeyLocatorNameChecker::RelationKeyLocatorNameChecker(const Name& name,
+ const KeyLocatorChecker::Relation& relation)
+ : m_name(name)
+ , m_relation(relation)
+{
+}
+
+bool
+RelationKeyLocatorNameChecker::check(const Name& packetName,
+ const KeyLocator& keyLocator,
+ std::string& failInfo)
+{
+ try {
+ if (checkRelation(m_relation, m_name, keyLocator.getName()))
+ return true;
+
+ failInfo = "KeyLocatorChecker failed";
+ return false;
+ }
+ catch (KeyLocator::Error&) {
+ failInfo = "KeyLocator does not have name";
+ return false;
+ }
+}
+
+RegexKeyLocatorNameChecker::RegexKeyLocatorNameChecker(const ndn::Regex& regex)
+ : m_regex(regex)
+{
+}
+
+bool
+RegexKeyLocatorNameChecker::check(const Name& packetName,
+ const KeyLocator& keyLocator,
+ std::string& failInfo)
+{
+ try {
+ if (m_regex.match(keyLocator.getName()))
+ return true;
+
+ failInfo = "KeyLocatorChecker failed";
+ return false;
+ }
+ catch (KeyLocator::Error&) {
+ failInfo = "KeyLocator does not have name";
+ return false;
+ }
+}
+
+HyperKeyLocatorNameChecker::HyperKeyLocatorNameChecker(const std::string& pExpr,
+ const std::string pExpand,
+ const std::string& kExpr,
+ const std::string kExpand,
+ const Relation& hyperRelation)
+ : m_hyperPRegex(new ndn::Regex(pExpr, pExpand))
+ , m_hyperKRegex(new ndn::Regex(kExpr, kExpand))
+ , m_hyperRelation(hyperRelation)
+{
+}
+
+bool
+HyperKeyLocatorNameChecker::check(const Name& packetName,
+ const KeyLocator& keyLocator,
+ std::string& failInfo)
+{
+ try {
+ if (m_hyperPRegex->match(packetName) &&
+ m_hyperKRegex->match(keyLocator.getName()) &&
+ checkRelation(m_hyperRelation,
+ m_hyperKRegex->expand(),
+ m_hyperPRegex->expand()))
+ return true;
+
+ failInfo = "KeyLocatorChecker failed";
+ return false;
+ }
+ catch (KeyLocator::Error&) {
+ failInfo = "KeyLocator does not have name";
+ return false;
+ }
+}
+
+shared_ptr<KeyLocatorChecker>
+KeyLocatorCheckerFactory::create(const ConfigSection& configSection)
+{
+ ConfigSection::const_iterator propertyIt = configSection.begin();
+
+ // Get checker.key-locator.type
+ if (propertyIt == configSection.end() || !boost::iequals(propertyIt->first, "type"))
+ throw Error("Expect <checker.key-locator.type>");
+
+ std::string type = propertyIt->second.data();
+
+ if (boost::iequals(type, "name"))
+ return createKeyLocatorNameChecker(configSection);
+ else
+ throw Error("Unsupported checker.key-locator.type: " + type);
+}
+
+shared_ptr<KeyLocatorChecker>
+KeyLocatorCheckerFactory::createKeyLocatorNameChecker(const ConfigSection& configSection)
+{
+ ConfigSection::const_iterator propertyIt = configSection.begin();
+ propertyIt++;
+
+ if (propertyIt == configSection.end())
+ throw Error("Expect more checker.key-locator properties");
+
+ if (boost::iequals(propertyIt->first, "name")) {
+ Name name;
+ try {
+ name = Name(propertyIt->second.data());
+ }
+ catch (Name::Error& e) {
+ throw Error("Invalid checker.key-locator.name: " +
+ propertyIt->second.data());
+ }
+ propertyIt++;
+
+ if (propertyIt == configSection.end() || !boost::iequals(propertyIt->first, "relation"))
+ throw Error("Expect <checker.key-locator.relation>!");
+
+ std::string relationString = propertyIt->second.data();
+ propertyIt++;
+
+ KeyLocatorChecker::Relation relation;
+ if (boost::iequals(relationString, "equal"))
+ relation = KeyLocatorChecker::RELATION_EQUAL;
+ else if (boost::iequals(relationString, "is-prefix-of"))
+ relation = KeyLocatorChecker::RELATION_IS_PREFIX_OF;
+ else if (boost::iequals(relationString, "is-strict-prefix-of"))
+ relation = KeyLocatorChecker::RELATION_IS_STRICT_PREFIX_OF;
+ else
+ throw Error("Unsupported relation: " + relationString);
+
+ if (propertyIt != configSection.end())
+ throw Error("Expect the end of checker.key-locator!");
+
+ return shared_ptr<RelationKeyLocatorNameChecker>
+ (new RelationKeyLocatorNameChecker(name, relation));
+ }
+ else if (boost::iequals(propertyIt->first, "regex")) {
+ std::string regexString = propertyIt->second.data();
+ propertyIt++;
+
+ if (propertyIt != configSection.end())
+ throw Error("Expect the end of checker.key-locator!");
+
+ try {
+ return shared_ptr<RegexKeyLocatorNameChecker>
+ (new RegexKeyLocatorNameChecker(regexString));
+ }
+ catch (ndn::Regex::Error& e) {
+ throw Error("Invalid checker.key-locator.regex: " + regexString);
+ }
+ }
+ else if (boost::iequals(propertyIt->first, "hyper-relation")) {
+ const ConfigSection& hSection = propertyIt->second;
+
+ ConfigSection::const_iterator hPropertyIt = hSection.begin();
+
+ // Get k-regex
+ if (hPropertyIt == hSection.end() || !boost::iequals(hPropertyIt->first, "k-regex"))
+ throw Error("Expect <checker.key-locator.hyper-relation.k-regex>!");
+
+ std::string kRegex = hPropertyIt->second.data();
+ hPropertyIt++;
+
+ // Get k-expand
+ if (hPropertyIt == hSection.end() || !boost::iequals(hPropertyIt->first, "k-expand"))
+ throw Error("Expect <checker.key-locator.hyper-relation.k-expand>!");
+
+ std::string kExpand = hPropertyIt->second.data();
+ hPropertyIt++;
+
+ // Get h-relation
+ if (hPropertyIt == hSection.end() || !boost::iequals(hPropertyIt->first, "h-relation"))
+ throw Error("Expect <checker.key-locator.hyper-relation.h-relation>!");
+
+ std::string hRelation = hPropertyIt->second.data();
+ hPropertyIt++;
+
+ // Get p-regex
+ if (hPropertyIt == hSection.end() || !boost::iequals(hPropertyIt->first, "p-regex"))
+ throw Error("Expect <checker.key-locator.hyper-relation.p-regex>!");
+
+ std::string pRegex = hPropertyIt->second.data();
+ hPropertyIt++;
+
+ // Get p-expand
+ if (hPropertyIt == hSection.end() || !boost::iequals(hPropertyIt->first, "p-expand"))
+ throw Error("Expect <checker.key-locator.hyper-relation.p-expand>!");
+
+ std::string pExpand = hPropertyIt->second.data();
+ hPropertyIt++;
+
+ if (hPropertyIt != hSection.end())
+ throw Error("Expect the end of checker.key-locator.hyper-relation!");
+
+ KeyLocatorChecker::Relation relation;
+ if (boost::iequals(hRelation, "equal"))
+ relation = KeyLocatorChecker::RELATION_EQUAL;
+ else if (boost::iequals(hRelation, "is-prefix-of"))
+ relation = KeyLocatorChecker::RELATION_IS_PREFIX_OF;
+ else if (boost::iequals(hRelation, "is-strict-prefix-of"))
+ relation = KeyLocatorChecker::RELATION_IS_STRICT_PREFIX_OF;
+ else
+ throw Error("Unsupported checker.key-locator.hyper-relation.h-relation: " + hRelation);
+
+ try {
+ return shared_ptr<HyperKeyLocatorNameChecker>
+ (new HyperKeyLocatorNameChecker(pRegex, pExpand,
+ kRegex, kExpand,
+ relation));
+ }
+ catch (ndn::Regex::Error& e) {
+ throw Error("Invalid regex for key-locator.hyper-relation");
+ }
+ }
+ else
+ throw Error("Unsupported checker.key-locator");
+}
+
+} // namespace conf
+} // namespace nsl