9 #include "../util/io.hpp"
11 #include <boost/filesystem.hpp>
12 #include <boost/property_tree/info_parser.hpp>
13 #include <boost/algorithm/string.hpp>
20 const shared_ptr<CertificateCache>& certificateCache,
23 , m_stepLimit(stepLimit)
24 , m_certificateCache(certificateCache)
26 if (!static_cast<bool>(m_certificateCache))
27 m_certificateCache = make_shared<CertificateCacheTtl>(
m_face.
ioService());
31 const shared_ptr<CertificateCache>& certificateCache,
34 , m_stepLimit(stepLimit)
35 , m_certificateCache(certificateCache)
37 if (!static_cast<bool>(m_certificateCache))
38 m_certificateCache = make_shared<CertificateCacheTtl>(
m_face.
ioService());
45 std::ifstream inputFile;
46 inputFile.open(filename.c_str());
47 if (!inputFile.good() || !inputFile.is_open())
49 std::string msg =
"Failed to read configuration file: ";
53 load(inputFile, filename);
60 std::istringstream inputStream(input);
61 load(inputStream, filename);
71 boost::property_tree::read_info(input, tree);
73 catch (boost::property_tree::info_parser_error& error)
75 std::stringstream msg;
76 msg <<
"Failed to parse configuration file";
77 msg <<
" " << filename;
78 msg <<
" " << error.message() <<
" line " << error.line();
87 const std::string& filename)
89 BOOST_ASSERT(!filename.empty());
91 if (configSection.begin() == configSection.end())
93 std::string msg =
"Error processing configuration file";
100 for (security::conf::ConfigSection::const_iterator i = configSection.begin();
101 i != configSection.end(); ++i)
103 const std::string& sectionName = i->first;
106 if (boost::iequals(sectionName,
"rule"))
108 onConfigRule(section, filename);
110 else if (boost::iequals(sectionName,
"trust-anchor"))
112 onConfigTrustAnchor(section, filename);
116 std::string msg =
"Error processing configuration file";
119 msg +=
" unrecognized section: " + sectionName;
127 const std::string& filename)
129 using namespace ndn::security::conf;
131 ConfigSection::const_iterator propertyIt = configSection.begin();
134 if (propertyIt == configSection.end() || !boost::iequals(propertyIt->first,
"id"))
135 throw Error(
"Expect <rule.id>!");
137 std::string ruleId = propertyIt->second.data();
141 if (propertyIt == configSection.end() || !boost::iequals(propertyIt->first,
"for"))
142 throw Error(
"Expect <rule.for> in rule: " + ruleId +
"!");
144 std::string usage = propertyIt->second.data();
148 if (boost::iequals(usage,
"data"))
150 else if (boost::iequals(usage,
"interest"))
153 throw Error(
"Unrecognized <rule.for>: " + usage
154 +
" in rule: " + ruleId);
157 std::vector<shared_ptr<Filter> > filters;
158 for (; propertyIt != configSection.end(); propertyIt++)
160 if (!boost::iequals(propertyIt->first,
"filter"))
162 if (boost::iequals(propertyIt->first,
"checker"))
164 throw Error(
"Expect <rule.filter> in rule: " + ruleId);
167 filters.push_back(FilterFactory::create(propertyIt->second));
172 std::vector<shared_ptr<Checker> > checkers;
173 for (; propertyIt != configSection.end(); propertyIt++)
175 if (!boost::iequals(propertyIt->first,
"checker"))
176 throw Error(
"Expect <rule.checker> in rule: " + ruleId);
178 checkers.push_back(CheckerFactory::create(propertyIt->second, filename));
183 if (propertyIt != configSection.end())
184 throw Error(
"Expect the end of rule: " + ruleId);
186 if (checkers.size() == 0)
187 throw Error(
"No <rule.checker> is specified in rule: " + ruleId);
191 shared_ptr<DataRule> rule(
new DataRule(ruleId));
192 for (
size_t i = 0; i < filters.size(); i++)
193 rule->addFilter(filters[i]);
194 for (
size_t i = 0; i < checkers.size(); i++)
195 rule->addChecker(checkers[i]);
197 m_dataRules.push_back(rule);
201 shared_ptr<InterestRule> rule(
new InterestRule(ruleId));
202 for (
size_t i = 0; i < filters.size(); i++)
203 rule->addFilter(filters[i]);
204 for (
size_t i = 0; i < checkers.size(); i++)
205 rule->addChecker(checkers[i]);
207 m_interestRules.push_back(rule);
213 const std::string& filename)
215 using namespace ndn::security::conf;
216 using namespace boost::filesystem;
218 ConfigSection::const_iterator propertyIt = configSection.begin();
221 if (propertyIt == configSection.end() || !boost::iequals(propertyIt->first,
"type"))
222 throw Error(
"Expect <trust-anchor.type>!");
224 std::string type = propertyIt->second.data();
227 if (boost::iequals(type,
"file"))
230 if (propertyIt == configSection.end() || !boost::iequals(propertyIt->first,
"file-name"))
231 throw Error(
"Expect <trust-anchor.file-name>!");
233 std::string file = propertyIt->second.data();
237 if (propertyIt != configSection.end())
238 throw Error(
"Expect the end of trust-anchor!");
240 path certfilePath = absolute(file, path(filename).parent_path());
241 shared_ptr<IdentityCertificate> idCert =
242 io::load<IdentityCertificate>(certfilePath.string());
244 if (static_cast<bool>(idCert))
246 BOOST_ASSERT(idCert->getName().size() >= 1);
247 m_anchors[idCert->getName().getPrefix(-1)] = idCert;
250 throw Error(
"Cannot read certificate from file: " +
251 certfilePath.native());
255 else if (boost::iequals(type,
"base64"))
258 if (propertyIt == configSection.end() || !boost::iequals(propertyIt->first,
"base64-string"))
259 throw Error(
"Expect <trust-anchor.base64-string>!");
261 std::stringstream ss(propertyIt->second.data());
265 if (propertyIt != configSection.end())
266 throw Error(
"Expect the end of trust-anchor!");
268 shared_ptr<IdentityCertificate> idCert = io::load<IdentityCertificate>(ss);
270 if (static_cast<bool>(idCert))
272 BOOST_ASSERT(idCert->getName().size() >= 1);
273 m_anchors[idCert->getName().getPrefix(-1)] = idCert;
276 throw Error(
"Cannot decode certificate from base64-string");
281 throw Error(
"Unsupported trust-anchor.type: " + type);
289 std::vector<shared_ptr<ValidationRequest> >& nextSteps)
291 if (m_stepLimit == nSteps)
292 return onValidationFailed(data.shared_from_this(),
293 "Maximum steps of validation reached");
295 bool isMatched =
false;
296 int8_t checkResult = -1;
298 for (DataRuleList::iterator it = m_dataRules.begin();
299 it != m_dataRules.end(); it++)
301 if ((*it)->match(data))
304 checkResult = (*it)->check(data, onValidated, onValidationFailed);
310 return onValidationFailed(data.shared_from_this(),
"No rule matched!");
312 if (checkResult == 0)
315 checkSignature(data, signature, nSteps,
316 onValidated, onValidationFailed, nextSteps);
325 std::vector<shared_ptr<ValidationRequest> >& nextSteps)
327 if (m_stepLimit == nSteps)
328 return onValidationFailed(interest.shared_from_this(),
329 "Maximum steps of validation reached");
331 bool isMatched =
false;
332 int8_t checkResult = -1;
334 for (InterestRuleList::iterator it = m_interestRules.begin();
335 it != m_interestRules.end(); it++)
337 if ((*it)->match(interest))
340 checkResult = (*it)->check(interest, onValidated, onValidationFailed);
346 return onValidationFailed(interest.shared_from_this(),
"No rule matched!");
348 if (checkResult == 0)
352 Signature signature(interestName[-2].blockFromValue(),
353 interestName[-1].blockFromValue());
355 checkSignature(interest, signature, nSteps,
356 onValidated, onValidationFailed, nextSteps);
const Name & getName() const
void load(const std::string &filename)
Name getPrefix(int nComponents) const
Return a new Name with the first nComponents components of this Name.
ValidatorConfig(Face &face, const shared_ptr< CertificateCache > &certificateCache=DEFAULT_CERTIFICATE_CACHE, const int stepLimit=10)
An Interest holds a Name and other fields for an interest.
virtual void checkPolicy(const Data &data, int nSteps, const OnDataValidated &onValidated, const OnDataValidationFailed &onValidationFailed, std::vector< shared_ptr< ValidationRequest > > &nextSteps)
Check the Data against policy and return the next validation step if necessary.
function< void(const shared_ptr< const Data > &)> OnDataValidated
Callback to report a successful Data validation.
shared_ptr< boost::asio::io_service > ioService()
Get shared_ptr of the IO service object.
function< void(const shared_ptr< const Data > &, const std::string &)> OnDataValidationFailed
Callback to report a failed Data validation.
Abstraction to communicate with local or remote NDN forwarder.
static const shared_ptr< CertificateCache > DEFAULT_CERTIFICATE_CACHE
A Name holds an array of Name::Component and represents an NDN name.
const Signature & getSignature() const
function< void(const shared_ptr< const Interest > &, const std::string &)> OnInterestValidationFailed
Callback to report a failed Interest validation.
boost::property_tree::ptree ConfigSection
Validator is one of the main classes of the security library.
function< void(const shared_ptr< const Interest > &)> OnInterestValidated
Callback to report a successful Interest validation.
A Signature is storage for the signature-related information (info and value) in a Data packet...