blob: 8e21677c6c136a76dabebf4118c85ef8a74f7295 [file] [log] [blame]
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/**
* Copyright (c) 2014-2017, Regents of the University of California
*
* This file is part of NDN DeLorean, An Authentication System for Data Archives in
* Named Data Networking. See AUTHORS.md for complete list of NDN DeLorean authors
* and contributors.
*
* NDN DeLorean 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.
*
* NDN DeLorean 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 NDN
* DeLorean, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>.
*/
#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