blob: d9032c86ba7600617ce292f62b493b78c767c148 [file] [log] [blame]
Alexander Afanasyeve5a19b82017-01-30 22:30:46 -08001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2/*
Davide Pesavento5df42a82018-03-08 20:06:51 -05003 * Copyright (c) 2013-2018 Regents of the University of California.
Alexander Afanasyeve5a19b82017-01-30 22:30:46 -08004 *
5 * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
6 *
7 * ndn-cxx library is free software: you can redistribute it and/or modify it under the
8 * terms of the GNU Lesser General Public License as published by the Free Software
9 * Foundation, either version 3 of the License, or (at your option) any later version.
10 *
11 * ndn-cxx library is distributed in the hope that it will be useful, but WITHOUT ANY
12 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
13 * PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
14 *
15 * You should have received copies of the GNU General Public License and GNU Lesser
16 * General Public License along with ndn-cxx, e.g., in COPYING.md file. If not, see
17 * <http://www.gnu.org/licenses/>.
18 *
19 * See AUTHORS.md for complete list of ndn-cxx authors and contributors.
20 */
21
22#include "filter.hpp"
23
24#include "data.hpp"
25#include "interest.hpp"
Alexander Afanasyeve5a19b82017-01-30 22:30:46 -080026#include "security/security-common.hpp"
Davide Pesavento5df42a82018-03-08 20:06:51 -050027#include "util/regex.hpp"
Alexander Afanasyeve5a19b82017-01-30 22:30:46 -080028
Davide Pesavento5df42a82018-03-08 20:06:51 -050029#include <boost/algorithm/string/predicate.hpp>
Alexander Afanasyeve5a19b82017-01-30 22:30:46 -080030
31namespace ndn {
32namespace security {
33namespace v2 {
34namespace validator_config {
35
36bool
37Filter::match(uint32_t pktType, const Name& pktName)
38{
39 BOOST_ASSERT(pktType == tlv::Interest || pktType == tlv::Data);
40
41 if (pktType == tlv::Interest) {
42 if (pktName.size() < signed_interest::MIN_SIZE)
43 return false;
44
45 return matchName(pktName.getPrefix(-signed_interest::MIN_SIZE));
46 }
47 else {
48 return matchName(pktName);
49 }
50}
51
52RelationNameFilter::RelationNameFilter(const Name& name, NameRelation relation)
53 : m_name(name)
54 , m_relation(relation)
55{
56}
57
58bool
59RelationNameFilter::matchName(const Name& name)
60{
61 return checkNameRelation(m_relation, m_name, name);
62}
63
64RegexNameFilter::RegexNameFilter(const Regex& regex)
65 : m_regex(regex)
66{
67}
68
69bool
70RegexNameFilter::matchName(const Name& name)
71{
72 return m_regex.match(name);
73}
74
75unique_ptr<Filter>
76Filter::create(const ConfigSection& configSection, const std::string& configFilename)
77{
78 auto propertyIt = configSection.begin();
79
80 if (propertyIt == configSection.end() || !boost::iequals(propertyIt->first, "type")) {
Davide Pesavento5df42a82018-03-08 20:06:51 -050081 BOOST_THROW_EXCEPTION(Error("Expecting <filter.type>"));
Alexander Afanasyeve5a19b82017-01-30 22:30:46 -080082 }
83
84 std::string type = propertyIt->second.data();
Alexander Afanasyeve5a19b82017-01-30 22:30:46 -080085 if (boost::iequals(type, "name"))
86 return createNameFilter(configSection, configFilename);
87 else
Davide Pesavento5df42a82018-03-08 20:06:51 -050088 BOOST_THROW_EXCEPTION(Error("Unrecognized <filter.type>: " + type));
Alexander Afanasyeve5a19b82017-01-30 22:30:46 -080089}
90
91unique_ptr<Filter>
92Filter::createNameFilter(const ConfigSection& configSection, const std::string& configFilename)
93{
94 auto propertyIt = configSection.begin();
95 propertyIt++;
96
Davide Pesavento5df42a82018-03-08 20:06:51 -050097 if (propertyIt == configSection.end())
98 BOOST_THROW_EXCEPTION(Error("Unexpected end of <filter>"));
Alexander Afanasyeve5a19b82017-01-30 22:30:46 -080099
100 if (boost::iequals(propertyIt->first, "name")) {
101 // Get filter.name
102 Name name;
103 try {
104 name = Name(propertyIt->second.data());
105 }
Davide Pesavento5df42a82018-03-08 20:06:51 -0500106 catch (const Name::Error&) {
107 BOOST_THROW_EXCEPTION(Error("Invalid <filter.name>: " + propertyIt->second.data()));
Alexander Afanasyeve5a19b82017-01-30 22:30:46 -0800108 }
109
110 propertyIt++;
111
112 // Get filter.relation
113 if (propertyIt == configSection.end() || !boost::iequals(propertyIt->first, "relation")) {
Davide Pesavento5df42a82018-03-08 20:06:51 -0500114 BOOST_THROW_EXCEPTION(Error("Expecting <filter.relation>"));
Alexander Afanasyeve5a19b82017-01-30 22:30:46 -0800115 }
116
117 NameRelation relation = getNameRelationFromString(propertyIt->second.data());
118 propertyIt++;
119
120 if (propertyIt != configSection.end())
Davide Pesavento5df42a82018-03-08 20:06:51 -0500121 BOOST_THROW_EXCEPTION(Error("Expecting end of <filter>"));
Alexander Afanasyeve5a19b82017-01-30 22:30:46 -0800122
123 return make_unique<RelationNameFilter>(name, relation);
124 }
125 else if (boost::iequals(propertyIt->first, "regex")) {
126 std::string regexString = propertyIt->second.data();
127 propertyIt++;
128
129 if (propertyIt != configSection.end())
Davide Pesavento5df42a82018-03-08 20:06:51 -0500130 BOOST_THROW_EXCEPTION(Error("Expecting end of <filter>"));
Alexander Afanasyeve5a19b82017-01-30 22:30:46 -0800131
132 try {
Davide Pesavento45ab9a92017-11-05 19:34:31 -0500133 return make_unique<RegexNameFilter>(Regex(regexString));
Alexander Afanasyeve5a19b82017-01-30 22:30:46 -0800134 }
Davide Pesavento5df42a82018-03-08 20:06:51 -0500135 catch (const Regex::Error&) {
136 BOOST_THROW_EXCEPTION(Error("Invalid <filter.regex>: " + regexString));
Alexander Afanasyeve5a19b82017-01-30 22:30:46 -0800137 }
138 }
139 else {
Davide Pesavento5df42a82018-03-08 20:06:51 -0500140 BOOST_THROW_EXCEPTION(Error("Unrecognized <filter> property: " + propertyIt->first));
Alexander Afanasyeve5a19b82017-01-30 22:30:46 -0800141 }
142}
143
144} // namespace validator_config
145} // namespace v2
146} // namespace security
147} // namespace ndn