blob: 7d5b833c4071a8cf9fd0c0d24be78e385a596b0d [file] [log] [blame]
Yingdi Yu48e8c0c2014-03-19 12:01:55 -07001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
2/**
3 * Copyright (C) 2013 Regents of the University of California.
4 * @author: Yingdi Yu <yingdi@cs.ucla.edu>
5 * See COPYING for copyright and distribution information.
6 */
7
8#ifndef NDN_SECURITY_CONF_FILTER_HPP
9#define NDN_SECURITY_CONF_FILTER_HPP
10
11#include "../../common.hpp"
12#include "../../data.hpp"
13#include "../../interest.hpp"
14#include "../../util/regex.hpp"
15#include <boost/algorithm/string.hpp>
16
17#include "common.hpp"
18
19namespace ndn {
20namespace security {
21namespace conf {
22
23class Filter
24{
25public:
26 virtual
27 ~Filter()
28 {
29 }
30
31 virtual bool
32 match(const Data& data) = 0;
33
34 virtual bool
35 match(const Interest& interest) = 0;
36};
37
38class RelationNameFilter : public Filter
39{
40public:
41 enum Relation
42 {
43 RELATION_EQUAL,
44 RELATION_IS_PREFIX_OF,
Alexander Afanasyevb78bc4d2014-04-09 21:20:52 -070045 RELATION_IS_STRICT_PREFIX_OF
Yingdi Yu48e8c0c2014-03-19 12:01:55 -070046 };
47
48 RelationNameFilter(const Name& name, Relation relation)
49 : m_name(name)
50 , m_relation(relation)
51 {
52 }
53
54 virtual
55 ~RelationNameFilter()
56 {
57 }
58
59 virtual bool
60 match(const Data& data)
61 {
62 return match(data.getName());
63 }
64
65 virtual bool
66 match(const Interest& interest)
67 {
68 if (interest.getName().size() < 2)
69 return false;
70
71 Name signedName = interest.getName().getPrefix(-2);
72 return match(signedName);
73 }
74
75private:
76 bool
77 match(const Name& name)
78 {
79 switch (m_relation)
80 {
81 case RELATION_EQUAL:
82 return (name == m_name);
83 case RELATION_IS_PREFIX_OF:
84 return m_name.isPrefixOf(name);
85 case RELATION_IS_STRICT_PREFIX_OF:
86 return (m_name.isPrefixOf(name) && m_name != name);
87 default:
88 return false;
89 }
90 }
91
92private:
93 Name m_name;
94 Relation m_relation;
95};
96
97class RegexNameFilter : public Filter
98{
99public:
100 explicit
101 RegexNameFilter(const Regex& regex)
102 : m_regex(regex)
103 {
104 }
105
106 virtual
107 ~RegexNameFilter()
108 {
109 }
110
111 virtual bool
112 match(const Data& data)
113 {
114 return m_regex.match(data.getName());
115 }
116
117 virtual bool
118 match(const Interest& interest)
119 {
120 if (interest.getName().size() < 2)
121 return false;
122
123 Name signedName = interest.getName().getPrefix(-2);
124 return m_regex.match(signedName);
125 }
126
127private:
128 Regex m_regex;
129};
130
131class FilterFactory
132{
133public:
134 static shared_ptr<Filter>
135 create(const ConfigSection& configSection)
136 {
137 ConfigSection::const_iterator propertyIt = configSection.begin();
138
139 if (propertyIt == configSection.end() || !boost::iequals(propertyIt->first, "type"))
140 throw Error("Expect <filter.type>!");
141
142 std::string type = propertyIt->second.data();
143
144 if (boost::iequals(type, "name"))
145 return createNameFilter(configSection);
146 else
147 throw Error("Unsupported filter.type: " + type);
148 }
149private:
150 static shared_ptr<Filter>
151 createNameFilter(const ConfigSection& configSection)
152 {
153 ConfigSection::const_iterator propertyIt = configSection.begin();
154 propertyIt++;
155
156 if (propertyIt == configSection.end())
157 throw Error("Expect more properties for filter(name)");
158
159 if (boost::iequals(propertyIt->first, "name"))
160 {
161 // Get filter.name
162 Name name;
163 try
164 {
165 name = Name(propertyIt->second.data());
166 }
167 catch (Name::Error& e)
168 {
169 throw Error("Wrong filter.name: " + propertyIt->second.data());
170 }
171
172 propertyIt++;
173
174 // Get filter.relation
175 if (propertyIt == configSection.end() || !boost::iequals(propertyIt->first, "relation"))
176 throw Error("Expect <filter.relation>!");
177
178 std::string relationString = propertyIt->second.data();
179 propertyIt++;
180
181 RelationNameFilter::Relation relation;
182 if (boost::iequals(relationString, "equal"))
183 relation = RelationNameFilter::RELATION_EQUAL;
184 else if (boost::iequals(relationString, "is-prefix-of"))
185 relation = RelationNameFilter::RELATION_IS_PREFIX_OF;
186 else if (boost::iequals(relationString, "is-strict-prefix-of"))
187 relation = RelationNameFilter::RELATION_IS_STRICT_PREFIX_OF;
188 else
189 throw Error("Unsupported relation: " + relationString);
190
191
192 if (propertyIt != configSection.end())
193 throw Error("Expect the end of filter!");
194
195 return make_shared<RelationNameFilter>(boost::cref(name),
196 boost::cref(relation));
197 }
198 else if (boost::iequals(propertyIt->first, "regex"))
199 {
200 std::string regexString = propertyIt->second.data();
201 propertyIt++;
202
203 if (propertyIt != configSection.end())
204 throw Error("Expect the end of filter!");
205
206 try
207 {
208 return shared_ptr<RegexNameFilter>(new RegexNameFilter(regexString));
209 }
210 catch (const Regex::Error& e)
211 {
212 throw Error("Wrong filter.regex: " + regexString);
213 }
214 }
215 else
216 throw Error("Wrong filter(name) properties");
217 }
218};
219
220} // namespace conf
221} // namespace security
222} // namespace ndn
223
224#endif // NDN_SECURITY_CONF_FILTER_HPP