blob: fd8a124f08d65e505ed15b99e15d14d9f34fb193 [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"
8#include <ndn-cpp-dev/util/io.hpp>
9#include <ndn-cpp-dev/security/identity-certificate.hpp>
10
Steve DiBenedetto1a3c6732014-03-13 06:44:05 -060011#include <boost/filesystem.hpp>
12
Steve DiBenedetto2c2b8892014-02-27 11:46:48 -070013namespace nfd {
14
15NFD_LOG_INIT("CommandValidator");
16
17CommandValidator::CommandValidator()
18{
19
20}
21
22CommandValidator::~CommandValidator()
23{
24
25}
26
27void
28CommandValidator::setConfigFile(ConfigFile& configFile)
29{
30 configFile.addSectionHandler("authorizations",
Steve DiBenedetto1a3c6732014-03-13 06:44:05 -060031 bind(&CommandValidator::onConfig, this, _1, _2, _3));
Steve DiBenedetto2c2b8892014-02-27 11:46:48 -070032}
33
34static inline void
35aggregateErrors(std::stringstream& ss, const std::string& msg)
36{
37 if (!ss.str().empty())
38 {
39 ss << "\n";
40 }
41 ss << msg;
42}
43
44void
45CommandValidator::onConfig(const ConfigSection& section,
Steve DiBenedetto1a3c6732014-03-13 06:44:05 -060046 bool isDryRun,
47 const std::string& filename)
Steve DiBenedetto2c2b8892014-02-27 11:46:48 -070048{
Steve DiBenedetto1a3c6732014-03-13 06:44:05 -060049 using namespace boost::filesystem;
50
Steve DiBenedetto2c2b8892014-02-27 11:46:48 -070051 const ConfigSection EMPTY_SECTION;
52
53 if (section.begin() == section.end())
54 {
55 throw ConfigFile::Error("No authorize sections found");
56 }
57
58 std::stringstream dryRunErrors;
59 ConfigSection::const_iterator authIt;
60 for (authIt = section.begin(); authIt != section.end(); authIt++)
61 {
Steve DiBenedetto1a3c6732014-03-13 06:44:05 -060062 std::string certfile;
Steve DiBenedetto2c2b8892014-02-27 11:46:48 -070063 try
64 {
Steve DiBenedetto1a3c6732014-03-13 06:44:05 -060065 certfile = authIt->second.get<std::string>("certfile");
Steve DiBenedetto2c2b8892014-02-27 11:46:48 -070066 }
67 catch (const std::runtime_error& e)
68 {
Steve DiBenedetto1a3c6732014-03-13 06:44:05 -060069 std::string msg = "No certfile specified";
Steve DiBenedetto2c2b8892014-02-27 11:46:48 -070070 if (!isDryRun)
71 {
72 throw ConfigFile::Error(msg);
73 }
74 aggregateErrors(dryRunErrors, msg);
75 continue;
76 }
77
Steve DiBenedetto1a3c6732014-03-13 06:44:05 -060078 path certfilePath = absolute(certfile, path(filename).parent_path());
79 NFD_LOG_DEBUG("generated certfile path: " << certfilePath.native());
80
Steve DiBenedetto2c2b8892014-02-27 11:46:48 -070081 std::ifstream in;
Steve DiBenedetto1a3c6732014-03-13 06:44:05 -060082 in.open(certfilePath.c_str());
Steve DiBenedetto2c2b8892014-02-27 11:46:48 -070083 if (!in.is_open())
84 {
Steve DiBenedetto1a3c6732014-03-13 06:44:05 -060085 std::string msg = "Unable to open certificate file " + certfilePath.native();
Steve DiBenedetto2c2b8892014-02-27 11:46:48 -070086 if (!isDryRun)
87 {
88 throw ConfigFile::Error(msg);
89 }
90 aggregateErrors(dryRunErrors, msg);
91 continue;
92 }
93
94 shared_ptr<ndn::IdentityCertificate> id;
95 try
96 {
97 id = ndn::io::load<ndn::IdentityCertificate>(in);
98 }
99 catch(const std::runtime_error& error)
100 {
Steve DiBenedetto1a3c6732014-03-13 06:44:05 -0600101 std::string msg = "Malformed certificate file " + certfilePath.native();
Steve DiBenedetto2c2b8892014-02-27 11:46:48 -0700102 if (!isDryRun)
103 {
104 throw ConfigFile::Error(msg);
105 }
106 aggregateErrors(dryRunErrors, msg);
107 continue;
108 }
109
110 in.close();
111
112 const ConfigSection* privileges = 0;
113
114 try
115 {
116 privileges = &authIt->second.get_child("privileges");
117 }
118 catch (const std::runtime_error& error)
119 {
Steve DiBenedetto1a3c6732014-03-13 06:44:05 -0600120 std::string msg = "No privileges section found for certificate file " +
121 certfile + " (" + id->getPublicKeyName().toUri() + ")";
Steve DiBenedetto2c2b8892014-02-27 11:46:48 -0700122 if (!isDryRun)
123 {
124 throw ConfigFile::Error(msg);
125 }
126 aggregateErrors(dryRunErrors, msg);
127 continue;
128 }
129
130 if (privileges->begin() == privileges->end())
131 {
Steve DiBenedetto1a3c6732014-03-13 06:44:05 -0600132 NFD_LOG_WARN("No privileges specified for certificate file " << certfile
133 << " (" << id->getPublicKeyName().toUri() << ")");
Steve DiBenedetto2c2b8892014-02-27 11:46:48 -0700134 }
135
136 ConfigSection::const_iterator privIt;
137 for (privIt = privileges->begin(); privIt != privileges->end(); privIt++)
138 {
139 const std::string& privilegeName = privIt->first;
140 if (m_supportedPrivileges.find(privilegeName) != m_supportedPrivileges.end())
141 {
142 NFD_LOG_INFO("Giving privilege \"" << privilegeName
Steve DiBenedetto1a3c6732014-03-13 06:44:05 -0600143 << "\" to identity " << id->getPublicKeyName());
Steve DiBenedetto2c2b8892014-02-27 11:46:48 -0700144 if (!isDryRun)
145 {
146 const std::string regex = "^<localhost><nfd><" + privilegeName + ">";
147 m_validator.addInterestRule(regex, *id);
148 }
149 }
150 else
151 {
152 // Invalid configuration
Steve DiBenedetto1a3c6732014-03-13 06:44:05 -0600153 std::string msg = "Invalid privilege \"" + privilegeName + "\" for certificate file " +
154 certfile + " (" + id->getPublicKeyName().toUri() + ")";
Steve DiBenedetto2c2b8892014-02-27 11:46:48 -0700155 if (!isDryRun)
156 {
157 throw ConfigFile::Error(msg);
158 }
159 aggregateErrors(dryRunErrors, msg);
160 }
161 }
162 }
163
164 if (!dryRunErrors.str().empty())
165 {
166 throw ConfigFile::Error(dryRunErrors.str());
167 }
168}
169
170void
171CommandValidator::addSupportedPrivilege(const std::string& privilege)
172{
173 if (m_supportedPrivileges.find(privilege) != m_supportedPrivileges.end())
174 {
Steve DiBenedetto1a3c6732014-03-13 06:44:05 -0600175 throw CommandValidator::Error("Duplicated privilege: " + privilege);
Steve DiBenedetto2c2b8892014-02-27 11:46:48 -0700176 }
177 m_supportedPrivileges.insert(privilege);
178}
179
180} // namespace nfd
181