Delete created identities/keys if the client doesn't complete successfully; update client command line tool
Client command line tool:
* remove infinite loop asking for user input when input is of wrong format
* add signal handling
Refs: #4962
Change-Id: Ib4f8143f6efd45dee7232f99c5b791f09926bb46
diff --git a/tools/ndncert-client.cpp b/tools/ndncert-client.cpp
index ea6f3be..bc5bb5a 100644
--- a/tools/ndncert-client.cpp
+++ b/tools/ndncert-client.cpp
@@ -1,6 +1,6 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/**
- * Copyright (c) 2017-2019, Regents of the University of California.
+ * Copyright (c) 2017-2020, Regents of the University of California.
*
* This file is part of ndncert, a certificate management system based on NDN.
*
@@ -22,9 +22,11 @@
#include "challenge-module.hpp"
#include <iostream>
#include <string>
+#include <csignal>
#include <boost/program_options/options_description.hpp>
#include <boost/program_options/variables_map.hpp>
#include <boost/program_options/parsers.hpp>
+#include <boost/asio.hpp>
#include <ndn-cxx/security/verification-helpers.hpp>
namespace ndn {
@@ -81,25 +83,20 @@
static void
captureValidityPeriod()
{
- if (validityPeriod <= 0) {
- std::cerr << "Step " << nStep++
- << ": Please type in your expected validity period of your certificate."
- << " Type the number of hours (168 for week, 730 for month, 8760 for year). The CA may change the validity"
- << " period if your expected period is too long." << std::endl;
- std::string periodStr = "";
- do {
- getline(std::cin, periodStr);
- try {
- validityPeriod = std::stoi(periodStr);
- }
- catch (const std::exception& e) {
- validityPeriod = -1;
- }
- if (validityPeriod > 0) {
- break;
- }
- std::cerr << "Invalid period time. Please input the period again." << std::endl;
- } while (true);
+ if (validityPeriod > 0) {
+ return;
+ }
+ std::cerr << "Step " << nStep++
+ << ": Please type in your expected validity period of your certificate."
+ << " Type the number of hours (168 for week, 730 for month, 8760 for year)."
+ << " The CA may reject your application if your expected period is too long." << std::endl;
+ std::string periodStr = "";
+ getline(std::cin, periodStr);
+ try {
+ validityPeriod = std::stoi(periodStr);
+ }
+ catch (const std::exception& e) {
+ validityPeriod = -1;
}
}
@@ -118,10 +115,14 @@
static void
downloadCb(const Data& reply)
{
- client.onDownloadResponse(reply);
+ auto cert = client.onDownloadResponse(reply);
+ if (cert == nullptr) {
+ std::cerr << "Certificate cannot be installed to your local keychain" << std::endl;
+ return;
+ }
std::cerr << "Step " << nStep++
- << ": DONE! Certificate has already been installed to local keychain\n";
- return;
+ << ": DONE! Certificate has already been installed to local keychain\n"
+ << "Certificate Name: " << cert->getName().toUri() << std::endl;
}
static void
@@ -142,12 +143,7 @@
std::cerr << "Step " << nStep++ << ": Please satisfy following instruction(s)\n";
std::string redo = "";
std::list<std::string> capturedParams;
- do {
- capturedParams = captureParams(requirement);
- std::cerr << "If everything is correct, please type in OK; otherwise, type in REDO" << std::endl;
- getline(std::cin, redo);
- boost::algorithm::to_lower(redo);
- } while (redo != "ok");
+ capturedParams = captureParams(requirement);
auto it1 = capturedParams.begin();
auto it2 = requirement.begin();
for (; it1 != capturedParams.end() && it2 != requirement.end(); it1++, it2++) {
@@ -173,23 +169,21 @@
int count = 0;
std::string choice = "";
std::cerr << "Step " << nStep++ << ": Please type in the challenge index that you want to perform\n";
- do {
- count = 0;
- for (auto item : challengeList) {
- std::cerr << "\t" << count++ << " : "<< item << std::endl;
- }
- getline(std::cin, choice);
- try {
- challengeIndex = std::stoi(choice);
- }
- catch (const std::exception& e) {
- challengeIndex = -1;
- }
- if (challengeIndex >= 0 && challengeIndex < count) {
- break;
- }
- std::cerr << "Your input index is out of range. Please type in again." << std::endl;
- } while (true);
+ count = 0;
+ for (auto item : challengeList) {
+ std::cerr << "\t" << count++ << " : "<< item << std::endl;
+ }
+ getline(std::cin, choice);
+ try {
+ challengeIndex = std::stoi(choice);
+ }
+ catch (const std::exception& e) {
+ challengeIndex = -1;
+ }
+ if (challengeIndex < 0 || challengeIndex >= count) {
+ std::cerr << "Your input index is out of range. Exit." << std::endl;
+ return;
+ }
}
auto it = challengeList.begin();
std::advance(it, challengeIndex);
@@ -208,12 +202,7 @@
std::cerr << "Step " << nStep++ << ": Please satisfy following instruction(s)\n";
std::string redo = "";
std::list<std::string> capturedParams;
- do {
- capturedParams = captureParams(requirement);
- std::cerr << "If everything is correct, please type in OK; otherwise, type in REDO" << std::endl;
- getline(std::cin, redo);
- boost::algorithm::to_lower(redo);
- } while (redo != "ok");
+ capturedParams = captureParams(requirement);
auto it1 = capturedParams.begin();
auto it2 = requirement.begin();
for (; it1 != capturedParams.end() && it2 != requirement.end(); it1++, it2++) {
@@ -261,12 +250,20 @@
{
client.onProbeResponse(reply);
captureValidityPeriod();
+ if (validityPeriod <= 0) {
+ std::cerr << "Invalid period time. Exit." << std::endl;
+ return;
+ }
auto probeToken = make_shared<Data>(reply);
auto now = time::system_clock::now();
std::cerr << "The validity period of your certificate will be: " << validityPeriod << " hours" << std::endl;
- face.expressInterest(*client.generateNewInterest(now, now + time::hours(validityPeriod),
- Name(), probeToken),
- bind(&newCb, _2), bind(&onNackCb), bind(&timeoutCb));
+ auto interest = client.generateNewInterest(now, now + time::hours(validityPeriod), Name(), probeToken);
+ if (interest != nullptr) {
+ face.expressInterest(*interest, bind(&newCb, _2), bind(&onNackCb), bind(&timeoutCb));
+ }
+ else {
+ std::cerr << "Cannot generate the Interest for NEW step. Exit" << std::endl;
+ }
}
static void
@@ -318,12 +315,7 @@
std::vector<std::string> probeFields = ClientModule::parseProbeComponents(targetCaItem.m_probe);
std::string redo = "";
std::list<std::string> capturedParams;
- do {
- capturedParams = captureParams(probeFields);
- std::cerr << "If everything is correct, please type in OK; otherwise, type in REDO" << std::endl;
- getline(std::cin, redo);
- boost::algorithm::to_lower(redo);
- } while (redo != "ok");
+ capturedParams = captureParams(probeFields);
std::string probeInfo;
for (const auto& item : capturedParams) {
probeInfo += item;
@@ -334,23 +326,55 @@
bind(&probeCb, _2), bind(&onNackCb), bind(&timeoutCb));
}
else {
- std::cerr << "Step " << nStep++ << ": Please type in the identity name you want to get (with CA prefix)\n";
+ std::cerr << "Step " << nStep++ << ": Please type in the full identity name you want to get (with CA prefix)\n";
std::string identityNameStr;
getline(std::cin, identityNameStr);
captureValidityPeriod();
+ if (validityPeriod <= 0) {
+ std::cerr << "Invalid period time. Exit." << std::endl;
+ return;
+ }
+ Name idName(identityNameStr);
std::cerr << "The validity period of your certificate will be: " << validityPeriod << " hours" << std::endl;
auto now = time::system_clock::now();
- face.expressInterest(*client.generateNewInterest(now, now + time::hours(validityPeriod),
- Name(identityNameStr)),
- bind(&newCb, _2), bind(&onNackCb), bind(&timeoutCb));
+ auto interest = client.generateNewInterest(now, now + time::hours(validityPeriod), idName);
+ if (interest != nullptr) {
+ face.expressInterest(*interest, bind(&newCb, _2), bind(&onNackCb), bind(&timeoutCb));
+ }
+ else {
+ std::cerr << "Cannot generate the Interest for NEW step. Exit" << std::endl;
+ }
}
}
}
+static void
+handleSignal(const boost::system::error_code& error, int signalNum)
+{
+ if (error) {
+ return;
+ }
+ const char* signalName = ::strsignal(signalNum);
+ std::cerr << "Exiting on signal ";
+ if (signalName == nullptr) {
+ std::cerr << signalNum;
+ }
+ else {
+ std::cerr << signalName;
+ }
+ std::cerr << std::endl;
+ client.endSession();
+ face.getIoService().stop();
+}
int
main(int argc, char* argv[])
{
+ boost::asio::signal_set terminateSignals(face.getIoService());
+ terminateSignals.add(SIGINT);
+ terminateSignals.add(SIGTERM);
+ terminateSignals.async_wait(handleSignal);
+
namespace po = boost::program_options;
std::string configFilePath = std::string(SYSCONFDIR) + "/ndncert/client.conf";
po::options_description description("General Usage\n ndncert-client [-h] [-c] [-v]\n");