26 #include <boost/algorithm/string/predicate.hpp>
27 #include <boost/lexical_cast.hpp>
28 #include <boost/property_tree/info_parser.hpp>
38 std::ifstream inputFile(filename);
40 NDN_THROW(
Error(
"Failed to read configuration file: " + filename));
42 load(inputFile, filename);
48 std::istringstream inputStream(input);
49 load(inputStream, filename);
57 boost::property_tree::read_info(input, tree);
59 catch (
const boost::property_tree::info_parser_error& e) {
61 " line " +
to_string(e.line()) +
": " + e.message()));
69 BOOST_ASSERT(!filename.empty());
75 m_shouldBypass =
false;
77 m_interestRules.clear();
81 m_isConfigured =
true;
83 for (
const auto& subSection : configSection) {
84 const std::string& sectionName = subSection.first;
87 if (boost::iequals(sectionName,
"rule")) {
90 m_dataRules.push_back(std::move(rule));
93 m_interestRules.push_back(std::move(rule));
96 else if (boost::iequals(sectionName,
"trust-anchor")) {
97 processConfigTrustAnchor(section, filename);
100 NDN_THROW(
Error(
"Error processing configuration file " + filename +
101 ": unrecognized section " + sectionName));
107 ValidationPolicyConfig::processConfigTrustAnchor(
const ConfigSection& configSection,
108 const std::string& filename)
110 auto propertyIt = configSection.begin();
113 if (propertyIt == configSection.end() || !boost::iequals(propertyIt->first,
"type")) {
117 auto baseDir = std::filesystem::absolute(filename).parent_path().lexically_normal();
118 std::string type = propertyIt->second.data();
121 if (boost::iequals(type,
"file")) {
123 if (propertyIt == configSection.end() || !boost::iequals(propertyIt->first,
"file-name")) {
124 NDN_THROW(Error(
"Expecting <trust-anchor.file-name>"));
127 std::string file = propertyIt->second.data();
131 if (propertyIt != configSection.end())
132 NDN_THROW(Error(
"Expecting end of <trust-anchor>"));
136 else if (boost::iequals(type,
"base64")) {
138 if (propertyIt == configSection.end() || !boost::iequals(propertyIt->first,
"base64-string"))
139 NDN_THROW(Error(
"Expecting <trust-anchor.base64-string>"));
141 std::stringstream ss(propertyIt->second.data());
144 if (propertyIt != configSection.end())
145 NDN_THROW(Error(
"Expecting end of <trust-anchor>"));
147 auto idCert = io::load<Certificate>(ss);
148 if (idCert !=
nullptr) {
152 NDN_THROW(Error(
"Cannot decode certificate from base64-string"));
155 else if (boost::iequals(type,
"dir")) {
156 if (propertyIt == configSection.end() || !boost::iequals(propertyIt->first,
"dir"))
157 NDN_THROW(Error(
"Expecting <trust-anchor.dir>"));
159 std::string dirString(propertyIt->second.data());
163 if (propertyIt != configSection.end())
164 NDN_THROW(Error(
"Expecting end of <trust-anchor>"));
168 else if (boost::iequals(type,
"any")) {
169 m_shouldBypass =
true;
172 NDN_THROW(Error(
"Unrecognized <trust-anchor.type>: " + type));
177 ValidationPolicyConfig::getRefreshPeriod(ConfigSection::const_iterator& it,
178 const ConfigSection::const_iterator& end)
180 auto refresh = time::nanoseconds::max();
185 if (!boost::iequals(it->first,
"refresh")) {
186 NDN_THROW(Error(
"Expecting <trust-anchor.refresh>"));
189 std::string inputString = it->second.data();
191 char unit = inputString[inputString.size() - 1];
192 std::string refreshString = inputString.substr(0, inputString.size() - 1);
194 int32_t refreshPeriod = -1;
196 refreshPeriod = boost::lexical_cast<int32_t>(refreshString);
198 catch (
const boost::bad_lexical_cast&) {
201 if (refreshPeriod < 0) {
202 NDN_THROW(Error(
"Bad refresh value: " + refreshString));
205 if (refreshPeriod == 0) {
206 return getDefaultRefreshPeriod();
217 NDN_THROW(Error(
"Bad refresh time unit: "s + unit));
222 ValidationPolicyConfig::getDefaultRefreshPeriod()
231 BOOST_ASSERT_MSG(!
hasInnerPolicy(),
"ValidationPolicyConfig must be a terminal inner policy");
233 if (m_shouldBypass) {
234 return continueValidation(
nullptr, state);
238 if (!state->getOutcome()) {
244 for (
const auto& rule : m_dataRules) {
247 return continueValidation(make_shared<CertificateRequest>(klName), state);
255 "No rule matched for data `" + data.
getName().toUri() +
"`"});
262 BOOST_ASSERT_MSG(!
hasInnerPolicy(),
"ValidationPolicyConfig must be a terminal inner policy");
264 if (m_shouldBypass) {
265 return continueValidation(
nullptr, state);
269 if (!state->getOutcome()) {
274 if (!state->getOutcome()) {
280 for (
const auto& rule : m_interestRules) {
283 return continueValidation(make_shared<CertificateRequest>(klName), state);
291 "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
Get the Interest name.
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 loadAnchor(const std::string &groupId, Certificate &&cert)
Load static trust anchor.
void resetVerifiedCertificates()
Remove any cached verified certificates.
void resetAnchors()
Remove any previously loaded static or dynamic 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
SignatureInfo getSignatureInfo(const Interest &interest, ValidationState &state)
Extract SignatureInfo from a signed Interest.
Name getKeyLocatorName(const SignatureInfo &si, ValidationState &state)
Extract the KeyLocator name from a SignatureInfo element.
::boost::chrono::seconds seconds
::boost::chrono::minutes minutes
::boost::chrono::nanoseconds nanoseconds
::boost::chrono::hours hours
SignatureTypeValue
SignatureType values.