| /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil -*- */ |
| /** |
| * Copyright (C) 2013 Regents of the University of California. |
| * @author: Yingdi Yu <yingdi@cs.ucla.edu> |
| * See COPYING for copyright and distribution information. |
| */ |
| |
| #ifndef NDN_SECURITY_CONF_FILTER_HPP |
| #define NDN_SECURITY_CONF_FILTER_HPP |
| |
| #include "../../common.hpp" |
| #include "../../data.hpp" |
| #include "../../interest.hpp" |
| #include "../../util/regex.hpp" |
| #include <boost/algorithm/string.hpp> |
| |
| #include "common.hpp" |
| |
| namespace ndn { |
| namespace security { |
| namespace conf { |
| |
| class Filter |
| { |
| public: |
| virtual |
| ~Filter() |
| { |
| } |
| |
| virtual bool |
| match(const Data& data) = 0; |
| |
| virtual bool |
| match(const Interest& interest) = 0; |
| }; |
| |
| class RelationNameFilter : public Filter |
| { |
| public: |
| enum Relation |
| { |
| RELATION_EQUAL, |
| RELATION_IS_PREFIX_OF, |
| RELATION_IS_STRICT_PREFIX_OF |
| }; |
| |
| RelationNameFilter(const Name& name, Relation relation) |
| : m_name(name) |
| , m_relation(relation) |
| { |
| } |
| |
| virtual |
| ~RelationNameFilter() |
| { |
| } |
| |
| virtual bool |
| match(const Data& data) |
| { |
| return match(data.getName()); |
| } |
| |
| virtual bool |
| match(const Interest& interest) |
| { |
| if (interest.getName().size() < 2) |
| return false; |
| |
| Name signedName = interest.getName().getPrefix(-2); |
| return match(signedName); |
| } |
| |
| private: |
| bool |
| match(const Name& name) |
| { |
| switch (m_relation) |
| { |
| case RELATION_EQUAL: |
| return (name == m_name); |
| case RELATION_IS_PREFIX_OF: |
| return m_name.isPrefixOf(name); |
| case RELATION_IS_STRICT_PREFIX_OF: |
| return (m_name.isPrefixOf(name) && m_name != name); |
| default: |
| return false; |
| } |
| } |
| |
| private: |
| Name m_name; |
| Relation m_relation; |
| }; |
| |
| class RegexNameFilter : public Filter |
| { |
| public: |
| explicit |
| RegexNameFilter(const Regex& regex) |
| : m_regex(regex) |
| { |
| } |
| |
| virtual |
| ~RegexNameFilter() |
| { |
| } |
| |
| virtual bool |
| match(const Data& data) |
| { |
| return m_regex.match(data.getName()); |
| } |
| |
| virtual bool |
| match(const Interest& interest) |
| { |
| if (interest.getName().size() < 2) |
| return false; |
| |
| Name signedName = interest.getName().getPrefix(-2); |
| return m_regex.match(signedName); |
| } |
| |
| private: |
| Regex m_regex; |
| }; |
| |
| class FilterFactory |
| { |
| public: |
| static shared_ptr<Filter> |
| create(const ConfigSection& configSection) |
| { |
| ConfigSection::const_iterator propertyIt = configSection.begin(); |
| |
| if (propertyIt == configSection.end() || !boost::iequals(propertyIt->first, "type")) |
| throw Error("Expect <filter.type>!"); |
| |
| std::string type = propertyIt->second.data(); |
| |
| if (boost::iequals(type, "name")) |
| return createNameFilter(configSection); |
| else |
| throw Error("Unsupported filter.type: " + type); |
| } |
| private: |
| static shared_ptr<Filter> |
| createNameFilter(const ConfigSection& configSection) |
| { |
| ConfigSection::const_iterator propertyIt = configSection.begin(); |
| propertyIt++; |
| |
| if (propertyIt == configSection.end()) |
| throw Error("Expect more properties for filter(name)"); |
| |
| if (boost::iequals(propertyIt->first, "name")) |
| { |
| // Get filter.name |
| Name name; |
| try |
| { |
| name = Name(propertyIt->second.data()); |
| } |
| catch (Name::Error& e) |
| { |
| throw Error("Wrong filter.name: " + propertyIt->second.data()); |
| } |
| |
| propertyIt++; |
| |
| // Get filter.relation |
| if (propertyIt == configSection.end() || !boost::iequals(propertyIt->first, "relation")) |
| throw Error("Expect <filter.relation>!"); |
| |
| std::string relationString = propertyIt->second.data(); |
| propertyIt++; |
| |
| RelationNameFilter::Relation relation; |
| if (boost::iequals(relationString, "equal")) |
| relation = RelationNameFilter::RELATION_EQUAL; |
| else if (boost::iequals(relationString, "is-prefix-of")) |
| relation = RelationNameFilter::RELATION_IS_PREFIX_OF; |
| else if (boost::iequals(relationString, "is-strict-prefix-of")) |
| relation = RelationNameFilter::RELATION_IS_STRICT_PREFIX_OF; |
| else |
| throw Error("Unsupported relation: " + relationString); |
| |
| |
| if (propertyIt != configSection.end()) |
| throw Error("Expect the end of filter!"); |
| |
| return make_shared<RelationNameFilter>(boost::cref(name), |
| boost::cref(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 filter!"); |
| |
| try |
| { |
| return shared_ptr<RegexNameFilter>(new RegexNameFilter(regexString)); |
| } |
| catch (const Regex::Error& e) |
| { |
| throw Error("Wrong filter.regex: " + regexString); |
| } |
| } |
| else |
| throw Error("Wrong filter(name) properties"); |
| } |
| }; |
| |
| } // namespace conf |
| } // namespace security |
| } // namespace ndn |
| |
| #endif // NDN_SECURITY_CONF_FILTER_HPP |