blob: 86ff60fca2acf4b1b0fdbbdd29f91ba7544f4b15 [file] [log] [blame]
Zhiyi Zhang08e0e982017-03-01 10:10:42 -08001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2/**
3 * Copyright (c) 2017, Regents of the University of California.
4 *
5 * This file is part of ndncert, a certificate management system based on NDN.
6 *
7 * ndncert is free software: you can redistribute it and/or modify it under the terms
8 * of the GNU General Public License as published by the Free Software Foundation, either
9 * version 3 of the License, or (at your option) any later version.
10 *
11 * ndncert is distributed in the hope that it will be useful, but WITHOUT ANY
12 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
13 * PARTICULAR PURPOSE. See the GNU General Public License for more details.
14 *
15 * You should have received copies of the GNU General Public License along with
16 * ndncert, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>.
17 *
18 * See AUTHORS.md for complete list of ndncert authors and contributors.
19 */
20
21#include "client-module.hpp"
22#include "challenge-module.hpp"
23#include "logging.hpp"
24
25#include <boost/program_options/options_description.hpp>
26#include <boost/program_options/variables_map.hpp>
27#include <boost/program_options/parsers.hpp>
28
29namespace ndn {
30namespace ndncert {
31
32_LOG_INIT(ndncert.clientTool);
33
34class ClientTool
35{
36public:
37 ClientTool(ClientModule& clientModule)
38 : client(clientModule)
39 {
40 }
41
42 void
43 errorCb(const std::string& errorInfo)
44 {
45 _LOG_TRACE("Error: " << errorInfo);
46 }
47
48 void
Zhiyi Zhang4d89fe02017-04-28 18:51:51 -070049 downloadCb(const shared_ptr<RequestState>& state, int& nStep)
50 {
51 _LOG_TRACE("Certificate has already been installed to local keychain");
52 return;
53 }
54
55 void
56 validateCb(const shared_ptr<RequestState>& state, int& nStep)
Zhiyi Zhang08e0e982017-03-01 10:10:42 -080057 {
58 if (state->m_status == ChallengeModule::SUCCESS) {
59 _LOG_TRACE("Certificate has already been issued");
Zhiyi Zhang4d89fe02017-04-28 18:51:51 -070060 client.requestDownload(state,
61 bind(&ClientTool::downloadCb, this, _1, nStep),
62 bind(&ClientTool::errorCb, this, _1));
Zhiyi Zhang08e0e982017-03-01 10:10:42 -080063 return;
64 }
65
66 auto challenge = ChallengeModule::createChallengeModule(state->m_challengeType);
67 auto requirementList = challenge->getRequirementForValidate(state->m_status);
68
69 std::cerr << "Step" << nStep++ << ": Please satisfy following instruction(s)" << std::endl;
70 for (auto requirement : requirementList) {
71 std::cerr << "\t" << requirement << std::endl;
72 }
73 std::list<std::string> paraList;
74 for (size_t i = 0; i < requirementList.size(); i++) {
75 std::string tempParam;
76 std::cin >> tempParam;
77 paraList.push_back(tempParam);
78 }
79 auto paramJson = challenge->genValidateParamsJson(state->m_status, paraList);
80 client.sendValidate(state, paramJson,
81 bind(&ClientTool::validateCb, this, _1, nStep),
82 bind(&ClientTool::errorCb, this, _1));
83 }
84
85 void
Zhiyi Zhang4d89fe02017-04-28 18:51:51 -070086 selectCb(const shared_ptr<RequestState>& state, int& nStep)
Zhiyi Zhang08e0e982017-03-01 10:10:42 -080087 {
88 auto challenge = ChallengeModule::createChallengeModule(state->m_challengeType);
89 auto requirementList = challenge->getRequirementForValidate(state->m_status);
90
91 std::cerr << "Step" << nStep++ << ": Please satisfy following instruction(s)" << std::endl;
92 for (auto item : requirementList) {
93 std::cerr << "\t" << item << std::endl;
94 }
95 std::list<std::string> paraList;
96 for (size_t i = 0; i < requirementList.size(); i++) {
97 std::string tempParam;
98 std::cin >> tempParam;
99 paraList.push_back(tempParam);
100 }
101
102 auto paramJson = challenge->genValidateParamsJson(state->m_status, paraList);
103 client.sendValidate(state, paramJson,
104 bind(&ClientTool::validateCb, this, _1, nStep),
105 bind(&ClientTool::errorCb, this, _1));
106 }
107
108 void
Zhiyi Zhang4d89fe02017-04-28 18:51:51 -0700109 newCb(const shared_ptr<RequestState>& state, int& nStep)
Zhiyi Zhang08e0e982017-03-01 10:10:42 -0800110 {
111 std::cerr << "Step" << nStep++ << ": Please select one challenge from following types." << std::endl;
112 for (auto item : state->m_challengeList) {
113 std::cerr << "\t" << item << std::endl;
114 }
115 std::string choice;
116 std::cin >> choice;
117
118 auto challenge = ChallengeModule::createChallengeModule(choice);
119 auto requirementList = challenge->getRequirementForSelect();
120 std::list<std::string> paraList;
121 if (requirementList.size() != 0) {
122 std::cerr << "Step" << nStep++ << ": Please satisfy following instruction(s)" << std::endl;
123 for (auto item : requirementList) {
124 std::cerr << "\t" << item << std::endl;
125 }
126 for (size_t i = 0; i < requirementList.size(); i++) {
127 std::string tempParam;
128 std::cin >> tempParam;
129 paraList.push_back(tempParam);
130 }
131 }
132 auto paramJson = challenge->genSelectParamsJson(state->m_status, paraList);
133 client.sendSelect(state, choice, paramJson,
134 bind(&ClientTool::selectCb, this, _1, nStep),
135 bind(&ClientTool::errorCb, this, _1));
136 }
137
138public:
139 ClientModule& client;
140};
141
142int
143main(int argc, char* argv[])
144{
145 namespace po = boost::program_options;
146 std::string configFilePath = std::string(SYSCONFDIR) + "/ndncert/client.conf";
147 po::options_description description("General Usage\n ndncert-client [-h] [-f] configFilePath-file\n");
148 description.add_options()
149 ("help,h", "produce help message")
150 ("config-file,f", po::value<std::string>(&configFilePath), "config file name");
151 po::positional_options_description p;
152
153 po::variables_map vm;
154 try {
155 po::store(po::command_line_parser(argc, argv).options(description).positional(p).run(), vm);
156 po::notify(vm);
157 }
158 catch (const std::exception& e) {
159 std::cerr << "ERROR: " << e.what() << std::endl;
160 return 1;
161 }
162 if (vm.count("help") != 0) {
163 std::cerr << description << std::endl;
164 return 0;
165 }
166
167 Face face;
168 security::v2::KeyChain keyChain;
169 ClientModule client(face, keyChain);
170 client.getClientConf().load(configFilePath);
171
172 ClientTool tool(client);
173
174 auto caList = client.getClientConf().m_caItems;
175 std::cerr << "Index \t CA Namespace \t CA Introduction" << std::endl;
176 int count = 0;
177 for (auto item : caList) {
178 std::cerr << count++ << "\t"
179 << item.m_caName << "\t"
180 << item.m_caInfo << std::endl;
181 }
182 std::vector<ClientCaItem> caVector{std::begin(caList), std::end(caList)};
183 int nStep = 0;
184 std::cerr << "Step" << nStep++ << ": Please type in the CA namespace index that you want to apply" << std::endl;
185 std::string caIndexS;
186 std::cin >> caIndexS;
187 int caIndex = std::stoi(caIndexS);
188
189 BOOST_ASSERT(caIndex <= count);
190
191 auto targetCaItem = caVector[caIndex];
192 if (targetCaItem.m_probe != "") {
193 std::cerr <<"Step" << nStep++ << ": Probe Requirement-" << targetCaItem.m_probe << std::endl;
194 std::string probeInfo;
195 std::cin >> probeInfo;
196 client.sendProbe(targetCaItem, probeInfo,
197 bind(&ClientTool::newCb, &tool, _1, nStep),
198 bind(&ClientTool::errorCb, &tool, _1));
199 }
200 else {
201 std::cerr <<"Step" << nStep++ << ": Please type in the identity name" << std::endl;
202 std::string nameComponent;
203 std::cin >> nameComponent;
Zhiyi Zhang4d89fe02017-04-28 18:51:51 -0700204 Name identityName = targetCaItem.m_caName.getPrefix(-1);
Zhiyi Zhang08e0e982017-03-01 10:10:42 -0800205 identityName.append(nameComponent);
206 client.sendNew(targetCaItem, identityName,
207 bind(&ClientTool::newCb, &tool, _1, nStep),
208 bind(&ClientTool::errorCb, &tool, _1));
209 }
210 face.processEvents();
211 return 0;
212}
213
214} // namespace ndncert
215} // namespace ndn
216
217int
218main(int argc, char* argv[])
219{
220 return ndn::ndncert::main(argc, argv);
221}