blob: eb765724413c92aaa54bd8274d29fa5856e1e86a [file] [log] [blame]
Steve DiBenedetto2c2b8892014-02-27 11:46:48 -07001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2/**
3 * Copyright (C) 2014 Named Data Networking Project
4 * See COPYING for copyright and distribution information.
5 */
6
7#include "command-validator.hpp"
Steve DiBenedettobf6a93d2014-03-21 14:03:02 -06008#include "core/logger.hpp"
9
Steve DiBenedetto2c2b8892014-02-27 11:46:48 -070010#include <ndn-cpp-dev/util/io.hpp>
11#include <ndn-cpp-dev/security/identity-certificate.hpp>
12
Steve DiBenedetto1a3c6732014-03-13 06:44:05 -060013#include <boost/filesystem.hpp>
14
Steve DiBenedetto2c2b8892014-02-27 11:46:48 -070015namespace nfd {
16
17NFD_LOG_INIT("CommandValidator");
18
19CommandValidator::CommandValidator()
20{
21
22}
23
24CommandValidator::~CommandValidator()
25{
26
27}
28
29void
30CommandValidator::setConfigFile(ConfigFile& configFile)
31{
32 configFile.addSectionHandler("authorizations",
Steve DiBenedetto1a3c6732014-03-13 06:44:05 -060033 bind(&CommandValidator::onConfig, this, _1, _2, _3));
Steve DiBenedetto2c2b8892014-02-27 11:46:48 -070034}
35
36static inline void
37aggregateErrors(std::stringstream& ss, const std::string& msg)
38{
39 if (!ss.str().empty())
40 {
41 ss << "\n";
42 }
43 ss << msg;
44}
45
46void
47CommandValidator::onConfig(const ConfigSection& section,
Steve DiBenedetto1a3c6732014-03-13 06:44:05 -060048 bool isDryRun,
49 const std::string& filename)
Steve DiBenedetto2c2b8892014-02-27 11:46:48 -070050{
Steve DiBenedetto1a3c6732014-03-13 06:44:05 -060051 using namespace boost::filesystem;
52
Steve DiBenedetto2c2b8892014-02-27 11:46:48 -070053 const ConfigSection EMPTY_SECTION;
54
55 if (section.begin() == section.end())
56 {
57 throw ConfigFile::Error("No authorize sections found");
58 }
59
60 std::stringstream dryRunErrors;
61 ConfigSection::const_iterator authIt;
62 for (authIt = section.begin(); authIt != section.end(); authIt++)
63 {
Steve DiBenedetto1a3c6732014-03-13 06:44:05 -060064 std::string certfile;
Steve DiBenedetto2c2b8892014-02-27 11:46:48 -070065 try
66 {
Steve DiBenedetto1a3c6732014-03-13 06:44:05 -060067 certfile = authIt->second.get<std::string>("certfile");
Steve DiBenedetto2c2b8892014-02-27 11:46:48 -070068 }
69 catch (const std::runtime_error& e)
70 {
Steve DiBenedetto1a3c6732014-03-13 06:44:05 -060071 std::string msg = "No certfile specified";
Steve DiBenedetto2c2b8892014-02-27 11:46:48 -070072 if (!isDryRun)
73 {
74 throw ConfigFile::Error(msg);
75 }
76 aggregateErrors(dryRunErrors, msg);
77 continue;
78 }
79
Steve DiBenedetto1a3c6732014-03-13 06:44:05 -060080 path certfilePath = absolute(certfile, path(filename).parent_path());
81 NFD_LOG_DEBUG("generated certfile path: " << certfilePath.native());
82
Steve DiBenedetto2c2b8892014-02-27 11:46:48 -070083 std::ifstream in;
Steve DiBenedetto1a3c6732014-03-13 06:44:05 -060084 in.open(certfilePath.c_str());
Steve DiBenedetto2c2b8892014-02-27 11:46:48 -070085 if (!in.is_open())
86 {
Steve DiBenedetto1a3c6732014-03-13 06:44:05 -060087 std::string msg = "Unable to open certificate file " + certfilePath.native();
Steve DiBenedetto2c2b8892014-02-27 11:46:48 -070088 if (!isDryRun)
89 {
90 throw ConfigFile::Error(msg);
91 }
92 aggregateErrors(dryRunErrors, msg);
93 continue;
94 }
95
96 shared_ptr<ndn::IdentityCertificate> id;
97 try
98 {
99 id = ndn::io::load<ndn::IdentityCertificate>(in);
100 }
101 catch(const std::runtime_error& error)
102 {
Steve DiBenedetto1a3c6732014-03-13 06:44:05 -0600103 std::string msg = "Malformed certificate file " + certfilePath.native();
Steve DiBenedetto2c2b8892014-02-27 11:46:48 -0700104 if (!isDryRun)
105 {
106 throw ConfigFile::Error(msg);
107 }
108 aggregateErrors(dryRunErrors, msg);
109 continue;
110 }
111
112 in.close();
113
114 const ConfigSection* privileges = 0;
115
116 try
117 {
118 privileges = &authIt->second.get_child("privileges");
119 }
120 catch (const std::runtime_error& error)
121 {
Steve DiBenedetto1a3c6732014-03-13 06:44:05 -0600122 std::string msg = "No privileges section found for certificate file " +
123 certfile + " (" + id->getPublicKeyName().toUri() + ")";
Steve DiBenedetto2c2b8892014-02-27 11:46:48 -0700124 if (!isDryRun)
125 {
126 throw ConfigFile::Error(msg);
127 }
128 aggregateErrors(dryRunErrors, msg);
129 continue;
130 }
131
132 if (privileges->begin() == privileges->end())
133 {
Steve DiBenedetto1a3c6732014-03-13 06:44:05 -0600134 NFD_LOG_WARN("No privileges specified for certificate file " << certfile
135 << " (" << id->getPublicKeyName().toUri() << ")");
Steve DiBenedetto2c2b8892014-02-27 11:46:48 -0700136 }
137
138 ConfigSection::const_iterator privIt;
139 for (privIt = privileges->begin(); privIt != privileges->end(); privIt++)
140 {
141 const std::string& privilegeName = privIt->first;
142 if (m_supportedPrivileges.find(privilegeName) != m_supportedPrivileges.end())
143 {
144 NFD_LOG_INFO("Giving privilege \"" << privilegeName
Steve DiBenedetto1a3c6732014-03-13 06:44:05 -0600145 << "\" to identity " << id->getPublicKeyName());
Steve DiBenedetto2c2b8892014-02-27 11:46:48 -0700146 if (!isDryRun)
147 {
148 const std::string regex = "^<localhost><nfd><" + privilegeName + ">";
149 m_validator.addInterestRule(regex, *id);
150 }
151 }
152 else
153 {
154 // Invalid configuration
Steve DiBenedetto1a3c6732014-03-13 06:44:05 -0600155 std::string msg = "Invalid privilege \"" + privilegeName + "\" for certificate file " +
156 certfile + " (" + id->getPublicKeyName().toUri() + ")";
Steve DiBenedetto2c2b8892014-02-27 11:46:48 -0700157 if (!isDryRun)
158 {
159 throw ConfigFile::Error(msg);
160 }
161 aggregateErrors(dryRunErrors, msg);
162 }
163 }
164 }
165
166 if (!dryRunErrors.str().empty())
167 {
168 throw ConfigFile::Error(dryRunErrors.str());
169 }
170}
171
172void
173CommandValidator::addSupportedPrivilege(const std::string& privilege)
174{
175 if (m_supportedPrivileges.find(privilege) != m_supportedPrivileges.end())
176 {
Steve DiBenedetto1a3c6732014-03-13 06:44:05 -0600177 throw CommandValidator::Error("Duplicated privilege: " + privilege);
Steve DiBenedetto2c2b8892014-02-27 11:46:48 -0700178 }
179 m_supportedPrivileges.insert(privilege);
180}
181
182} // namespace nfd