29 #include <ndn-cxx/security/identity-certificate.hpp>
30 #include <ndn-cxx/security/validator-null.hpp>
31 #include <ndn-cxx/util/io.hpp>
33 #include <boost/filesystem.hpp>
41 shared_ptr<CommandAuthenticator>
47 CommandAuthenticator::CommandAuthenticator()
48 : m_validator(make_unique<
ndn::ValidatorNull>())
56 bind(&CommandAuthenticator::processConfig,
this, _1, _2, _3));
60 CommandAuthenticator::processConfig(
const ConfigSection& section,
bool isDryRun,
const std::string& filename)
64 for (
auto& kv : m_moduleAuth) {
65 kv.second.allowAny =
false;
66 kv.second.certs.clear();
70 if (section.empty()) {
71 BOOST_THROW_EXCEPTION(ConfigFile::Error(
"'authorize' is missing under 'authorizations'"));
74 int authSectionIndex = 0;
75 for (
const auto& kv : section) {
76 if (kv.first !=
"authorize") {
77 BOOST_THROW_EXCEPTION(ConfigFile::Error(
78 "'" + kv.first +
"' section is not permitted under 'authorizations'"));
84 certfile = authSection.get<std::string>(
"certfile");
86 catch (
const boost::property_tree::ptree_error&) {
87 BOOST_THROW_EXCEPTION(ConfigFile::Error(
88 "'certfile' is missing under authorize[" + to_string(authSectionIndex) +
"]"));
92 shared_ptr<ndn::IdentityCertificate> cert;
93 if (certfile ==
"any") {
95 NFD_LOG_WARN(
"'certfile any' is intended for demo purposes only and "
96 "SHOULD NOT be used in production environments");
99 using namespace boost::filesystem;
100 path certfilePath = absolute(certfile, path(filename).parent_path());
101 cert = ndn::io::load<ndn::IdentityCertificate>(certfilePath.string());
102 if (cert ==
nullptr) {
103 BOOST_THROW_EXCEPTION(ConfigFile::Error(
104 "cannot load certfile " + certfilePath.string() +
105 " for authorize[" + to_string(authSectionIndex) +
"]"));
111 privSection = &authSection.get_child(
"privileges");
113 catch (
const boost::property_tree::ptree_error&) {
114 BOOST_THROW_EXCEPTION(ConfigFile::Error(
115 "'privileges' is missing under authorize[" + to_string(authSectionIndex) +
"]"));
118 if (privSection->empty()) {
119 NFD_LOG_WARN(
"No privileges granted to certificate " << certfile);
121 for (
const auto& kv : *privSection) {
122 const std::string& module = kv.first;
123 auto found = m_moduleAuth.find(module);
124 if (found == m_moduleAuth.end()) {
125 BOOST_THROW_EXCEPTION(ConfigFile::Error(
126 "unknown module '" + module +
"' under authorize[" + to_string(authSectionIndex) +
"]"));
134 found->second.allowAny =
true;
135 NFD_LOG_INFO(
"authorize module=" << module <<
" signer=any");
138 const Name& keyName = cert->getPublicKeyName();
139 found->second.certs.emplace(keyName, cert->getPublicKeyInfo());
140 NFD_LOG_INFO(
"authorize module=" << module <<
" signer=" << keyName <<
141 " certfile=" << certfile);
149 ndn::mgmt::Authorization
152 m_moduleAuth[module];
154 auto self = this->shared_from_this();
155 return [=] (
const Name& prefix,
const Interest& interest,
156 const ndn::mgmt::ControlParameters* params,
157 const ndn::mgmt::AcceptContinuation& accept,
158 const ndn::mgmt::RejectContinuation& reject) {
159 const AuthorizedCerts& authorized =
self->m_moduleAuth.at(module);
160 if (authorized.allowAny) {
161 NFD_LOG_DEBUG(
"accept " << interest.getName() <<
" allowAny");
168 std::tie(isOk, keyName) = CommandAuthenticator::extractKeyName(interest);
170 NFD_LOG_DEBUG(
"reject " << interest.getName() <<
" bad-KeyLocator");
171 reject(ndn::mgmt::RejectReply::SILENT);
175 auto found = authorized.certs.find(keyName);
176 if (found == authorized.certs.end()) {
177 NFD_LOG_DEBUG(
"reject " << interest.getName() <<
" signer=" << keyName <<
" not-authorized");
178 reject(ndn::mgmt::RejectReply::STATUS403);
182 bool hasGoodSig = ndn::Validator::verifySignature(interest, found->second);
184 NFD_LOG_DEBUG(
"reject " << interest.getName() <<
" signer=" << keyName <<
" bad-sig");
185 reject(ndn::mgmt::RejectReply::STATUS403);
189 self->m_validator.validate(interest,
191 NFD_LOG_DEBUG(
"accept " << interest.getName() <<
" signer=" << keyName);
192 accept(keyName.toUri());
195 NFD_LOG_DEBUG(
"reject " << interest.getName() <<
" signer=" << keyName <<
" invalid-timestamp");
196 reject(ndn::mgmt::RejectReply::STATUS403);
201 std::pair<bool, Name>
202 CommandAuthenticator::extractKeyName(
const Interest& interest)
204 const Name& name = interest.getName();
205 if (name.size() < ndn::signed_interest::MIN_LENGTH) {
206 return {
false, Name()};
209 ndn::SignatureInfo sig;
211 sig.wireDecode(name[ndn::signed_interest::POS_SIG_INFO].blockFromValue());
213 catch (
const tlv::Error&) {
214 return {
false, Name()};
217 if (!sig.hasKeyLocator()) {
218 return {
false, Name()};
221 const ndn::KeyLocator& keyLocator = sig.getKeyLocator();
222 if (keyLocator.getType() != ndn::KeyLocator::KeyLocator_Name) {
223 return {
false, Name()};
227 return {
true, ndn::IdentityCertificate::certificateNameToPublicKeyName(keyLocator.getName())};
229 catch (
const ndn::IdentityCertificate::Error&) {
230 return {
false, Name()};
Copyright (c) 2014-2016, Regents of the University of California, Arizona Board of Regents...
void addSectionHandler(const std::string §ionName, ConfigSectionHandler subscriber)
setup notification of configuration file sections
#define NFD_LOG_DEBUG(expression)
configuration file parsing utility
ndn::mgmt::Authorization makeAuthorization(const std::string &module, const std::string &verb)
provides ControlCommand authorization according to NFD configuration file
#define NFD_LOG_WARN(expression)
#define NFD_LOG_INFO(expression)
Copyright (c) 2014-2015, Regents of the University of California, Arizona Board of Regents...
boost::property_tree::ptree ConfigSection
static shared_ptr< CommandAuthenticator > create()
#define NFD_LOG_INIT(name)
void setConfigFile(ConfigFile &configFile)