blob: 2de9ff1bec0424d159720e11fa616bfbd1147fcd [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 Afanasyevaf99f462015-01-19 21:43:09 -08003 * Copyright (c) 2013-2015 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
40
Junxiao Shi482ccc52014-03-31 13:05:24 -070041#include "security/cryptopp.hpp"
Yingdi Yu8d7468f2014-02-21 14:49:45 -080042
43#include "security/key-chain.hpp"
Yingdi Yu64c3fb42014-02-26 17:30:04 -080044#include "util/io.hpp"
Yingdi Yu8d7468f2014-02-21 14:49:45 -080045
46bool
47getPassword(std::string& password, const std::string& prompt)
48{
Alexander Afanasyeva2ada222015-01-22 18:34:16 -080049#ifndef NDN_CXX_HAVE_GETPASS
Yingdi Yub61f5402014-02-26 17:46:11 -080050 bool isReady = false;
Yingdi Yu8d7468f2014-02-21 14:49:45 -080051
Yingdi Yub61f5402014-02-26 17:46:11 -080052 char* pw0 = 0;
Alexander Afanasyevdfa52c42014-04-24 21:10:11 -070053
Yingdi Yu8d7468f2014-02-21 14:49:45 -080054 pw0 = getpass(prompt.c_str());
Alexander Afanasyevdfa52c42014-04-24 21:10:11 -070055 if (!pw0)
Yingdi Yu8d7468f2014-02-21 14:49:45 -080056 return false;
57 std::string password1 = pw0;
58 memset(pw0, 0, strlen(pw0));
59
60 pw0 = getpass("Confirm:");
Yingdi Yub61f5402014-02-26 17:46:11 -080061 if (!pw0)
Yingdi Yu8d7468f2014-02-21 14:49:45 -080062 {
63 char* pw1 = const_cast<char*>(password1.c_str());
64 memset(pw1, 0, password1.size());
65 return false;
66 }
67
Yingdi Yub61f5402014-02-26 17:46:11 -080068 if (!password1.compare(pw0))
Yingdi Yu8d7468f2014-02-21 14:49:45 -080069 {
Yingdi Yub61f5402014-02-26 17:46:11 -080070 isReady = true;
Yingdi Yu8d7468f2014-02-21 14:49:45 -080071 password.swap(password1);
72 }
73
74 char* pw1 = const_cast<char*>(password1.c_str());
75 memset(pw1, 0, password1.size());
76 memset(pw0, 0, strlen(pw0));
77
Yingdi Yub61f5402014-02-26 17:46:11 -080078 if (password.empty())
Yingdi Yu8d7468f2014-02-21 14:49:45 -080079 return false;
80
Yingdi Yub61f5402014-02-26 17:46:11 -080081 return isReady;
Alexander Afanasyeva2ada222015-01-22 18:34:16 -080082#else
83 return false;
84#endif // NDN_CXX_HAVE_GETPASS
Yingdi Yu8d7468f2014-02-21 14:49:45 -080085}
86
87ndn::shared_ptr<ndn::IdentityCertificate>
88getIdentityCertificate(const std::string& fileName)
89{
Yingdi Yu8d7468f2014-02-21 14:49:45 -080090
Yingdi Yub61f5402014-02-26 17:46:11 -080091 if (fileName == "-")
Yingdi Yu64c3fb42014-02-26 17:30:04 -080092 return ndn::io::load<ndn::IdentityCertificate>(std::cin);
93 else
94 return ndn::io::load<ndn::IdentityCertificate>(fileName);
Yingdi Yu8d7468f2014-02-21 14:49:45 -080095}
96
Yingdi Yu3e8b52e2014-11-26 22:05:00 -080097
98/**
99 * @brief An accumulating option value to handle multiple incrementing options.
100 *
101 * Based on https://gitorious.org/bwy/bwy/source/8753148c324ddfacb1f3cdc315650586bd7b75a4:use/accumulator.hpp
102 * @sa http://benjaminwolsey.de/node/103
103 */
104template<typename T>
105class AccumulatorType : public boost::program_options::value_semantic
106{
107public:
108 explicit
109 AccumulatorType(T* store)
110 : m_store(store)
111 , m_interval(1)
112 , m_default(0)
113 {
114 }
115
116 virtual
117 ~AccumulatorType()
118 {
119 }
120
121 /// @brief Set the default value for this option.
122 AccumulatorType*
123 setDefaultValue(const T& t)
124 {
125 m_default = t;
126 return this;
127 }
128
129 /**
130 * @brief Set the interval for this option.
131 *
132 * Unlike for program_options::value, this specifies a value
133 * to be applied on each occurrence of the option.
134 */
135 AccumulatorType*
136 setInterval(const T& t) {
137 m_interval = t;
138 return this;
139 }
140
141 virtual std::string
142 name() const
143 {
144 return std::string();
145 }
146
147 // There are no tokens for an AccumulatorType
148 virtual unsigned
149 min_tokens() const
150 {
151 return 0;
152 }
153
154 virtual unsigned
155 max_tokens() const
156 {
157 return 0;
158 }
159
160 // Accumulating from different sources is silly.
161 virtual bool
162 is_composing() const
163 {
164 return false;
165 }
166
167 // Requiring one or more appearances is unlikely.
168 virtual bool
169 is_required() const
170 {
171 return false;
172 }
173
174 /**
175 * @brief Parse options
176 *
177 * Every appearance of the option simply increments the value
178 * There should never be any tokens.
179 */
180 virtual void
181 parse(boost::any& value_store,
182 const std::vector<std::string>& new_tokens,
183 bool utf8) const
184 {
185 if (value_store.empty())
186 value_store = T();
187 boost::any_cast<T&>(value_store) += m_interval;
188 }
189
190 /**
191 * @brief If the option doesn't appear, this is the default value.
192 */
193 virtual bool
194 apply_default(boost::any& value_store) const
195 {
196 value_store = m_default;
197 return true;
198 }
199
200 /**
201 * @brief Notify the user function with the value of the value store.
202 */
203 virtual void
204 notify(const boost::any& value_store) const
205 {
206 const T* val = boost::any_cast<T>(&value_store);
207 if (m_store)
208 *m_store = *val;
209 }
210
211private:
212 T* m_store;
213 T m_interval;
214 T m_default;
215};
216
217template<typename T>
218AccumulatorType<T>* accumulator()
219{
220 return new AccumulatorType<T>(0);
221}
222
223template<typename T>
224AccumulatorType<T>* accumulator(T* store)
225{
226 return new AccumulatorType<T>(store);
227}
228
Alexander Afanasyevd7db8bf2015-01-04 15:31:02 -0800229#endif // NDN_TOOLS_NDNSEC_UTIL_HPP