rule.cpp
Go to the documentation of this file.
1 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2 /*
3  * Copyright (c) 2013-2023 Regents of the University of California.
4  *
5  * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
6  *
7  * ndn-cxx library is free software: you can redistribute it and/or modify it under the
8  * terms of the GNU Lesser General Public License as published by the Free Software
9  * Foundation, either version 3 of the License, or (at your option) any later version.
10  *
11  * ndn-cxx library is distributed in the hope that it will be useful, but WITHOUT ANY
12  * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
13  * PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
14  *
15  * You should have received copies of the GNU General Public License and GNU Lesser
16  * General Public License along with ndn-cxx, e.g., in COPYING.md file. If not, see
17  * <http://www.gnu.org/licenses/>.
18  *
19  * See AUTHORS.md for complete list of ndn-cxx authors and contributors.
20  */
21 
24 #include "ndn-cxx/util/logger.hpp"
25 
26 #include <boost/algorithm/string/predicate.hpp>
27 
29 
31 
32 Rule::Rule(const std::string& id, uint32_t pktType)
33  : m_id(id)
34  , m_pktType(pktType)
35 {
36 }
37 
38 void
39 Rule::addFilter(unique_ptr<Filter> filter)
40 {
41  m_filters.push_back(std::move(filter));
42 }
43 
44 void
45 Rule::addChecker(unique_ptr<Checker> checker)
46 {
47  m_checkers.push_back(std::move(checker));
48 }
49 
50 bool
51 Rule::match(uint32_t pktType, const Name& pktName, const shared_ptr<ValidationState>& state) const
52 {
53  NDN_LOG_TRACE("Trying to match " << pktName);
54  if (pktType != m_pktType) {
55  NDN_THROW(Error("Invalid packet type supplied (" + to_string(pktType) +
56  " != " + to_string(m_pktType) + ")"));
57  }
58 
59  if (m_filters.empty()) {
60  return true;
61  }
62 
63  bool retval = false;
64  for (const auto& filter : m_filters) {
65  retval |= filter->match(pktType, pktName, state);
66  if (retval) {
67  break;
68  }
69  }
70  return retval;
71 }
72 
73 bool
74 Rule::check(uint32_t pktType, tlv::SignatureTypeValue sigType, const Name& pktName, const Name& klName,
75  const shared_ptr<ValidationState>& state) const
76 {
77  NDN_LOG_TRACE("Trying to check " << pktName << " with KeyLocator " << klName);
78 
79  if (pktType != m_pktType) {
80  NDN_THROW(Error("Invalid packet type supplied (" + to_string(pktType) +
81  " != " + to_string(m_pktType) + ")"));
82  }
83 
84  std::vector<Checker::Result> checkerResults;
85  checkerResults.reserve(m_checkers.size());
86  for (const auto& checker : m_checkers) {
87  auto result = checker->check(pktType, sigType, pktName, klName, *state);
88  if (result) {
89  return true;
90  }
91  checkerResults.push_back(std::move(result));
92  }
93 
94  std::ostringstream err;
95  err << "Packet " << pktName << " (KeyLocator=" << klName << ") cannot pass any checker.";
96  for (size_t i = 0; i < checkerResults.size(); ++i) {
97  err << "\nChecker " << i << ": " << checkerResults[i].getErrorMessage();
98  }
99  state->fail({ValidationError::POLICY_ERROR, err.str()});
100  return false;
101 }
102 
103 unique_ptr<Rule>
104 Rule::create(const ConfigSection& configSection, const std::string& configFilename)
105 {
106  auto propertyIt = configSection.begin();
107 
108  // Get rule.id
109  if (propertyIt == configSection.end() || !boost::iequals(propertyIt->first, "id")) {
110  NDN_THROW(Error("Expecting <rule.id>"));
111  }
112 
113  std::string ruleId = propertyIt->second.data();
114  propertyIt++;
115 
116  // Get rule.for
117  if (propertyIt == configSection.end() || !boost::iequals(propertyIt->first, "for")) {
118  NDN_THROW(Error("Expecting <rule.for> in rule: " + ruleId));
119  }
120 
121  std::string usage = propertyIt->second.data();
122  propertyIt++;
123 
124  bool isForData = false;
125  if (boost::iequals(usage, "data")) {
126  isForData = true;
127  }
128  else if (boost::iequals(usage, "interest")) {
129  isForData = false;
130  }
131  else {
132  NDN_THROW(Error("Unrecognized <rule.for>: " + usage + " in rule: " + ruleId));
133  }
134 
135  auto rule = make_unique<Rule>(ruleId, isForData ? tlv::Data : tlv::Interest);
136 
137  // Get rule.filter(s)
138  for (; propertyIt != configSection.end(); propertyIt++) {
139  if (!boost::iequals(propertyIt->first, "filter")) {
140  if (boost::iequals(propertyIt->first, "checker")) {
141  break;
142  }
143  NDN_THROW(Error("Expecting <rule.filter> in rule: " + ruleId));
144  }
145 
146  rule->addFilter(Filter::create(propertyIt->second, configFilename));
147  }
148 
149  // Get rule.checker(s)
150  bool hasCheckers = false;
151  for (; propertyIt != configSection.end(); propertyIt++) {
152  if (!boost::iequals(propertyIt->first, "checker")) {
153  NDN_THROW(Error("Expecting <rule.checker> in rule: " + ruleId));
154  }
155 
156  rule->addChecker(Checker::create(propertyIt->second, configFilename));
157  hasCheckers = true;
158  }
159 
160  if (propertyIt != configSection.end()) {
161  NDN_THROW(Error("Expecting end of <rule>: " + ruleId));
162  }
163 
164  if (!hasCheckers) {
165  NDN_THROW(Error("No <rule.checker> is specified in rule: " + ruleId));
166  }
167 
168  return rule;
169 }
170 
171 } // namespace ndn::security::validator_config
Represents an absolute name.
Definition: name.hpp:45
@ POLICY_ERROR
The packet violates the validation rules enforced by the policy.
static unique_ptr< Checker > create(const ConfigSection &configSection, const std::string &configFilename)
Create a checker from configuration section.
Definition: checker.cpp:177
static unique_ptr< Filter > create(const ConfigSection &configSection, const std::string &configFilename)
Create a filter from the configuration section.
Definition: filter.cpp:88
void addFilter(unique_ptr< Filter > filter)
Definition: rule.cpp:39
bool check(uint32_t pktType, tlv::SignatureTypeValue sigType, const Name &pktName, const Name &klName, const shared_ptr< ValidationState > &state) const
Check if packet satisfies rule's condition.
Definition: rule.cpp:74
static unique_ptr< Rule > create(const ConfigSection &configSection, const std::string &configFilename)
Create a rule from configuration section.
Definition: rule.cpp:104
Rule(const std::string &id, uint32_t pktType)
Definition: rule.cpp:32
void addChecker(unique_ptr< Checker > checker)
Definition: rule.cpp:45
bool match(uint32_t pktType, const Name &pktName, const shared_ptr< ValidationState > &state) const
Check if the packet name matches rule's filter.
Definition: rule.cpp:51
#define NDN_THROW(e)
Definition: exception.hpp:56
#define NDN_LOG_TRACE(expression)
Log at TRACE level.
Definition: logger.hpp:255
#define NDN_LOG_INIT(name)
Define a non-member log module.
Definition: logger.hpp:169
std::string to_string(const errinfo_stacktrace &x)
Definition: exception.cpp:30
boost::property_tree::ptree ConfigSection
Definition: common.hpp:33
Contains the ndn-cxx security framework.
@ Data
Definition: tlv.hpp:69
@ Interest
Definition: tlv.hpp:68
SignatureTypeValue
SignatureType values.
Definition: tlv.hpp:127
Definition: data.cpp:25