blob: 9028ba2da6ac7a57592b088c23954c7d1077b9bf [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
11namespace nfd {
12
13NFD_LOG_INIT("CommandValidator");
14
15CommandValidator::CommandValidator()
16{
17
18}
19
20CommandValidator::~CommandValidator()
21{
22
23}
24
25void
26CommandValidator::setConfigFile(ConfigFile& configFile)
27{
28 configFile.addSectionHandler("authorizations",
29 bind(&CommandValidator::onConfig, this, _1, _2));
30}
31
32static inline void
33aggregateErrors(std::stringstream& ss, const std::string& msg)
34{
35 if (!ss.str().empty())
36 {
37 ss << "\n";
38 }
39 ss << msg;
40}
41
42void
43CommandValidator::onConfig(const ConfigSection& section,
44 bool isDryRun)
45{
46 const ConfigSection EMPTY_SECTION;
47
48 if (section.begin() == section.end())
49 {
50 throw ConfigFile::Error("No authorize sections found");
51 }
52
53 std::stringstream dryRunErrors;
54 ConfigSection::const_iterator authIt;
55 for (authIt = section.begin(); authIt != section.end(); authIt++)
56 {
57 std::string keyfile;
58 try
59 {
60 keyfile = authIt->second.get<std::string>("keyfile");
61 }
62 catch (const std::runtime_error& e)
63 {
64 std::string msg = "No keyfile specified";
65 if (!isDryRun)
66 {
67 throw ConfigFile::Error(msg);
68 }
69 aggregateErrors(dryRunErrors, msg);
70 continue;
71 }
72
73 std::ifstream in;
74 in.open(keyfile.c_str());
75 if (!in.is_open())
76 {
77 std::string msg = "Unable to open key file " + keyfile;
78 if (!isDryRun)
79 {
80 throw ConfigFile::Error(msg);
81 }
82 aggregateErrors(dryRunErrors, msg);
83 continue;
84 }
85
86 shared_ptr<ndn::IdentityCertificate> id;
87 try
88 {
89 id = ndn::io::load<ndn::IdentityCertificate>(in);
90 }
91 catch(const std::runtime_error& error)
92 {
93 std::string msg = "Malformed key file " + keyfile;
94 if (!isDryRun)
95 {
96 throw ConfigFile::Error(msg);
97 }
98 aggregateErrors(dryRunErrors, msg);
99 continue;
100 }
101
102 in.close();
103
104 const ConfigSection* privileges = 0;
105
106 try
107 {
108 privileges = &authIt->second.get_child("privileges");
109 }
110 catch (const std::runtime_error& error)
111 {
112 std::string msg = "No privileges section found for key file " +
113 keyfile + " (" + id->getPublicKeyName().toUri() + ")";
114 if (!isDryRun)
115 {
116 throw ConfigFile::Error(msg);
117 }
118 aggregateErrors(dryRunErrors, msg);
119 continue;
120 }
121
122 if (privileges->begin() == privileges->end())
123 {
124 NFD_LOG_WARN("No privileges specified for key file " << keyfile + " (" << id->getPublicKeyName().toUri() << ")");
125 }
126
127 ConfigSection::const_iterator privIt;
128 for (privIt = privileges->begin(); privIt != privileges->end(); privIt++)
129 {
130 const std::string& privilegeName = privIt->first;
131 if (m_supportedPrivileges.find(privilegeName) != m_supportedPrivileges.end())
132 {
133 NFD_LOG_INFO("Giving privilege \"" << privilegeName
134 << "\" to key " << id->getPublicKeyName());
135 if (!isDryRun)
136 {
137 const std::string regex = "^<localhost><nfd><" + privilegeName + ">";
138 m_validator.addInterestRule(regex, *id);
139 }
140 }
141 else
142 {
143 // Invalid configuration
144 std::string msg = "Invalid privilege \"" + privilegeName + "\" for key file " +
145 keyfile + " (" + id->getPublicKeyName().toUri() + ")";
146 if (!isDryRun)
147 {
148 throw ConfigFile::Error(msg);
149 }
150 aggregateErrors(dryRunErrors, msg);
151 }
152 }
153 }
154
155 if (!dryRunErrors.str().empty())
156 {
157 throw ConfigFile::Error(dryRunErrors.str());
158 }
159}
160
161void
162CommandValidator::addSupportedPrivilege(const std::string& privilege)
163{
164 if (m_supportedPrivileges.find(privilege) != m_supportedPrivileges.end())
165 {
166 throw CommandValidator::Error("Duplicated privivilege: " + privilege);
167 }
168 m_supportedPrivileges.insert(privilege);
169}
170
171} // namespace nfd
172