26 #include <boost/algorithm/string/predicate.hpp>
27 #include <boost/filesystem.hpp>
28 #include <boost/lexical_cast.hpp>
29 #include <boost/property_tree/info_parser.hpp>
36 namespace validator_config {
41 std::ifstream inputFile(filename);
43 NDN_THROW(
Error(
"Failed to read configuration file: " + filename));
45 load(inputFile, filename);
51 std::istringstream inputStream(input);
52 load(inputStream, filename);
60 boost::property_tree::read_info(input, tree);
62 catch (
const boost::property_tree::info_parser_error& e) {
64 " line " +
to_string(e.line()) +
": " + e.message()));
72 BOOST_ASSERT(!filename.empty());
74 if (m_validator ==
nullptr) {
78 m_shouldBypass =
false;
80 m_interestRules.clear();
81 m_validator->resetAnchors();
82 m_validator->resetVerifiedCertificates();
84 m_isConfigured =
true;
86 for (
const auto& subSection : configSection) {
87 const std::string& sectionName = subSection.first;
90 if (boost::iequals(sectionName,
"rule")) {
96 m_interestRules.push_back(
std::move(rule));
99 else if (boost::iequals(sectionName,
"trust-anchor")) {
100 processConfigTrustAnchor(section, filename);
103 NDN_THROW(
Error(
"Error processing configuration file " + filename +
104 ": unrecognized section " + sectionName));
110 ValidationPolicyConfig::processConfigTrustAnchor(
const ConfigSection& configSection,
111 const std::string& filename)
113 using namespace boost::filesystem;
115 auto propertyIt = configSection.begin();
118 if (propertyIt == configSection.end() || !boost::iequals(propertyIt->first,
"type")) {
122 std::string type = propertyIt->second.data();
125 if (boost::iequals(type,
"file")) {
127 if (propertyIt == configSection.end() || !boost::iequals(propertyIt->first,
"file-name")) {
128 NDN_THROW(Error(
"Expecting <trust-anchor.file-name>"));
131 std::string file = propertyIt->second.data();
134 time::nanoseconds refresh = getRefreshPeriod(propertyIt, configSection.end());
135 if (propertyIt != configSection.end())
136 NDN_THROW(Error(
"Expecting end of <trust-anchor>"));
138 m_validator->loadAnchor(filename, absolute(file, path(filename).parent_path()).
string(),
141 else if (boost::iequals(type,
"base64")) {
143 if (propertyIt == configSection.end() || !boost::iequals(propertyIt->first,
"base64-string"))
144 NDN_THROW(Error(
"Expecting <trust-anchor.base64-string>"));
146 std::stringstream ss(propertyIt->second.data());
149 if (propertyIt != configSection.end())
150 NDN_THROW(Error(
"Expecting end of <trust-anchor>"));
152 auto idCert = io::load<Certificate>(ss);
153 if (idCert !=
nullptr) {
154 m_validator->loadAnchor(
"",
std::move(*idCert));
157 NDN_THROW(Error(
"Cannot decode certificate from base64-string"));
160 else if (boost::iequals(type,
"dir")) {
161 if (propertyIt == configSection.end() || !boost::iequals(propertyIt->first,
"dir"))
162 NDN_THROW(Error(
"Expecting <trust-anchor.dir>"));
164 std::string dirString(propertyIt->second.data());
167 time::nanoseconds refresh = getRefreshPeriod(propertyIt, configSection.end());
168 if (propertyIt != configSection.end())
169 NDN_THROW(Error(
"Expecting end of <trust-anchor>"));
171 path dirPath = absolute(dirString, path(filename).parent_path());
172 m_validator->loadAnchor(dirString, dirPath.string(), refresh,
true);
174 else if (boost::iequals(type,
"any")) {
175 m_shouldBypass =
true;
178 NDN_THROW(Error(
"Unrecognized <trust-anchor.type>: " + type));
183 ValidationPolicyConfig::getRefreshPeriod(ConfigSection::const_iterator& it,
184 const ConfigSection::const_iterator& end)
186 auto refresh = time::nanoseconds::max();
191 if (!boost::iequals(it->first,
"refresh")) {
192 NDN_THROW(Error(
"Expecting <trust-anchor.refresh>"));
195 std::string inputString = it->second.data();
197 char unit = inputString[inputString.size() - 1];
198 std::string refreshString = inputString.substr(0, inputString.size() - 1);
200 int32_t refreshPeriod = -1;
202 refreshPeriod = boost::lexical_cast<int32_t>(refreshString);
204 catch (
const boost::bad_lexical_cast&) {
207 if (refreshPeriod < 0) {
208 NDN_THROW(Error(
"Bad refresh value: " + refreshString));
211 if (refreshPeriod == 0) {
212 return getDefaultRefreshPeriod();
217 return time::hours(refreshPeriod);
219 return time::minutes(refreshPeriod);
221 return time::seconds(refreshPeriod);
223 NDN_THROW(Error(
"Bad refresh time unit: "s + unit));
228 ValidationPolicyConfig::getDefaultRefreshPeriod()
237 BOOST_ASSERT_MSG(!
hasInnerPolicy(),
"ValidationPolicyConfig must be a terminal inner policy");
239 if (m_shouldBypass) {
240 return continueValidation(
nullptr, state);
244 if (!state->getOutcome()) {
248 for (
const auto& rule : m_dataRules) {
251 return continueValidation(make_shared<CertificateRequest>(klName), state);
259 "No rule matched for data `" + data.
getName().toUri() +
"`"});
266 BOOST_ASSERT_MSG(!
hasInnerPolicy(),
"ValidationPolicyConfig must be a terminal inner policy");
268 if (m_shouldBypass) {
269 return continueValidation(
nullptr, state);
273 if (!state->getOutcome()) {
277 for (
const auto& rule : m_interestRules) {
280 return continueValidation(make_shared<CertificateRequest>(klName), state);
288 "No rule matched for interest `" + interest.
getName().toUri() +
"`"});