blob: 696d3489967da3fe08adef60aebcddc2a95a9777 [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/**
Davide Pesaventoaa82eb62016-04-22 19:08:40 +02003 * Copyright (c) 2013-2016 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
Yingdi Yu8d7468f2014-02-21 14:49:45 -080040#include "security/key-chain.hpp"
Yingdi Yu64c3fb42014-02-26 17:30:04 -080041#include "util/io.hpp"
Yingdi Yu8d7468f2014-02-21 14:49:45 -080042
43bool
44getPassword(std::string& password, const std::string& prompt)
45{
Alexander Afanasyevcf3a6672015-02-01 20:33:22 -080046#ifdef NDN_CXX_HAVE_GETPASS
Yingdi Yub61f5402014-02-26 17:46:11 -080047 bool isReady = false;
Yingdi Yu8d7468f2014-02-21 14:49:45 -080048
Yingdi Yub61f5402014-02-26 17:46:11 -080049 char* pw0 = 0;
Alexander Afanasyevdfa52c42014-04-24 21:10:11 -070050
Yingdi Yu8d7468f2014-02-21 14:49:45 -080051 pw0 = getpass(prompt.c_str());
Alexander Afanasyevdfa52c42014-04-24 21:10:11 -070052 if (!pw0)
Yingdi Yu8d7468f2014-02-21 14:49:45 -080053 return false;
54 std::string password1 = pw0;
55 memset(pw0, 0, strlen(pw0));
56
57 pw0 = getpass("Confirm:");
Yingdi Yub61f5402014-02-26 17:46:11 -080058 if (!pw0)
Yingdi Yu8d7468f2014-02-21 14:49:45 -080059 {
60 char* pw1 = const_cast<char*>(password1.c_str());
61 memset(pw1, 0, password1.size());
62 return false;
63 }
64
Yingdi Yub61f5402014-02-26 17:46:11 -080065 if (!password1.compare(pw0))
Yingdi Yu8d7468f2014-02-21 14:49:45 -080066 {
Yingdi Yub61f5402014-02-26 17:46:11 -080067 isReady = true;
Yingdi Yu8d7468f2014-02-21 14:49:45 -080068 password.swap(password1);
69 }
70
71 char* pw1 = const_cast<char*>(password1.c_str());
72 memset(pw1, 0, password1.size());
73 memset(pw0, 0, strlen(pw0));
74
Yingdi Yub61f5402014-02-26 17:46:11 -080075 if (password.empty())
Yingdi Yu8d7468f2014-02-21 14:49:45 -080076 return false;
77
Yingdi Yub61f5402014-02-26 17:46:11 -080078 return isReady;
Alexander Afanasyeva2ada222015-01-22 18:34:16 -080079#else
80 return false;
81#endif // NDN_CXX_HAVE_GETPASS
Yingdi Yu8d7468f2014-02-21 14:49:45 -080082}
83
Alexander Afanasyev2fa59392016-07-29 17:24:23 -070084ndn::shared_ptr<ndn::security::v1::IdentityCertificate>
Yingdi Yu8d7468f2014-02-21 14:49:45 -080085getIdentityCertificate(const std::string& fileName)
86{
Yingdi Yu8d7468f2014-02-21 14:49:45 -080087
Yingdi Yub61f5402014-02-26 17:46:11 -080088 if (fileName == "-")
Alexander Afanasyev2fa59392016-07-29 17:24:23 -070089 return ndn::io::load<ndn::security::v1::IdentityCertificate>(std::cin);
Yingdi Yu64c3fb42014-02-26 17:30:04 -080090 else
Alexander Afanasyev2fa59392016-07-29 17:24:23 -070091 return ndn::io::load<ndn::security::v1::IdentityCertificate>(fileName);
Yingdi Yu8d7468f2014-02-21 14:49:45 -080092}
93
Yingdi Yu3e8b52e2014-11-26 22:05:00 -080094
95/**
96 * @brief An accumulating option value to handle multiple incrementing options.
97 *
98 * Based on https://gitorious.org/bwy/bwy/source/8753148c324ddfacb1f3cdc315650586bd7b75a4:use/accumulator.hpp
99 * @sa http://benjaminwolsey.de/node/103
100 */
101template<typename T>
102class AccumulatorType : public boost::program_options::value_semantic
103{
104public:
105 explicit
106 AccumulatorType(T* store)
107 : m_store(store)
108 , m_interval(1)
109 , m_default(0)
110 {
111 }
112
113 virtual
114 ~AccumulatorType()
115 {
116 }
117
118 /// @brief Set the default value for this option.
119 AccumulatorType*
120 setDefaultValue(const T& t)
121 {
122 m_default = t;
123 return this;
124 }
125
126 /**
127 * @brief Set the interval for this option.
128 *
129 * Unlike for program_options::value, this specifies a value
130 * to be applied on each occurrence of the option.
131 */
132 AccumulatorType*
133 setInterval(const T& t) {
134 m_interval = t;
135 return this;
136 }
137
138 virtual std::string
Davide Pesaventoaa82eb62016-04-22 19:08:40 +0200139 name() const final
Yingdi Yu3e8b52e2014-11-26 22:05:00 -0800140 {
141 return std::string();
142 }
143
144 // There are no tokens for an AccumulatorType
145 virtual unsigned
Davide Pesaventoaa82eb62016-04-22 19:08:40 +0200146 min_tokens() const final
Yingdi Yu3e8b52e2014-11-26 22:05:00 -0800147 {
148 return 0;
149 }
150
151 virtual unsigned
Davide Pesaventoaa82eb62016-04-22 19:08:40 +0200152 max_tokens() const final
Yingdi Yu3e8b52e2014-11-26 22:05:00 -0800153 {
154 return 0;
155 }
156
157 // Accumulating from different sources is silly.
158 virtual bool
Davide Pesaventoaa82eb62016-04-22 19:08:40 +0200159 is_composing() const final
Yingdi Yu3e8b52e2014-11-26 22:05:00 -0800160 {
161 return false;
162 }
163
164 // Requiring one or more appearances is unlikely.
165 virtual bool
Davide Pesaventoaa82eb62016-04-22 19:08:40 +0200166 is_required() const final
Yingdi Yu3e8b52e2014-11-26 22:05:00 -0800167 {
168 return false;
169 }
170
171 /**
172 * @brief Parse options
173 *
174 * Every appearance of the option simply increments the value
175 * There should never be any tokens.
176 */
177 virtual void
178 parse(boost::any& value_store,
179 const std::vector<std::string>& new_tokens,
Davide Pesaventoaa82eb62016-04-22 19:08:40 +0200180 bool utf8) const final
Yingdi Yu3e8b52e2014-11-26 22:05:00 -0800181 {
182 if (value_store.empty())
183 value_store = T();
184 boost::any_cast<T&>(value_store) += m_interval;
185 }
186
187 /**
188 * @brief If the option doesn't appear, this is the default value.
189 */
190 virtual bool
Davide Pesaventoaa82eb62016-04-22 19:08:40 +0200191 apply_default(boost::any& value_store) const final
Yingdi Yu3e8b52e2014-11-26 22:05:00 -0800192 {
193 value_store = m_default;
194 return true;
195 }
196
197 /**
198 * @brief Notify the user function with the value of the value store.
199 */
200 virtual void
Davide Pesaventoaa82eb62016-04-22 19:08:40 +0200201 notify(const boost::any& value_store) const final
Yingdi Yu3e8b52e2014-11-26 22:05:00 -0800202 {
203 const T* val = boost::any_cast<T>(&value_store);
204 if (m_store)
205 *m_store = *val;
206 }
207
Alexander Afanasyevae205252015-08-24 14:08:46 -0700208#if BOOST_VERSION >= 105900
209 virtual bool
Davide Pesaventoaa82eb62016-04-22 19:08:40 +0200210 adjacent_tokens_only() const final
Alexander Afanasyevae205252015-08-24 14:08:46 -0700211 {
212 return false;
213 }
214#endif // BOOST_VERSION >= 105900
215
Yingdi Yu3e8b52e2014-11-26 22:05:00 -0800216private:
217 T* m_store;
218 T m_interval;
219 T m_default;
220};
221
222template<typename T>
223AccumulatorType<T>* accumulator()
224{
225 return new AccumulatorType<T>(0);
226}
227
228template<typename T>
229AccumulatorType<T>* accumulator(T* store)
230{
231 return new AccumulatorType<T>(store);
232}
233
Alexander Afanasyevd7db8bf2015-01-04 15:31:02 -0800234#endif // NDN_TOOLS_NDNSEC_UTIL_HPP