1 /* 2 * Copyright (C) 2018 Rafael Ostertag 3 * 4 * This file is part of YAPET. 5 * 6 * YAPET is free software: you can redistribute it and/or modify it under the 7 * terms of the GNU General Public License as published by the Free Software 8 * Foundation, either version 3 of the License, or (at your option) any later 9 * version. 10 * 11 * YAPET is distributed in the hope that it will be useful, but WITHOUT ANY 12 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 13 * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more 14 * details. 15 * 16 * You should have received a copy of the GNU General Public License along with 17 * YAPET. If not, see <http://www.gnu.org/licenses/>. 18 * 19 * Additional permission under GNU GPL version 3 section 7 20 * 21 * If you modify this program, or any covered work, by linking or combining it 22 * with the OpenSSL project's OpenSSL library (or a modified version of that 23 * library), containing parts covered by the terms of the OpenSSL or SSLeay 24 * licenses, Rafael Ostertag grants you additional permission to convey the 25 * resulting work. Corresponding Source for a non-source form of such a 26 * combination shall include the source code for the parts of OpenSSL used as 27 * well as that of the covered work. 28 */ 29 30 #ifndef _CFG_H 31 #define _CFG_H 1 32 33 #ifdef HAVE_CONFIG_H 34 #include "config.h" 35 #endif 36 37 #include <algorithm> 38 #include <cassert> 39 #include <functional> 40 #include <limits> 41 #include <map> 42 #include <sstream> 43 #include <string> 44 45 #include <sys/types.h> 46 47 #include "cfgfile.h" 48 #include "consts.h" 49 #include "rng.hh" 50 51 namespace YAPET { 52 namespace CONFIG { 53 extern std::string trim(const std::string& s); 54 extern std::string getHomeDir(); 55 56 namespace INTERNAL { 57 // Wrapper function object which returns bool so that it 58 // can be used by *_if algorithms 59 class IntIsTrue { 60 std::pointer_to_unary_function<int, int> __f; 61 62 public: IntIsTrue(std::pointer_to_unary_function<int,int> _f)63 IntIsTrue(std::pointer_to_unary_function<int, int> _f) : __f(_f) {} operator()64 bool operator()(int i) { return std::not_equal_to<int>()(0, __f(i)); } 65 }; 66 67 // Wrapper function object which returns bool so that it 68 // can be used by *_if algorithms 69 class IntIsFalse { 70 std::pointer_to_unary_function<int, int> __f; 71 72 public: IntIsFalse(std::pointer_to_unary_function<int,int> _f)73 IntIsFalse(std::pointer_to_unary_function<int, int> _f) : __f(_f) {} operator()74 bool operator()(int i) { return std::equal_to<int>()(0, __f(i)); } 75 }; 76 } // namespace INTERNAL 77 78 class CfgValBase { 79 public: 80 virtual void set_str(const std::string&) = 0; ~CfgValBase()81 virtual ~CfgValBase() {} 82 }; 83 84 /** 85 * @brief template class used for configuration values 86 * 87 * This template class is mainly used for configuration 88 * values. It allows the values being locked, i.e. preventing 89 * the values being changed by set methods. 90 */ 91 template <class T> 92 class CfgVal : public CfgValBase { 93 private: 94 //! Indicates whether or not the value can be changed. 95 bool locked; 96 T val; 97 98 protected: remove_space(const std::string & str)99 std::string remove_space(const std::string& str) { 100 std::string space_clean(str); 101 102 INTERNAL::IntIsTrue space(std::ptr_fun<int, int>(std::isspace)); 103 104 std::string::iterator new_end = 105 std::remove_if(space_clean.begin(), space_clean.end(), space); 106 107 if (new_end == space_clean.end()) return space_clean; 108 109 space_clean.erase(new_end, space_clean.end()); 110 111 return space_clean; 112 } 113 tolower(const std::string & str)114 std::string tolower(const std::string& str) { 115 std::string lower(str); 116 std::transform(lower.begin(), lower.end(), lower.begin(), 117 std::ptr_fun<int, int>(std::tolower)); 118 119 return lower; 120 } 121 122 public: 123 typedef T type; 124 CfgVal()125 CfgVal() : locked(false) {} 126 CfgVal(const T & v)127 CfgVal(const T& v) : locked(false), val(v) {} 128 CfgVal(const CfgVal & c)129 CfgVal(const CfgVal& c) : locked(c.locked), val(c.val) {} 130 131 CfgVal& operator=(const CfgVal& c) { 132 if (&c == this) return *this; 133 134 locked = c.locked; 135 val = c.val; 136 137 return *this; 138 } 139 140 CfgVal& operator=(const T& c) { 141 if (!locked) val = c; 142 143 return *this; 144 } 145 set(const T & v)146 virtual void set(const T& v) { 147 if (!locked) val = v; 148 } 149 get()150 virtual T get() const { return val; } 151 lock()152 void lock() { locked = true; } 153 unlock()154 void unlock() { locked = false; } 155 is_locked()156 bool is_locked() const { return locked; } 157 T()158 operator T() const { return val; } 159 }; 160 161 typedef CfgVal<std::string> CfgValStr; 162 163 class CfgValPetFile : public CfgValStr { 164 private: 165 std::string cleanup_path(const std::string& p); 166 std::string add_suffix(const std::string& p); 167 168 public: 169 CfgValPetFile(std::string v = std::string()) CfgValStr(add_suffix (cleanup_path (v)))170 : CfgValStr(add_suffix(cleanup_path(v))) {} CfgValPetFile(const CfgValPetFile & cv)171 CfgValPetFile(const CfgValPetFile& cv) : CfgValStr(cv) {} 172 CfgValPetFile& operator=(const CfgValPetFile& cv) { 173 CfgValStr::operator=(cv); 174 return *this; 175 } 176 CfgValPetFile& operator=(const std::string b) { 177 CfgValStr::operator=(b); 178 return *this; 179 } 180 181 void set(const std::string& s); 182 void set_str(const std::string& s); 183 }; 184 185 class CfgValBool : public CfgVal<bool> { 186 public: 187 CfgValBool(bool v = true) : CfgVal<bool>(v) {} CfgValBool(const CfgValBool & cv)188 CfgValBool(const CfgValBool& cv) : CfgVal<bool>(cv) {} 189 CfgValBool& operator=(const CfgValBool& cv) { 190 CfgVal<bool>::operator=(cv); 191 return *this; 192 } 193 CfgValBool& operator=(const bool b) { 194 CfgVal<bool>::operator=(b); 195 return *this; 196 } 197 198 void set_str(const std::string& s); 199 }; 200 201 class CfgValInt : public CfgVal<int> { 202 private: 203 int __min; 204 int __max; 205 int __def_out_of_bounds; 206 207 public: 208 CfgValInt(int v = 0, int def_out_of_bounds = 0, 209 int min = std::numeric_limits<int>::min(), 210 int max = std::numeric_limits<int>::max()) 211 : CfgVal<int>(v < min || v > max ? def_out_of_bounds : v), 212 __min(min), 213 __max(max), 214 __def_out_of_bounds(def_out_of_bounds) { 215 assert(__def_out_of_bounds >= __min); 216 assert(__def_out_of_bounds <= __max); 217 } CfgValInt(const CfgValInt & cv)218 CfgValInt(const CfgValInt& cv) : CfgVal<int>(cv) {} 219 CfgValInt& operator=(const CfgValInt& cv) { 220 CfgVal<int>::operator=(cv); 221 return *this; 222 } 223 CfgValInt& operator=(const int b) { 224 CfgVal<int>::operator=(b); 225 return *this; 226 } 227 set(const int & i)228 void set(const int& i) { 229 CfgVal<int>::set(i < __min || i > __max ? __def_out_of_bounds : i); 230 } 231 232 void set_str(const std::string& s); 233 string()234 operator std::string() const { 235 std::ostringstream conv; 236 conv << get(); 237 return conv.str(); 238 } 239 }; 240 241 class CfgValColor : public CfgValStr { 242 public: set_str(const std::string & s)243 void set_str(const std::string& s) { set(s); } 244 }; 245 246 /** 247 * @brief Handle the command line and config file options. 248 * 249 * This class handles the command line and config file options. 250 */ 251 class Config { 252 private: 253 // mainly used by ConfigFile; 254 std::map<std::string, CfgValBase*> _options; 255 //! Removes two or more consecutive slashes from the path 256 std::string cleanupPath(const std::string& s) const; 257 258 void setup_map(); 259 260 public: 261 CfgValPetFile petfile; 262 /// @todo rename to locktimeout 263 CfgValInt timeout; 264 CfgValBool filesecurity; 265 CfgValInt pwgenpwlen; 266 CfgValBool pwgen_letters; 267 CfgValBool pwgen_digits; 268 CfgValBool pwgen_punct; 269 CfgValBool pwgen_special; 270 CfgValBool pwgen_other; 271 CfgValBool allow_lock_quit; 272 CfgValInt pw_input_timeout; 273 // in kibi 274 CfgValInt argon2_memory; 275 CfgValInt argon2_parallelism; 276 CfgValInt argon2_iterations; 277 CfgValBool ignorerc; 278 CfgValColor colors; 279 280 Config(); 281 Config(const Config& c); 282 Config(Config&& c) = delete; 283 ~Config(); 284 285 Config& operator=(Config&& c) = delete; 286 Config& operator=(const Config& c); 287 288 /** 289 * Convenience method. 290 * 291 * @return @c int representing all selected character 292 * pools. 293 */ 294 int character_pools() const; 295 296 //! Lock all configuration values 297 void lock(); 298 299 //! Unlock all configuration values 300 void unlock(); 301 302 CfgValBase& operator[](const std::string& key); 303 }; 304 } // namespace CONFIG 305 } // namespace YAPET 306 307 #endif // _CFG_H 308