blob: 14ddf4849aeb69e03fe3f2e07ab57321bc968f68 [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 Afanasyevc169a812014-05-20 20:37:29 -04003 * Copyright (c) 2013-2014 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
24#ifndef NDNSEC_UTIL_HPP
25#define NDNSEC_UTIL_HPP
26
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{
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;
Yingdi Yu8d7468f2014-02-21 14:49:45 -080081}
82
83ndn::shared_ptr<ndn::IdentityCertificate>
84getIdentityCertificate(const std::string& fileName)
85{
Yingdi Yu8d7468f2014-02-21 14:49:45 -080086
Yingdi Yub61f5402014-02-26 17:46:11 -080087 if (fileName == "-")
Yingdi Yu64c3fb42014-02-26 17:30:04 -080088 return ndn::io::load<ndn::IdentityCertificate>(std::cin);
89 else
90 return ndn::io::load<ndn::IdentityCertificate>(fileName);
Yingdi Yu8d7468f2014-02-21 14:49:45 -080091}
92
Yingdi Yu3e8b52e2014-11-26 22:05:00 -080093
94/**
95 * @brief An accumulating option value to handle multiple incrementing options.
96 *
97 * Based on https://gitorious.org/bwy/bwy/source/8753148c324ddfacb1f3cdc315650586bd7b75a4:use/accumulator.hpp
98 * @sa http://benjaminwolsey.de/node/103
99 */
100template<typename T>
101class AccumulatorType : public boost::program_options::value_semantic
102{
103public:
104 explicit
105 AccumulatorType(T* store)
106 : m_store(store)
107 , m_interval(1)
108 , m_default(0)
109 {
110 }
111
112 virtual
113 ~AccumulatorType()
114 {
115 }
116
117 /// @brief Set the default value for this option.
118 AccumulatorType*
119 setDefaultValue(const T& t)
120 {
121 m_default = t;
122 return this;
123 }
124
125 /**
126 * @brief Set the interval for this option.
127 *
128 * Unlike for program_options::value, this specifies a value
129 * to be applied on each occurrence of the option.
130 */
131 AccumulatorType*
132 setInterval(const T& t) {
133 m_interval = t;
134 return this;
135 }
136
137 virtual std::string
138 name() const
139 {
140 return std::string();
141 }
142
143 // There are no tokens for an AccumulatorType
144 virtual unsigned
145 min_tokens() const
146 {
147 return 0;
148 }
149
150 virtual unsigned
151 max_tokens() const
152 {
153 return 0;
154 }
155
156 // Accumulating from different sources is silly.
157 virtual bool
158 is_composing() const
159 {
160 return false;
161 }
162
163 // Requiring one or more appearances is unlikely.
164 virtual bool
165 is_required() const
166 {
167 return false;
168 }
169
170 /**
171 * @brief Parse options
172 *
173 * Every appearance of the option simply increments the value
174 * There should never be any tokens.
175 */
176 virtual void
177 parse(boost::any& value_store,
178 const std::vector<std::string>& new_tokens,
179 bool utf8) const
180 {
181 if (value_store.empty())
182 value_store = T();
183 boost::any_cast<T&>(value_store) += m_interval;
184 }
185
186 /**
187 * @brief If the option doesn't appear, this is the default value.
188 */
189 virtual bool
190 apply_default(boost::any& value_store) const
191 {
192 value_store = m_default;
193 return true;
194 }
195
196 /**
197 * @brief Notify the user function with the value of the value store.
198 */
199 virtual void
200 notify(const boost::any& value_store) const
201 {
202 const T* val = boost::any_cast<T>(&value_store);
203 if (m_store)
204 *m_store = *val;
205 }
206
207private:
208 T* m_store;
209 T m_interval;
210 T m_default;
211};
212
213template<typename T>
214AccumulatorType<T>* accumulator()
215{
216 return new AccumulatorType<T>(0);
217}
218
219template<typename T>
220AccumulatorType<T>* accumulator(T* store)
221{
222 return new AccumulatorType<T>(store);
223}
224
225#endif // NDNSEC_UTIL_HPP