29 #include <ndn-cxx/tag.hpp> 30 #include <ndn-cxx/security/certificate-fetcher-offline.hpp> 31 #include <ndn-cxx/security/certificate-request.hpp> 32 #include <ndn-cxx/security/validation-policy.hpp> 33 #include <ndn-cxx/security/validation-policy-accept-all.hpp> 34 #include <ndn-cxx/security/validation-policy-command-interest.hpp> 35 #include <ndn-cxx/security/validator.hpp> 36 #include <ndn-cxx/util/io.hpp> 38 #include <boost/filesystem.hpp> 40 namespace security = ndn::security;
54 static optional<std::string>
57 shared_ptr<SignerTag> signerTag = interest.getTag<
SignerTag>();
58 if (signerTag ==
nullptr) {
62 return signerTag->get().toUri();
68 class CommandAuthenticatorValidationPolicy :
public security::ValidationPolicy
72 checkPolicy(
const Interest& interest,
const shared_ptr<security::ValidationState>& state,
73 const ValidationContinuation& continueValidation)
final 75 Name klName = getKeyLocatorName(interest, *state);
76 if (!state->getOutcome()) {
83 auto state1 = dynamic_pointer_cast<security::InterestValidationState>(state);
84 state1->getOriginalInterest().setTag(make_shared<SignerTag>(klName));
86 continueValidation(make_shared<security::CertificateRequest>(Interest(klName)), state);
90 checkPolicy(
const Data& data,
const shared_ptr<security::ValidationState>& state,
91 const ValidationContinuation& continueValidation)
final 95 BOOST_ASSERT_MSG(
false,
"Data should not be passed to this policy");
99 shared_ptr<CommandAuthenticator>
105 CommandAuthenticator::CommandAuthenticator() =
default;
111 bind(&CommandAuthenticator::processConfig,
this, _1, _2, _3));
115 CommandAuthenticator::processConfig(
const ConfigSection& section,
bool isDryRun,
const std::string& filename)
119 for (
auto& kv : m_validators) {
120 kv.second = make_shared<security::Validator>(
121 make_unique<security::ValidationPolicyCommandInterest>(make_unique<CommandAuthenticatorValidationPolicy>()),
122 make_unique<security::CertificateFetcherOffline>());
126 if (section.empty()) {
130 int authSectionIndex = 0;
131 for (
const auto& kv : section) {
132 if (kv.first !=
"authorize") {
133 NDN_THROW(
ConfigFile::Error(
"'" + kv.first +
"' section is not permitted under 'authorizations'"));
137 std::string certfile;
139 certfile = authSection.get<std::string>(
"certfile");
141 catch (
const boost::property_tree::ptree_error&) {
143 to_string(authSectionIndex) +
"]"));
147 shared_ptr<security::Certificate> cert;
148 if (certfile ==
"any") {
150 NFD_LOG_WARN(
"'certfile any' is intended for demo purposes only and " 151 "SHOULD NOT be used in production environments");
154 using namespace boost::filesystem;
155 path certfilePath = absolute(certfile, path(filename).parent_path());
156 cert = ndn::io::load<security::Certificate>(certfilePath.string());
157 if (cert ==
nullptr) {
159 " for authorize[" + to_string(authSectionIndex) +
"]"));
165 privSection = &authSection.get_child(
"privileges");
167 catch (
const boost::property_tree::ptree_error&) {
169 to_string(authSectionIndex) +
"]"));
172 if (privSection->empty()) {
173 NFD_LOG_WARN(
"No privileges granted to certificate " << certfile);
175 for (
const auto& kv : *privSection) {
176 const std::string& module = kv.first;
177 auto found = m_validators.find(module);
178 if (found == m_validators.end()) {
180 "' under authorize[" + to_string(authSectionIndex) +
"]"));
188 found->second = make_shared<security::Validator>(make_unique<security::ValidationPolicyAcceptAll>(),
189 make_unique<security::CertificateFetcherOffline>());
190 NFD_LOG_INFO(
"authorize module=" << module <<
" signer=any");
193 const Name& keyName = cert->getKeyName();
194 security::Certificate certCopy = *cert;
195 found->second->loadAnchor(certfile, std::move(certCopy));
196 NFD_LOG_INFO(
"authorize module=" << module <<
" signer=" << keyName <<
" certfile=" << certfile);
204 ndn::mgmt::Authorization
207 m_validators[module];
209 auto self = this->shared_from_this();
210 return [=] (
const Name&,
const Interest& interest,
211 const ndn::mgmt::ControlParameters*,
212 const ndn::mgmt::AcceptContinuation& accept,
213 const ndn::mgmt::RejectContinuation& reject) {
214 auto validator =
self->m_validators.at(module);
215 auto successCb = [accept, validator] (
const Interest& interest1) {
217 BOOST_ASSERT(signer1 ||
218 dynamic_cast<security::ValidationPolicyAcceptAll*>(&validator->getPolicy()) !=
nullptr);
219 std::string signer = signer1.value_or(
"*");
220 NFD_LOG_DEBUG(
"accept " << interest1.getName() <<
" signer=" << signer);
223 auto failureCb = [reject] (
const Interest& interest1,
const security::ValidationError& err) {
224 using ndn::mgmt::RejectReply;
225 RejectReply reply = RejectReply::STATUS403;
226 switch (err.getCode()) {
227 case security::ValidationError::NO_SIGNATURE:
228 case security::ValidationError::INVALID_KEY_LOCATOR:
229 reply = RejectReply::SILENT;
231 case security::ValidationError::POLICY_ERROR:
232 if (interest1.getName().size() < ndn::command_interest::MIN_SIZE) {
233 reply = RejectReply::SILENT;
237 NFD_LOG_DEBUG(
"reject " << interest1.getName() <<
" signer=" <<
243 validator->validate(interest, successCb, failureCb);
246 NFD_LOG_DEBUG(
"reject " << interest.getName() <<
" signer=" <<
248 reject(ndn::mgmt::RejectReply::STATUS403);
ndn::SimpleTag< Name, 20 > SignerTag
an Interest tag to indicate command signer
void addSectionHandler(const std::string §ionName, ConfigSectionHandler subscriber)
setup notification of configuration file sections
configuration file parsing utility
ndn::mgmt::Authorization makeAuthorization(const std::string &module, const std::string &verb)
Provides ControlCommand authorization according to NFD configuration file.
boost::property_tree::ptree ConfigSection
a config file section
Copyright (c) 2014-2015, Regents of the University of California, Arizona Board of Regents...
static optional< std::string > getSignerFromTag(const Interest &interest)
obtain signer from SignerTag attached to Interest, if available
static shared_ptr< CommandAuthenticator > create()
#define NFD_LOG_INIT(name)
void setConfigFile(ConfigFile &configFile)