Add list function
Change-Id: I3923d4f12e2134250b5a61419d53582e5450bdde
diff --git a/tools/ndncert-client.cpp b/tools/ndncert-client.cpp
index 7f082d8..a4b3368 100644
--- a/tools/ndncert-client.cpp
+++ b/tools/ndncert-client.cpp
@@ -20,18 +20,19 @@
#include "client-module.hpp"
#include "challenge-module.hpp"
-#include "logging.hpp"
#include <iostream>
+#include <string>
#include <boost/program_options/options_description.hpp>
#include <boost/program_options/variables_map.hpp>
#include <boost/program_options/parsers.hpp>
+#include <ndn-cxx/security/verification-helpers.hpp>
namespace ndn {
namespace ndncert {
-_LOG_INIT(ndncert.clientTool);
+int nStep;
class ClientTool
{
@@ -44,23 +45,101 @@
void
errorCb(const std::string& errorInfo)
{
- _LOG_TRACE("Error: " << errorInfo);
+ std::cerr << "Error: " << errorInfo << std::endl;
}
void
- downloadCb(const shared_ptr<RequestState>& state, int& nStep)
+ downloadCb(const shared_ptr<RequestState>& state)
{
- _LOG_TRACE("Certificate has already been installed to local keychain");
+ std::cerr << "Step " << nStep++
+ << "DONE! Certificate has already been installed to local keychain" << std::endl;
return;
}
void
- validateCb(const shared_ptr<RequestState>& state, int& nStep)
+ anchorCb(const Interest& request, const Data& reply,
+ const ClientCaItem& anchorItem, const Name& assignedName)
+ {
+ auto contentJson = ClientModule::getJsonFromData(reply);
+ auto caItem = ClientConfig::extractCaItem(contentJson);
+
+ if (!security::verifySignature(caItem.m_anchor, anchorItem.m_anchor)) {
+ std::cerr << "Fail to verify fetched anchor" << std::endl;
+ return;
+ }
+ client.getClientConf().m_caItems.push_back(caItem);
+
+ if (assignedName.toUri() != "/") {
+ client.sendNew(caItem, assignedName,
+ bind(&ClientTool::newCb, this, _1),
+ bind(&ClientTool::errorCb, this, _1));
+ }
+ else {
+ if (caItem.m_probe != "") {
+ std::cerr <<"Step " << nStep++ << ": Probe Requirement-" << caItem.m_probe << std::endl;
+ std::string probeInfo;
+ getline(std::cin, probeInfo);
+ client.sendProbe(caItem, probeInfo,
+ bind(&ClientTool::newCb, this, _1),
+ bind(&ClientTool::errorCb, this, _1));
+ }
+ else {
+ std::cerr <<"Step " << nStep++ << ": Please type in the identity name" << std::endl;
+ std::string nameComponent;
+ getline(std::cin, nameComponent);
+ Name identityName = caItem.m_caName.getPrefix(-1);
+ identityName.append(nameComponent);
+ client.sendNew(caItem, identityName,
+ bind(&ClientTool::newCb, this, _1),
+ bind(&ClientTool::errorCb, this, _1));
+ }
+ }
+ }
+
+ void
+ listCb(const std::list<Name>& caList, const Name& assignedName, const Name& schema,
+ const ClientCaItem& caItem)
+ {
+ if (assignedName.toUri() != "" && caList.size() == 1) {
+ // with recommendation
+
+ std::cerr << "Get recommended CA: " << caList.front()
+ << "Get recommended Identity: " << assignedName << std::endl;
+ client.requestCaTrustAnchor(caList.front(),
+ bind(&ClientTool::anchorCb, this, _1, _2, caItem, assignedName),
+ bind(&ClientTool::errorCb, this, _1));
+ }
+ else {
+ // without recommendation
+ int count = 0;
+ for (auto name : caList) {
+ std::cerr << "***************************************" << "\n"
+ << "Index: " << count++ << "\n"
+ << "CA prefix:" << name << "\n"
+ << "***************************************" << std::endl;
+ }
+ std::cerr << "Select an index to apply for a certificate."<< std::endl;
+
+ std::string option;
+ getline(std::cin, option);
+ int caIndex = std::stoi(option);
+
+ std::vector<Name> caVector{std::begin(caList), std::end(caList)};
+ Name targetCaName = caVector[caIndex];
+
+ client.requestCaTrustAnchor(targetCaName,
+ bind(&ClientTool::anchorCb, this, _1, _2, caItem, Name("")),
+ bind(&ClientTool::errorCb, this, _1));
+ }
+ }
+
+ void
+ validateCb(const shared_ptr<RequestState>& state)
{
if (state->m_status == ChallengeModule::SUCCESS) {
- _LOG_TRACE("Certificate has already been issued");
+ std::cerr << "DONE! Certificate has already been issued" << std::endl;
client.requestDownload(state,
- bind(&ClientTool::downloadCb, this, _1, nStep),
+ bind(&ClientTool::downloadCb, this, _1),
bind(&ClientTool::errorCb, this, _1));
return;
}
@@ -75,17 +154,17 @@
std::list<std::string> paraList;
for (size_t i = 0; i < requirementList.size(); i++) {
std::string tempParam;
- std::cin >> tempParam;
+ getline(std::cin, tempParam);
paraList.push_back(tempParam);
}
auto paramJson = challenge->genValidateParamsJson(state->m_status, paraList);
client.sendValidate(state, paramJson,
- bind(&ClientTool::validateCb, this, _1, nStep),
+ bind(&ClientTool::validateCb, this, _1),
bind(&ClientTool::errorCb, this, _1));
}
void
- selectCb(const shared_ptr<RequestState>& state, int& nStep)
+ selectCb(const shared_ptr<RequestState>& state)
{
auto challenge = ChallengeModule::createChallengeModule(state->m_challengeType);
auto requirementList = challenge->getRequirementForValidate(state->m_status);
@@ -97,25 +176,25 @@
std::list<std::string> paraList;
for (size_t i = 0; i < requirementList.size(); i++) {
std::string tempParam;
- std::cin >> tempParam;
+ getline(std::cin, tempParam);
paraList.push_back(tempParam);
}
auto paramJson = challenge->genValidateParamsJson(state->m_status, paraList);
client.sendValidate(state, paramJson,
- bind(&ClientTool::validateCb, this, _1, nStep),
+ bind(&ClientTool::validateCb, this, _1),
bind(&ClientTool::errorCb, this, _1));
}
void
- newCb(const shared_ptr<RequestState>& state, int& nStep)
+ newCb(const shared_ptr<RequestState>& state)
{
std::cerr << "Step" << nStep++ << ": Please select one challenge from following types." << std::endl;
for (auto item : state->m_challengeList) {
std::cerr << "\t" << item << std::endl;
}
std::string choice;
- std::cin >> choice;
+ getline(std::cin, choice);
auto challenge = ChallengeModule::createChallengeModule(choice);
auto requirementList = challenge->getRequirementForSelect();
@@ -127,13 +206,13 @@
}
for (size_t i = 0; i < requirementList.size(); i++) {
std::string tempParam;
- std::cin >> tempParam;
+ getline(std::cin, tempParam);
paraList.push_back(tempParam);
}
}
auto paramJson = challenge->genSelectParamsJson(state->m_status, paraList);
client.sendSelect(state, choice, paramJson,
- bind(&ClientTool::selectCb, this, _1, nStep),
+ bind(&ClientTool::selectCb, this, _1),
bind(&ClientTool::errorCb, this, _1));
}
@@ -146,10 +225,13 @@
{
namespace po = boost::program_options;
std::string configFilePath = std::string(SYSCONFDIR) + "/ndncert/client.conf";
- po::options_description description("General Usage\n ndncert-client [-h] [-f] configFilePath-file\n");
+ bool isIntra = false;
+ po::options_description description("General Usage\n ndncert-client [-h] [-i] [-f]\n");
description.add_options()
("help,h", "produce help message")
- ("config-file,f", po::value<std::string>(&configFilePath), "config file name");
+ ("intra-node,i", "optional, if specified, switch on the intra-node mode")
+ ("config-file,f", po::value<std::string>(&configFilePath), "config file name")
+ ;
po::positional_options_description p;
po::variables_map vm;
@@ -165,50 +247,123 @@
std::cerr << description << std::endl;
return 0;
}
+ if (vm.count("intra-node") != 0) {
+ isIntra = true;
+ }
+ nStep = 0;
Face face;
security::v2::KeyChain keyChain;
ClientModule client(face, keyChain);
client.getClientConf().load(configFilePath);
-
ClientTool tool(client);
- auto caList = client.getClientConf().m_caItems;
- std::cerr << "Index \t CA Namespace \t CA Introduction" << std::endl;
- int count = 0;
- for (auto item : caList) {
- std::cerr << count++ << "\t"
- << item.m_caName << "\t"
- << item.m_caInfo << std::endl;
- }
- std::vector<ClientCaItem> caVector{std::begin(caList), std::end(caList)};
- int nStep = 0;
- std::cerr << "Step" << nStep++ << ": Please type in the CA namespace index that you want to apply" << std::endl;
- std::string caIndexS;
- std::cin >> caIndexS;
- int caIndex = std::stoi(caIndexS);
+ if (isIntra) {
+ client.requestLocalhostList([&](const ClientConfig& config) {
+ auto caList = config.m_caItems;
+ int count = 0;
+ for (auto item : caList) {
+ std::cerr << "***************************************" << "\n"
+ << "Index: " << count++ << "\n"
+ << "CA prefix:" << item.m_caName << "\n"
+ << "Introduction: " << item.m_caInfo << "\n"
+ << "***************************************" << std::endl;
+ }
+ std::vector<ClientCaItem> caVector{std::begin(caList), std::end(caList)};
+ std::cerr << "Step" << nStep++
+ << ": Please type in the CA namespace index that you want to apply" << std::endl;
+ std::string caIndexS;
+ getline(std::cin, caIndexS);
+ int caIndex = std::stoi(caIndexS);
- BOOST_ASSERT(caIndex <= count);
+ BOOST_ASSERT(caIndex <= count);
- auto targetCaItem = caVector[caIndex];
- if (targetCaItem.m_probe != "") {
- std::cerr <<"Step" << nStep++ << ": Probe Requirement-" << targetCaItem.m_probe << std::endl;
- std::string probeInfo;
- std::cin >> probeInfo;
- client.sendProbe(targetCaItem, probeInfo,
- bind(&ClientTool::newCb, &tool, _1, nStep),
- bind(&ClientTool::errorCb, &tool, _1));
+ auto targetCaItem = caVector[caIndex];
+ if (targetCaItem.m_probe != "") {
+ std::cerr <<"Step" << nStep++ << ": Probe Requirement-" << targetCaItem.m_probe << std::endl;
+ std::string probeInfo;
+ getline(std::cin, probeInfo);
+ client.sendProbe(targetCaItem, probeInfo,
+ bind(&ClientTool::newCb, &tool, _1),
+ bind(&ClientTool::errorCb, &tool, _1));
+ }
+ else {
+ std::cerr <<"Step" << nStep++ << ": Please type in the identity name" << std::endl;
+ std::string nameComponent;
+ getline(std::cin, nameComponent);
+ Name identityName = targetCaItem.m_caName.getPrefix(-1);
+ identityName.append(nameComponent);
+ client.sendNew(targetCaItem, identityName,
+ bind(&ClientTool::newCb, &tool, _1),
+ bind(&ClientTool::errorCb, &tool, _1));
+ }
+ },
+ bind(&ClientTool::errorCb, &tool, _1));
}
else {
- std::cerr <<"Step" << nStep++ << ": Please type in the identity name" << std::endl;
- std::string nameComponent;
- std::cin >> nameComponent;
- Name identityName = targetCaItem.m_caName.getPrefix(-1);
- identityName.append(nameComponent);
- client.sendNew(targetCaItem, identityName,
- bind(&ClientTool::newCb, &tool, _1, nStep),
- bind(&ClientTool::errorCb, &tool, _1));
+ auto caList = client.getClientConf().m_caItems;
+ int count = 0;
+ for (auto item : caList) {
+ std::cerr << "***************************************" << "\n"
+ << "Index: " << count++ << "\n"
+ << "CA prefix:" << item.m_caName << "\n"
+ << "Introduction: " << item.m_caInfo << "\n"
+ << "***************************************" << std::endl;
+ }
+ std::vector<ClientCaItem> caVector{std::begin(caList), std::end(caList)};
+ std::cerr << "Step " << nStep++ << ": Please type in the CA namespace index that you want to apply" << std::endl;
+
+ std::string caIndexS;
+ getline(std::cin, caIndexS);
+
+ int caIndex = std::stoi(caIndexS);
+
+ BOOST_ASSERT(caIndex <= count);
+
+ auto targetCaItem = caVector[caIndex];
+ std::cerr << "You want a namespace with prefix (A) /ndn or (B) a sub-namespace of "
+ << targetCaItem.m_caName << "?" << std::endl;
+ std::string listOption;
+ getline(std::cin, listOption);
+ if (listOption == "A" || listOption == "a") {
+ // should directly send _PROBE or _NEW
+ if (targetCaItem.m_probe != "") {
+ std::cerr <<"Step " << nStep++ << ": Probe Requirement-" << targetCaItem.m_probe << std::endl;
+ std::string probeInfo;
+ getline(std::cin, probeInfo);
+ client.sendProbe(targetCaItem, probeInfo,
+ bind(&ClientTool::newCb, &tool, _1),
+ bind(&ClientTool::errorCb, &tool, _1));
+ }
+ else {
+ std::cerr <<"Step " << nStep++ << ": Please type in the identity name" << std::endl;
+ std::string nameComponent;
+ getline(std::cin, nameComponent);
+ Name identityName = targetCaItem.m_caName.getPrefix(-1);
+ identityName.append(nameComponent);
+ client.sendNew(targetCaItem, identityName,
+ bind(&ClientTool::newCb, &tool, _1),
+ bind(&ClientTool::errorCb, &tool, _1));
+ }
+ }
+ else if (listOption == "B" || listOption == "b") {
+ std::string additionalInfo = "";
+ if (targetCaItem.m_targetedList != "") {
+ std::cerr <<"Step " << nStep++
+ << ": Enter nothing if you want to see all available sub-namespace CAs"
+ << "or follow the instruction to get a recommended CA\n"
+ << "\t" << targetCaItem.m_targetedList << std::endl;
+ getline(std::cin, additionalInfo);
+ }
+ client.requestList(targetCaItem, additionalInfo,
+ bind(&ClientTool::listCb, &tool, _1, _2, _3, targetCaItem),
+ bind(&ClientTool::errorCb, &tool, _1));
+ }
+ else {
+ std::cerr << "Your input is not an option." << std::endl;
+ }
}
+
face.processEvents();
return 0;
}