blob: 2fd27bcff83a11ac3df476f8b537d914301019f4 [file] [log] [blame]
Yingdi Yu7d773322015-03-22 21:32:48 -07001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2/**
3 * Copyright (c) 2014, Regents of the University of California
4 *
5 * This file is part of NSL (NDN Signature Logger).
6 * See AUTHORS.md for complete list of NSL authors and contributors.
7 *
8 * NSL is free software: you can redistribute it and/or modify it under the terms
9 * of the GNU General Public License as published by the Free Software Foundation,
10 * either version 3 of the License, or (at your option) any later version.
11 *
12 * NSL is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
13 * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
14 * PURPOSE. See the GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License along with
17 * NSL, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>.
18 *
19 * See AUTHORS.md for complete list of nsl authors and contributors.
20 */
21
22#include "key-locator-checker.hpp"
23
24#include <boost/algorithm/string.hpp>
25
26namespace nsl {
27namespace conf {
28
29KeyLocatorChecker::~KeyLocatorChecker()
30{
31}
32
33bool
34KeyLocatorChecker::check(const Data& data, const KeyLocator& keyLocator, std::string& failInfo)
35{
36 return check(data.getName(), keyLocator, failInfo);
37}
38
39bool
40KeyLocatorChecker::checkRelation(const Relation& relation, const Name& name1, const Name& name2)
41{
42 switch (relation) {
43 case RELATION_EQUAL:
44 return (name1 == name2);
45 case RELATION_IS_PREFIX_OF:
46 return name1.isPrefixOf(name2);
47 case RELATION_IS_STRICT_PREFIX_OF:
48 return (name1.isPrefixOf(name2) && name1 != name2);
49 default:
50 return false;
51 }
52}
53
54RelationKeyLocatorNameChecker::RelationKeyLocatorNameChecker(const Name& name,
55 const KeyLocatorChecker::Relation& relation)
56 : m_name(name)
57 , m_relation(relation)
58{
59}
60
61bool
62RelationKeyLocatorNameChecker::check(const Name& packetName,
63 const KeyLocator& keyLocator,
64 std::string& failInfo)
65{
66 try {
67 if (checkRelation(m_relation, m_name, keyLocator.getName()))
68 return true;
69
70 failInfo = "KeyLocatorChecker failed";
71 return false;
72 }
73 catch (KeyLocator::Error&) {
74 failInfo = "KeyLocator does not have name";
75 return false;
76 }
77}
78
79RegexKeyLocatorNameChecker::RegexKeyLocatorNameChecker(const ndn::Regex& regex)
80 : m_regex(regex)
81{
82}
83
84bool
85RegexKeyLocatorNameChecker::check(const Name& packetName,
86 const KeyLocator& keyLocator,
87 std::string& failInfo)
88{
89 try {
90 if (m_regex.match(keyLocator.getName()))
91 return true;
92
93 failInfo = "KeyLocatorChecker failed";
94 return false;
95 }
96 catch (KeyLocator::Error&) {
97 failInfo = "KeyLocator does not have name";
98 return false;
99 }
100}
101
102HyperKeyLocatorNameChecker::HyperKeyLocatorNameChecker(const std::string& pExpr,
103 const std::string pExpand,
104 const std::string& kExpr,
105 const std::string kExpand,
106 const Relation& hyperRelation)
107 : m_hyperPRegex(new ndn::Regex(pExpr, pExpand))
108 , m_hyperKRegex(new ndn::Regex(kExpr, kExpand))
109 , m_hyperRelation(hyperRelation)
110{
111}
112
113bool
114HyperKeyLocatorNameChecker::check(const Name& packetName,
115 const KeyLocator& keyLocator,
116 std::string& failInfo)
117{
118 try {
119 if (m_hyperPRegex->match(packetName) &&
120 m_hyperKRegex->match(keyLocator.getName()) &&
121 checkRelation(m_hyperRelation,
122 m_hyperKRegex->expand(),
123 m_hyperPRegex->expand()))
124 return true;
125
126 failInfo = "KeyLocatorChecker failed";
127 return false;
128 }
129 catch (KeyLocator::Error&) {
130 failInfo = "KeyLocator does not have name";
131 return false;
132 }
133}
134
135shared_ptr<KeyLocatorChecker>
136KeyLocatorCheckerFactory::create(const ConfigSection& configSection)
137{
138 ConfigSection::const_iterator propertyIt = configSection.begin();
139
140 // Get checker.key-locator.type
141 if (propertyIt == configSection.end() || !boost::iequals(propertyIt->first, "type"))
142 throw Error("Expect <checker.key-locator.type>");
143
144 std::string type = propertyIt->second.data();
145
146 if (boost::iequals(type, "name"))
147 return createKeyLocatorNameChecker(configSection);
148 else
149 throw Error("Unsupported checker.key-locator.type: " + type);
150}
151
152shared_ptr<KeyLocatorChecker>
153KeyLocatorCheckerFactory::createKeyLocatorNameChecker(const ConfigSection& configSection)
154{
155 ConfigSection::const_iterator propertyIt = configSection.begin();
156 propertyIt++;
157
158 if (propertyIt == configSection.end())
159 throw Error("Expect more checker.key-locator properties");
160
161 if (boost::iequals(propertyIt->first, "name")) {
162 Name name;
163 try {
164 name = Name(propertyIt->second.data());
165 }
166 catch (Name::Error& e) {
167 throw Error("Invalid checker.key-locator.name: " +
168 propertyIt->second.data());
169 }
170 propertyIt++;
171
172 if (propertyIt == configSection.end() || !boost::iequals(propertyIt->first, "relation"))
173 throw Error("Expect <checker.key-locator.relation>!");
174
175 std::string relationString = propertyIt->second.data();
176 propertyIt++;
177
178 KeyLocatorChecker::Relation relation;
179 if (boost::iequals(relationString, "equal"))
180 relation = KeyLocatorChecker::RELATION_EQUAL;
181 else if (boost::iequals(relationString, "is-prefix-of"))
182 relation = KeyLocatorChecker::RELATION_IS_PREFIX_OF;
183 else if (boost::iequals(relationString, "is-strict-prefix-of"))
184 relation = KeyLocatorChecker::RELATION_IS_STRICT_PREFIX_OF;
185 else
186 throw Error("Unsupported relation: " + relationString);
187
188 if (propertyIt != configSection.end())
189 throw Error("Expect the end of checker.key-locator!");
190
191 return shared_ptr<RelationKeyLocatorNameChecker>
192 (new RelationKeyLocatorNameChecker(name, relation));
193 }
194 else if (boost::iequals(propertyIt->first, "regex")) {
195 std::string regexString = propertyIt->second.data();
196 propertyIt++;
197
198 if (propertyIt != configSection.end())
199 throw Error("Expect the end of checker.key-locator!");
200
201 try {
202 return shared_ptr<RegexKeyLocatorNameChecker>
203 (new RegexKeyLocatorNameChecker(regexString));
204 }
205 catch (ndn::Regex::Error& e) {
206 throw Error("Invalid checker.key-locator.regex: " + regexString);
207 }
208 }
209 else if (boost::iequals(propertyIt->first, "hyper-relation")) {
210 const ConfigSection& hSection = propertyIt->second;
211
212 ConfigSection::const_iterator hPropertyIt = hSection.begin();
213
214 // Get k-regex
215 if (hPropertyIt == hSection.end() || !boost::iequals(hPropertyIt->first, "k-regex"))
216 throw Error("Expect <checker.key-locator.hyper-relation.k-regex>!");
217
218 std::string kRegex = hPropertyIt->second.data();
219 hPropertyIt++;
220
221 // Get k-expand
222 if (hPropertyIt == hSection.end() || !boost::iequals(hPropertyIt->first, "k-expand"))
223 throw Error("Expect <checker.key-locator.hyper-relation.k-expand>!");
224
225 std::string kExpand = hPropertyIt->second.data();
226 hPropertyIt++;
227
228 // Get h-relation
229 if (hPropertyIt == hSection.end() || !boost::iequals(hPropertyIt->first, "h-relation"))
230 throw Error("Expect <checker.key-locator.hyper-relation.h-relation>!");
231
232 std::string hRelation = hPropertyIt->second.data();
233 hPropertyIt++;
234
235 // Get p-regex
236 if (hPropertyIt == hSection.end() || !boost::iequals(hPropertyIt->first, "p-regex"))
237 throw Error("Expect <checker.key-locator.hyper-relation.p-regex>!");
238
239 std::string pRegex = hPropertyIt->second.data();
240 hPropertyIt++;
241
242 // Get p-expand
243 if (hPropertyIt == hSection.end() || !boost::iequals(hPropertyIt->first, "p-expand"))
244 throw Error("Expect <checker.key-locator.hyper-relation.p-expand>!");
245
246 std::string pExpand = hPropertyIt->second.data();
247 hPropertyIt++;
248
249 if (hPropertyIt != hSection.end())
250 throw Error("Expect the end of checker.key-locator.hyper-relation!");
251
252 KeyLocatorChecker::Relation relation;
253 if (boost::iequals(hRelation, "equal"))
254 relation = KeyLocatorChecker::RELATION_EQUAL;
255 else if (boost::iequals(hRelation, "is-prefix-of"))
256 relation = KeyLocatorChecker::RELATION_IS_PREFIX_OF;
257 else if (boost::iequals(hRelation, "is-strict-prefix-of"))
258 relation = KeyLocatorChecker::RELATION_IS_STRICT_PREFIX_OF;
259 else
260 throw Error("Unsupported checker.key-locator.hyper-relation.h-relation: " + hRelation);
261
262 try {
263 return shared_ptr<HyperKeyLocatorNameChecker>
264 (new HyperKeyLocatorNameChecker(pRegex, pExpand,
265 kRegex, kExpand,
266 relation));
267 }
268 catch (ndn::Regex::Error& e) {
269 throw Error("Invalid regex for key-locator.hyper-relation");
270 }
271 }
272 else
273 throw Error("Unsupported checker.key-locator");
274}
275
276} // namespace conf
277} // namespace nsl