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>
39 std::ifstream inputFile(filename);
41 NDN_THROW(
Error(
"Failed to read configuration file: " + filename));
43 load(inputFile, filename);
49 std::istringstream inputStream(input);
50 load(inputStream, filename);
58 boost::property_tree::read_info(input, tree);
60 catch (
const boost::property_tree::info_parser_error& e) {
62 " line " +
to_string(e.line()) +
": " + e.message()));
70 BOOST_ASSERT(!filename.empty());
76 m_shouldBypass =
false;
78 m_interestRules.clear();
82 m_isConfigured =
true;
84 for (
const auto& subSection : configSection) {
85 const std::string& sectionName = subSection.first;
88 if (boost::iequals(sectionName,
"rule")) {
91 m_dataRules.push_back(std::move(rule));
94 m_interestRules.push_back(std::move(rule));
97 else if (boost::iequals(sectionName,
"trust-anchor")) {
98 processConfigTrustAnchor(section, filename);
101 NDN_THROW(
Error(
"Error processing configuration file " + filename +
102 ": unrecognized section " + sectionName));
108 ValidationPolicyConfig::processConfigTrustAnchor(
const ConfigSection& configSection,
109 const std::string& filename)
111 using namespace boost::filesystem;
113 auto propertyIt = configSection.begin();
116 if (propertyIt == configSection.end() || !boost::iequals(propertyIt->first,
"type")) {
120 std::string type = propertyIt->second.data();
123 if (boost::iequals(type,
"file")) {
125 if (propertyIt == configSection.end() || !boost::iequals(propertyIt->first,
"file-name")) {
126 NDN_THROW(Error(
"Expecting <trust-anchor.file-name>"));
129 std::string file = propertyIt->second.data();
133 if (propertyIt != configSection.end())
134 NDN_THROW(Error(
"Expecting end of <trust-anchor>"));
139 else if (boost::iequals(type,
"base64")) {
141 if (propertyIt == configSection.end() || !boost::iequals(propertyIt->first,
"base64-string"))
142 NDN_THROW(Error(
"Expecting <trust-anchor.base64-string>"));
144 std::stringstream ss(propertyIt->second.data());
147 if (propertyIt != configSection.end())
148 NDN_THROW(Error(
"Expecting end of <trust-anchor>"));
150 auto idCert = io::load<Certificate>(ss);
151 if (idCert !=
nullptr) {
155 NDN_THROW(Error(
"Cannot decode certificate from base64-string"));
158 else if (boost::iequals(type,
"dir")) {
159 if (propertyIt == configSection.end() || !boost::iequals(propertyIt->first,
"dir"))
160 NDN_THROW(Error(
"Expecting <trust-anchor.dir>"));
162 std::string dirString(propertyIt->second.data());
166 if (propertyIt != configSection.end())
167 NDN_THROW(Error(
"Expecting end of <trust-anchor>"));
169 path dirPath = absolute(dirString, path(filename).parent_path());
172 else if (boost::iequals(type,
"any")) {
173 m_shouldBypass =
true;
176 NDN_THROW(Error(
"Unrecognized <trust-anchor.type>: " + type));
181 ValidationPolicyConfig::getRefreshPeriod(ConfigSection::const_iterator& it,
182 const ConfigSection::const_iterator& end)
184 auto refresh = time::nanoseconds::max();
189 if (!boost::iequals(it->first,
"refresh")) {
190 NDN_THROW(Error(
"Expecting <trust-anchor.refresh>"));
193 std::string inputString = it->second.data();
195 char unit = inputString[inputString.size() - 1];
196 std::string refreshString = inputString.substr(0, inputString.size() - 1);
198 int32_t refreshPeriod = -1;
200 refreshPeriod = boost::lexical_cast<int32_t>(refreshString);
202 catch (
const boost::bad_lexical_cast&) {
205 if (refreshPeriod < 0) {
206 NDN_THROW(Error(
"Bad refresh value: " + refreshString));
209 if (refreshPeriod == 0) {
210 return getDefaultRefreshPeriod();
221 NDN_THROW(Error(
"Bad refresh time unit: "s + unit));
226 ValidationPolicyConfig::getDefaultRefreshPeriod()
235 BOOST_ASSERT_MSG(!
hasInnerPolicy(),
"ValidationPolicyConfig must be a terminal inner policy");
237 if (m_shouldBypass) {
238 return continueValidation(
nullptr, state);
242 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()) {
278 if (!state->getOutcome()) {
284 for (
const auto& rule : m_interestRules) {
287 return continueValidation(make_shared<CertificateRequest>(klName), state);
295 "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.