blob: c026852806747240878cb4fb14ba9d50846e9f58 [file] [log] [blame]
Alexander Afanasyevc169a812014-05-20 20:37:29 -04001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
Alexander Afanasyevdfa52c42014-04-24 21:10:11 -07002/**
Alexander Afanasyev80782e02017-01-04 13:16:54 -08003 * Copyright (c) 2013-2017 Regents of the University of California.
Alexander Afanasyevdfa52c42014-04-24 21:10:11 -07004 *
5 * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
Alexander Afanasyevdfa52c42014-04-24 21:10:11 -07006 *
Alexander Afanasyevc169a812014-05-20 20:37:29 -04007 * ndn-cxx library is free software: you can redistribute it and/or modify it under the
8 * terms of the GNU Lesser General Public License as published by the Free Software
9 * Foundation, either version 3 of the License, or (at your option) any later version.
10 *
11 * ndn-cxx library 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 Lesser General Public License for more details.
14 *
15 * You should have received copies of the GNU General Public License and GNU Lesser
16 * General Public License along with ndn-cxx, e.g., in COPYING.md file. If not, see
17 * <http://www.gnu.org/licenses/>.
18 *
19 * See AUTHORS.md for complete list of ndn-cxx authors and contributors.
Alexander Afanasyevdfa52c42014-04-24 21:10:11 -070020 *
21 * @author Yingdi Yu <http://irl.cs.ucla.edu/~yingdi/>
Yingdi Yu8d7468f2014-02-21 14:49:45 -080022 */
23
Alexander Afanasyevd7db8bf2015-01-04 15:31:02 -080024#ifndef NDN_TOOLS_NDNSEC_UTIL_HPP
25#define NDN_TOOLS_NDNSEC_UTIL_HPP
Yingdi Yu8d7468f2014-02-21 14:49:45 -080026
27#include <iostream>
28#include <fstream>
29#include <string>
30#include <cstring>
31
32#include <boost/program_options/options_description.hpp>
33#include <boost/program_options/variables_map.hpp>
34#include <boost/program_options/parsers.hpp>
35#include <boost/date_time/posix_time/posix_time.hpp>
36#include <boost/tokenizer.hpp>
37#include <boost/asio.hpp>
38#include <boost/exception/all.hpp>
39
Junxiao Shi160701a2016-08-30 11:35:25 +000040#include "encoding/buffer-stream.hpp"
Alexander Afanasyev80782e02017-01-04 13:16:54 -080041#include "security/v1/key-chain.hpp"
Junxiao Shi160701a2016-08-30 11:35:25 +000042#include "security/transform.hpp"
Yingdi Yu64c3fb42014-02-26 17:30:04 -080043#include "util/io.hpp"
Yingdi Yu8d7468f2014-02-21 14:49:45 -080044
45bool
46getPassword(std::string& password, const std::string& prompt)
47{
Alexander Afanasyevcf3a6672015-02-01 20:33:22 -080048#ifdef NDN_CXX_HAVE_GETPASS
Yingdi Yub61f5402014-02-26 17:46:11 -080049 bool isReady = false;
Yingdi Yu8d7468f2014-02-21 14:49:45 -080050
Yingdi Yub61f5402014-02-26 17:46:11 -080051 char* pw0 = 0;
Alexander Afanasyevdfa52c42014-04-24 21:10:11 -070052
Yingdi Yu8d7468f2014-02-21 14:49:45 -080053 pw0 = getpass(prompt.c_str());
Alexander Afanasyevdfa52c42014-04-24 21:10:11 -070054 if (!pw0)
Yingdi Yu8d7468f2014-02-21 14:49:45 -080055 return false;
56 std::string password1 = pw0;
57 memset(pw0, 0, strlen(pw0));
58
59 pw0 = getpass("Confirm:");
Yingdi Yub61f5402014-02-26 17:46:11 -080060 if (!pw0)
Yingdi Yu8d7468f2014-02-21 14:49:45 -080061 {
62 char* pw1 = const_cast<char*>(password1.c_str());
63 memset(pw1, 0, password1.size());
64 return false;
65 }
66
Yingdi Yub61f5402014-02-26 17:46:11 -080067 if (!password1.compare(pw0))
Yingdi Yu8d7468f2014-02-21 14:49:45 -080068 {
Yingdi Yub61f5402014-02-26 17:46:11 -080069 isReady = true;
Yingdi Yu8d7468f2014-02-21 14:49:45 -080070 password.swap(password1);
71 }
72
73 char* pw1 = const_cast<char*>(password1.c_str());
74 memset(pw1, 0, password1.size());
75 memset(pw0, 0, strlen(pw0));
76
Yingdi Yub61f5402014-02-26 17:46:11 -080077 if (password.empty())
Yingdi Yu8d7468f2014-02-21 14:49:45 -080078 return false;
79
Yingdi Yub61f5402014-02-26 17:46:11 -080080 return isReady;
Alexander Afanasyeva2ada222015-01-22 18:34:16 -080081#else
82 return false;
83#endif // NDN_CXX_HAVE_GETPASS
Yingdi Yu8d7468f2014-02-21 14:49:45 -080084}
85
Alexander Afanasyev2fa59392016-07-29 17:24:23 -070086ndn::shared_ptr<ndn::security::v1::IdentityCertificate>
Yingdi Yu8d7468f2014-02-21 14:49:45 -080087getIdentityCertificate(const std::string& fileName)
88{
Yingdi Yu8d7468f2014-02-21 14:49:45 -080089
Yingdi Yub61f5402014-02-26 17:46:11 -080090 if (fileName == "-")
Alexander Afanasyev2fa59392016-07-29 17:24:23 -070091 return ndn::io::load<ndn::security::v1::IdentityCertificate>(std::cin);
Yingdi Yu64c3fb42014-02-26 17:30:04 -080092 else
Alexander Afanasyev2fa59392016-07-29 17:24:23 -070093 return ndn::io::load<ndn::security::v1::IdentityCertificate>(fileName);
Yingdi Yu8d7468f2014-02-21 14:49:45 -080094}
95
Yingdi Yu3e8b52e2014-11-26 22:05:00 -080096
97/**
98 * @brief An accumulating option value to handle multiple incrementing options.
99 *
100 * Based on https://gitorious.org/bwy/bwy/source/8753148c324ddfacb1f3cdc315650586bd7b75a4:use/accumulator.hpp
101 * @sa http://benjaminwolsey.de/node/103
102 */
103template<typename T>
104class AccumulatorType : public boost::program_options::value_semantic
105{
106public:
107 explicit
108 AccumulatorType(T* store)
109 : m_store(store)
110 , m_interval(1)
111 , m_default(0)
112 {
113 }
114
115 virtual
116 ~AccumulatorType()
117 {
118 }
119
120 /// @brief Set the default value for this option.
121 AccumulatorType*
122 setDefaultValue(const T& t)
123 {
124 m_default = t;
125 return this;
126 }
127
128 /**
129 * @brief Set the interval for this option.
130 *
131 * Unlike for program_options::value, this specifies a value
132 * to be applied on each occurrence of the option.
133 */
134 AccumulatorType*
135 setInterval(const T& t) {
136 m_interval = t;
137 return this;
138 }
139
Alexander Afanasyev80782e02017-01-04 13:16:54 -0800140 std::string
Davide Pesaventoaa82eb62016-04-22 19:08:40 +0200141 name() const final
Yingdi Yu3e8b52e2014-11-26 22:05:00 -0800142 {
143 return std::string();
144 }
145
146 // There are no tokens for an AccumulatorType
Alexander Afanasyev80782e02017-01-04 13:16:54 -0800147 unsigned
Davide Pesaventoaa82eb62016-04-22 19:08:40 +0200148 min_tokens() const final
Yingdi Yu3e8b52e2014-11-26 22:05:00 -0800149 {
150 return 0;
151 }
152
Alexander Afanasyev80782e02017-01-04 13:16:54 -0800153 unsigned
Davide Pesaventoaa82eb62016-04-22 19:08:40 +0200154 max_tokens() const final
Yingdi Yu3e8b52e2014-11-26 22:05:00 -0800155 {
156 return 0;
157 }
158
159 // Accumulating from different sources is silly.
Alexander Afanasyev80782e02017-01-04 13:16:54 -0800160 bool
Davide Pesaventoaa82eb62016-04-22 19:08:40 +0200161 is_composing() const final
Yingdi Yu3e8b52e2014-11-26 22:05:00 -0800162 {
163 return false;
164 }
165
166 // Requiring one or more appearances is unlikely.
Alexander Afanasyev80782e02017-01-04 13:16:54 -0800167 bool
Davide Pesaventoaa82eb62016-04-22 19:08:40 +0200168 is_required() const final
Yingdi Yu3e8b52e2014-11-26 22:05:00 -0800169 {
170 return false;
171 }
172
173 /**
174 * @brief Parse options
175 *
176 * Every appearance of the option simply increments the value
177 * There should never be any tokens.
178 */
Alexander Afanasyev80782e02017-01-04 13:16:54 -0800179 void
Yingdi Yu3e8b52e2014-11-26 22:05:00 -0800180 parse(boost::any& value_store,
181 const std::vector<std::string>& new_tokens,
Davide Pesaventoaa82eb62016-04-22 19:08:40 +0200182 bool utf8) const final
Yingdi Yu3e8b52e2014-11-26 22:05:00 -0800183 {
184 if (value_store.empty())
185 value_store = T();
186 boost::any_cast<T&>(value_store) += m_interval;
187 }
188
189 /**
190 * @brief If the option doesn't appear, this is the default value.
191 */
Alexander Afanasyev80782e02017-01-04 13:16:54 -0800192 bool
Davide Pesaventoaa82eb62016-04-22 19:08:40 +0200193 apply_default(boost::any& value_store) const final
Yingdi Yu3e8b52e2014-11-26 22:05:00 -0800194 {
195 value_store = m_default;
196 return true;
197 }
198
199 /**
200 * @brief Notify the user function with the value of the value store.
201 */
Alexander Afanasyev80782e02017-01-04 13:16:54 -0800202 void
Davide Pesaventoaa82eb62016-04-22 19:08:40 +0200203 notify(const boost::any& value_store) const final
Yingdi Yu3e8b52e2014-11-26 22:05:00 -0800204 {
205 const T* val = boost::any_cast<T>(&value_store);
206 if (m_store)
207 *m_store = *val;
208 }
209
Alexander Afanasyevae205252015-08-24 14:08:46 -0700210#if BOOST_VERSION >= 105900
Alexander Afanasyev80782e02017-01-04 13:16:54 -0800211 bool
Davide Pesaventoaa82eb62016-04-22 19:08:40 +0200212 adjacent_tokens_only() const final
Alexander Afanasyevae205252015-08-24 14:08:46 -0700213 {
214 return false;
215 }
216#endif // BOOST_VERSION >= 105900
217
Yingdi Yu3e8b52e2014-11-26 22:05:00 -0800218private:
219 T* m_store;
220 T m_interval;
221 T m_default;
222};
223
224template<typename T>
225AccumulatorType<T>* accumulator()
226{
227 return new AccumulatorType<T>(0);
228}
229
230template<typename T>
231AccumulatorType<T>* accumulator(T* store)
232{
233 return new AccumulatorType<T>(store);
234}
235
Alexander Afanasyevd7db8bf2015-01-04 15:31:02 -0800236#endif // NDN_TOOLS_NDNSEC_UTIL_HPP