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 {
39 : m_shouldBypass(false)
40 , m_isConfigured(false)
47 std::ifstream inputFile(filename);
49 BOOST_THROW_EXCEPTION(
Error(
"Failed to read configuration file: " + filename));
51 load(inputFile, filename);
57 std::istringstream inputStream(input);
58 load(inputStream, filename);
66 boost::property_tree::read_info(input, tree);
68 catch (
const boost::property_tree::info_parser_error& e) {
69 BOOST_THROW_EXCEPTION(
Error(
"Failed to parse configuration file " + filename +
70 " line " +
to_string(e.line()) +
": " + e.message()));
78 if (m_validator ==
nullptr) {
79 BOOST_THROW_EXCEPTION(
Error(
"Validator instance not assigned on the policy"));
82 m_shouldBypass =
false;
84 m_interestRules.clear();
85 m_validator->resetAnchors();
86 m_validator->resetVerifiedCertificates();
88 m_isConfigured =
true;
90 BOOST_ASSERT(!filename.empty());
92 if (configSection.begin() == configSection.end()) {
93 BOOST_THROW_EXCEPTION(
Error(
"Error processing configuration file " + filename +
": no data"));
96 for (
const auto& subSection : configSection) {
97 const std::string& sectionName = subSection.first;
100 if (boost::iequals(sectionName,
"rule")) {
103 m_dataRules.push_back(std::move(rule));
106 m_interestRules.push_back(std::move(rule));
109 else if (boost::iequals(sectionName,
"trust-anchor")) {
110 processConfigTrustAnchor(section, filename);
113 BOOST_THROW_EXCEPTION(
Error(
"Error processing configuration file " + filename +
114 ": unrecognized section " + sectionName));
120 ValidationPolicyConfig::processConfigTrustAnchor(
const ConfigSection& configSection,
121 const std::string& filename)
123 using namespace boost::filesystem;
125 auto propertyIt = configSection.begin();
128 if (propertyIt == configSection.end() || !boost::iequals(propertyIt->first,
"type")) {
129 BOOST_THROW_EXCEPTION(
Error(
"Expecting <trust-anchor.type>"));
132 std::string type = propertyIt->second.data();
135 if (boost::iequals(type,
"file")) {
137 if (propertyIt == configSection.end() || !boost::iequals(propertyIt->first,
"file-name")) {
138 BOOST_THROW_EXCEPTION(Error(
"Expecting <trust-anchor.file-name>"));
141 std::string file = propertyIt->second.data();
144 time::nanoseconds refresh = getRefreshPeriod(propertyIt, configSection.end());
145 if (propertyIt != configSection.end())
146 BOOST_THROW_EXCEPTION(Error(
"Expecting end of <trust-anchor>"));
148 m_validator->loadAnchor(filename, absolute(file, path(filename).parent_path()).
string(),
151 else if (boost::iequals(type,
"base64")) {
153 if (propertyIt == configSection.end() || !boost::iequals(propertyIt->first,
"base64-string"))
154 BOOST_THROW_EXCEPTION(Error(
"Expecting <trust-anchor.base64-string>"));
156 std::stringstream ss(propertyIt->second.data());
159 if (propertyIt != configSection.end())
160 BOOST_THROW_EXCEPTION(Error(
"Expecting end of <trust-anchor>"));
162 auto idCert = io::load<Certificate>(ss);
163 if (idCert !=
nullptr) {
164 m_validator->loadAnchor(
"", std::move(*idCert));
167 BOOST_THROW_EXCEPTION(Error(
"Cannot decode certificate from base64-string"));
170 else if (boost::iequals(type,
"dir")) {
171 if (propertyIt == configSection.end() || !boost::iequals(propertyIt->first,
"dir"))
172 BOOST_THROW_EXCEPTION(Error(
"Expecting <trust-anchor.dir>"));
174 std::string dirString(propertyIt->second.data());
177 time::nanoseconds refresh = getRefreshPeriod(propertyIt, configSection.end());
178 if (propertyIt != configSection.end())
179 BOOST_THROW_EXCEPTION(Error(
"Expecting end of <trust-anchor>"));
181 path dirPath = absolute(dirString, path(filename).parent_path());
182 m_validator->loadAnchor(dirString, dirPath.string(), refresh,
true);
184 else if (boost::iequals(type,
"any")) {
185 m_shouldBypass =
true;
188 BOOST_THROW_EXCEPTION(Error(
"Unrecognized <trust-anchor.type>: " + type));
193 ValidationPolicyConfig::getRefreshPeriod(ConfigSection::const_iterator& it,
194 const ConfigSection::const_iterator& end)
196 auto refresh = time::nanoseconds::max();
201 if (!boost::iequals(it->first,
"refresh")) {
202 BOOST_THROW_EXCEPTION(Error(
"Expecting <trust-anchor.refresh>"));
205 std::string inputString = it->second.data();
207 char unit = inputString[inputString.size() - 1];
208 std::string refreshString = inputString.substr(0, inputString.size() - 1);
210 int32_t refreshPeriod = -1;
212 refreshPeriod = boost::lexical_cast<int32_t>(refreshString);
214 catch (
const boost::bad_lexical_cast&) {
217 if (refreshPeriod < 0) {
218 BOOST_THROW_EXCEPTION(Error(
"Bad refresh value: " + refreshString));
221 if (refreshPeriod == 0) {
222 return getDefaultRefreshPeriod();
227 return time::hours(refreshPeriod);
229 return time::minutes(refreshPeriod);
231 return time::seconds(refreshPeriod);
233 BOOST_THROW_EXCEPTION(Error(
"Bad refresh time unit: "s + unit));
238 ValidationPolicyConfig::getDefaultRefreshPeriod()
247 BOOST_ASSERT_MSG(!
hasInnerPolicy(),
"ValidationPolicyConfig must be a terminal inner policy");
249 if (m_shouldBypass) {
250 return continueValidation(
nullptr, state);
254 if (!state->getOutcome()) {
258 for (
const auto& rule : m_dataRules) {
261 return continueValidation(make_shared<CertificateRequest>(klName), state);
269 "No rule matched for data `" + data.
getName().
toUri() +
"`"});
276 BOOST_ASSERT_MSG(!
hasInnerPolicy(),
"ValidationPolicyConfig must be a terminal inner policy");
278 if (m_shouldBypass) {
279 return continueValidation(
nullptr, state);
283 if (!state->getOutcome()) {
287 for (
const auto& rule : m_interestRules) {
290 return continueValidation(make_shared<CertificateRequest>(klName), state);
298 "No rule matched for interest `" + interest.
getName().
toUri() +
"`"});
Copyright (c) 2011-2015 Regents of the University of California.
std::string toUri() const
Get URI representation of the name.
const Name & getName() const
Get name.
static unique_ptr< Rule > create(const ConfigSection &configSection, const std::string &configFilename)
create a rule from configuration section
Represents an Interest packet.
std::function< void(const shared_ptr< CertificateRequest > &certRequest, const shared_ptr< ValidationState > &state)> ValidationContinuation
static Name getKeyLocatorName(const SignatureInfo &si, ValidationState &state)
Represents an absolute name.
boost::property_tree::ptree ConfigSection
bool hasInnerPolicy() const
Check if inner policy is set.
void checkPolicy(const Data &data, const shared_ptr< ValidationState > &state, const ValidationContinuation &continueValidation) override
Check data against the policy.
std::string to_string(const V &v)
Represents a Data packet.
void load(const std::string &filename)
Load policy from file filename.
const Name & getName() const