26 #include <boost/algorithm/string/predicate.hpp>
27 #include <boost/filesystem/operations.hpp>
28 #include <boost/filesystem/path.hpp>
29 #include <boost/lexical_cast.hpp>
30 #include <boost/property_tree/info_parser.hpp>
37 namespace validator_config {
42 std::ifstream inputFile(filename);
44 NDN_THROW(
Error(
"Failed to read configuration file: " + filename));
46 load(inputFile, filename);
52 std::istringstream inputStream(input);
53 load(inputStream, filename);
61 boost::property_tree::read_info(input, tree);
63 catch (
const boost::property_tree::info_parser_error& e) {
65 " line " +
to_string(e.line()) +
": " + e.message()));
73 BOOST_ASSERT(!filename.empty());
79 m_shouldBypass =
false;
81 m_interestRules.clear();
85 m_isConfigured =
true;
87 for (
const auto& subSection : configSection) {
88 const std::string& sectionName = subSection.first;
91 if (boost::iequals(sectionName,
"rule")) {
94 m_dataRules.push_back(std::move(rule));
97 m_interestRules.push_back(std::move(rule));
100 else if (boost::iequals(sectionName,
"trust-anchor")) {
101 processConfigTrustAnchor(section, filename);
104 NDN_THROW(
Error(
"Error processing configuration file " + filename +
105 ": unrecognized section " + sectionName));
111 ValidationPolicyConfig::processConfigTrustAnchor(
const ConfigSection& configSection,
112 const std::string& filename)
114 using namespace boost::filesystem;
116 auto propertyIt = configSection.begin();
119 if (propertyIt == configSection.end() || !boost::iequals(propertyIt->first,
"type")) {
123 std::string type = propertyIt->second.data();
126 if (boost::iequals(type,
"file")) {
128 if (propertyIt == configSection.end() || !boost::iequals(propertyIt->first,
"file-name")) {
129 NDN_THROW(Error(
"Expecting <trust-anchor.file-name>"));
132 std::string file = propertyIt->second.data();
136 if (propertyIt != configSection.end())
137 NDN_THROW(Error(
"Expecting end of <trust-anchor>"));
142 else if (boost::iequals(type,
"base64")) {
144 if (propertyIt == configSection.end() || !boost::iequals(propertyIt->first,
"base64-string"))
145 NDN_THROW(Error(
"Expecting <trust-anchor.base64-string>"));
147 std::stringstream ss(propertyIt->second.data());
150 if (propertyIt != configSection.end())
151 NDN_THROW(Error(
"Expecting end of <trust-anchor>"));
153 auto idCert = io::load<Certificate>(ss);
154 if (idCert !=
nullptr) {
158 NDN_THROW(Error(
"Cannot decode certificate from base64-string"));
161 else if (boost::iequals(type,
"dir")) {
162 if (propertyIt == configSection.end() || !boost::iequals(propertyIt->first,
"dir"))
163 NDN_THROW(Error(
"Expecting <trust-anchor.dir>"));
165 std::string dirString(propertyIt->second.data());
169 if (propertyIt != configSection.end())
170 NDN_THROW(Error(
"Expecting end of <trust-anchor>"));
172 path dirPath = absolute(dirString, path(filename).parent_path());
175 else if (boost::iequals(type,
"any")) {
176 m_shouldBypass =
true;
179 NDN_THROW(Error(
"Unrecognized <trust-anchor.type>: " + type));
184 ValidationPolicyConfig::getRefreshPeriod(ConfigSection::const_iterator& it,
185 const ConfigSection::const_iterator& end)
187 auto refresh = time::nanoseconds::max();
192 if (!boost::iequals(it->first,
"refresh")) {
193 NDN_THROW(Error(
"Expecting <trust-anchor.refresh>"));
196 std::string inputString = it->second.data();
198 char unit = inputString[inputString.size() - 1];
199 std::string refreshString = inputString.substr(0, inputString.size() - 1);
201 int32_t refreshPeriod = -1;
203 refreshPeriod = boost::lexical_cast<int32_t>(refreshString);
205 catch (
const boost::bad_lexical_cast&) {
208 if (refreshPeriod < 0) {
209 NDN_THROW(Error(
"Bad refresh value: " + refreshString));
212 if (refreshPeriod == 0) {
213 return getDefaultRefreshPeriod();
224 NDN_THROW(Error(
"Bad refresh time unit: "s + unit));
229 ValidationPolicyConfig::getDefaultRefreshPeriod()
238 BOOST_ASSERT_MSG(!
hasInnerPolicy(),
"ValidationPolicyConfig must be a terminal inner policy");
240 if (m_shouldBypass) {
241 return continueValidation(
nullptr, state);
245 if (!state->getOutcome()) {
251 for (
const auto& rule : m_dataRules) {
254 return continueValidation(make_shared<CertificateRequest>(klName), state);
262 "No rule matched for data `" + data.
getName().toUri() +
"`"});
269 BOOST_ASSERT_MSG(!
hasInnerPolicy(),
"ValidationPolicyConfig must be a terminal inner policy");
271 if (m_shouldBypass) {
272 return continueValidation(
nullptr, state);
276 if (!state->getOutcome()) {
281 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() +
"`"});
Represents a Data packet.
int32_t getSignatureType() const noexcept
Get the SignatureType.
const SignatureInfo & getSignatureInfo() const noexcept
Get the SignatureInfo element.
const Name & getName() const noexcept
Get the data name.
Represents an Interest packet.
const Name & getName() const noexcept
Represents an absolute name.
@ POLICY_ERROR
The packet violates the validation rules enforced by the policy.
std::function< void(const shared_ptr< CertificateRequest > &certRequest, const shared_ptr< ValidationState > &state)> ValidationContinuation
bool hasInnerPolicy() const
Check if inner policy is set.
void resetAnchors()
Remove any previously loaded static or dynamic trust anchor.
void resetVerifiedCertificates()
Remove any cached verified certificates.
void loadAnchor(const std::string &groupId, Certificate &&cert)
Load static trust anchor.
static unique_ptr< Rule > create(const ConfigSection &configSection, const std::string &configFilename)
Create a rule from configuration section.
void load(const std::string &filename)
Load policy from file filename.
void checkPolicy(const Data &data, const shared_ptr< ValidationState > &state, const ValidationContinuation &continueValidation) override
Check data against the policy.
std::string to_string(const errinfo_stacktrace &x)
boost::property_tree::ptree ConfigSection
Name getKeyLocatorName(const SignatureInfo &si, ValidationState &state)
Extract the KeyLocator name from a SignatureInfo element.
SignatureInfo getSignatureInfo(const Interest &interest, ValidationState &state)
Extract SignatureInfo from a signed Interest.
boost::chrono::minutes minutes
boost::chrono::nanoseconds nanoseconds
boost::chrono::hours hours
boost::chrono::seconds seconds
SignatureTypeValue
SignatureType values.