diff --git a/libretroshare/src/pqi/authgpg.cc b/libretroshare/src/pqi/authgpg.cc index 6eca8538a..61cb7886e 100644 --- a/libretroshare/src/pqi/authgpg.cc +++ b/libretroshare/src/pqi/authgpg.cc @@ -92,7 +92,7 @@ std::string pgp_pwd_callback(void * /*hook*/, const char *uid_hint, const char * fprintf(stderr, "pgp_pwd_callback() called.\n"); #endif std::string password; - rsicontrol->getNotify().askForPassword(uid_hint, prev_was_bad, password) ; + rsicontrol->getNotify().askForPassword(std::string("Please enter your PGP password for key ")+uid_hint+" :", prev_was_bad, password) ; return password ; } diff --git a/libretroshare/src/rsserver/rsinit.cc b/libretroshare/src/rsserver/rsinit.cc index c009de129..3a8bf1420 100644 --- a/libretroshare/src/rsserver/rsinit.cc +++ b/libretroshare/src/rsserver/rsinit.cc @@ -35,6 +35,7 @@ #include "util/rswin.h" #endif +#include "util/argstream.h" #include "util/rsdebug.h" #include "util/rsdir.h" #include "util/rsrandom.h" @@ -122,12 +123,11 @@ class RsInitConfig static bool forceExtPort; static bool forceLocalAddr; static unsigned short port; - static char inet[256]; + static std::string inet ; /* Logging */ static bool haveLogFile; static bool outStderr; - static bool haveDebugLevel; static int debugLevel; static std::string logfname; @@ -183,12 +183,11 @@ bool RsInitConfig::isWindowsXP = false; bool RsInitConfig::forceExtPort; bool RsInitConfig::forceLocalAddr; unsigned short RsInitConfig::port; -char RsInitConfig::inet[256]; +std::string RsInitConfig::inet; /* Logging */ bool RsInitConfig::haveLogFile; bool RsInitConfig::outStderr; -bool RsInitConfig::haveDebugLevel; int RsInitConfig::debugLevel; std::string RsInitConfig::logfname; @@ -220,12 +219,11 @@ void RsInit::InitRsConfig() RsInitConfig::outStderr = false; RsInitConfig::forceExtPort = false; - strcpy(RsInitConfig::inet, "127.0.0.1"); + RsInitConfig::inet = std::string("127.0.0.1"); RsInitConfig::autoLogin = false; // . RsInitConfig::startMinimised = false; RsInitConfig::passwd = ""; - RsInitConfig::haveDebugLevel = false; RsInitConfig::debugLevel = PQL_WARNING; RsInitConfig::udpListenerOnly = false; @@ -330,19 +328,12 @@ int RsInit::InitRetroShare(int argcIgnored, char **argvIgnored, bool strictCheck { /* THIS IS A HACK TO ALLOW WINDOWS TO ACCEPT COMMANDLINE ARGUMENTS */ - - - - int argc; int i; #ifdef USE_CMD_ARGS char** argv = argvIgnored; argc = argcIgnored; - - #else - const int MAX_ARGS = 32; int j; char *argv[MAX_ARGS]; @@ -368,24 +359,16 @@ int RsInit::InitRetroShare(int argcIgnored, char **argvIgnored, bool strictCheck } } argc = i; - #endif for( i=0; i> option('a',"auto-login" ,RsInitConfig::autoLogin ,"AutoLogin (Windows Only) + StartMinimised") + >> option('m',"minimized" ,RsInitConfig::startMinimised ,"Start minimized." ) + >> option('s',"stderr" ,RsInitConfig::outStderr ,"output to stderr instead of log file." ) + >> option('u',"udp" ,RsInitConfig::udpListenerOnly,"Only listen to UDP." ) + >> option('e',"external-port" ,RsInitConfig::forceExtPort ,"Use a forwarded external port." ) + + >> parameter('l',"log-file" ,RsInitConfig::logfname ,"logfile" ,"Set Log filename." ,false) + >> parameter('d',"debug-level" ,RsInitConfig::debugLevel ,"level" ,"Set debug level." ,false) + >> parameter('w',"password" ,RsInitConfig::passwd ,"password" ,"Set Login Password." ,false) + >> parameter('i',"ip-address" ,RsInitConfig::inet ,"nnn.nnn.nnn.nnn", "Set IP address to use." ,false) + >> parameter('p',"port" ,RsInitConfig::port ,"port", "Set listenning port to use." ,false) + >> parameter('c',"base-dir" ,RsInitConfig::basedir ,"directory", "Set base directory." ,false) + >> parameter('U',"user-id" ,prefUserString ,"ID", "[User Name/GPG id/SSL id] Sets Account to Use, Useful when Autologin is enabled",false) + >> parameter('r',"link" ,RsInitConfig::RetroShareLink ,"retroshare://...", "Use a given Retroshare Link" ,false) +#ifdef LOCALNET_TESTING + >> parameter('R',"restrict-port" ,portRestrictions ,"port1-port2","Apply port restriction" ,false) +#endif + >> help() ; + + as.defaultErrorHandling(true) ; + + if(RsInitConfig::autoLogin) RsInitConfig::startMinimised = true ; + if(RsInitConfig::outStderr) RsInitConfig::haveLogFile = false ; + if(!RsInitConfig::logfname.empty()) RsInitConfig::haveLogFile = true; + if(!RsInitConfig::inet.empty()) RsInitConfig::forceLocalAddr = true; +#ifdef LOCALNET_TESTING + if(!portRestrictions.empty()) doPortRestrictions = true; +#endif + +#ifdef SUSPENDED_CODE #ifdef LOCALNET_TESTING while((c = getopt(argc, argv,"hesamui:p:c:w:l:d:U:r:R:")) != -1) #else @@ -402,85 +420,6 @@ int RsInit::InitRetroShare(int argcIgnored, char **argvIgnored, bool strictCheck { switch (c) { - case 'a': - RsInitConfig::autoLogin = true; - RsInitConfig::startMinimised = true; - std::cerr << "AutoLogin Allowed / Start Minimised On"; - std::cerr << std::endl; - break; - case 'm': - RsInitConfig::startMinimised = true; - std::cerr << "Start Minimised On"; - std::cerr << std::endl; - break; - case 'l': - RsInitConfig::logfname = optarg; - std::cerr << "LogFile (" << RsInitConfig::logfname; - std::cerr << ") Selected" << std::endl; - RsInitConfig::haveLogFile = true; - break; - case 'w': - RsInitConfig::passwd = optarg; - std::cerr << "Password Specified(********" ; //<< RsInitConfig::passwd; - std::cerr << ") Selected" << std::endl; - break; - case 'i': - strncpy(RsInitConfig::inet, optarg, 256); - std::cerr << "New Inet Addr(" << RsInitConfig::inet; - std::cerr << ") Selected" << std::endl; - RsInitConfig::forceLocalAddr = true; - break; - case 'p': - RsInitConfig::port = atoi(optarg); - std::cerr << "New Listening Port(" << RsInitConfig::port; - std::cerr << ") Selected" << std::endl; - break; - case 'c': - RsInitConfig::basedir = optarg; - std::cerr << "New Base Config Dir("; - std::cerr << RsInitConfig::basedir; - std::cerr << ") Selected" << std::endl; - break; - case 's': - RsInitConfig::outStderr = true; - RsInitConfig::haveLogFile = false; - std::cerr << "Output to Stderr"; - std::cerr << std::endl; - break; - case 'd': - RsInitConfig::haveDebugLevel = true; - RsInitConfig::debugLevel = atoi(optarg); - std::cerr << "Opt for new Debug Level"; - std::cerr << std::endl; - break; - case 'u': - RsInitConfig::udpListenerOnly = true; - std::cerr << "Opt for only udpListener"; - std::cerr << std::endl; - break; - case 'e': - RsInitConfig::forceExtPort = true; - std::cerr << "Opt for External Port Mode"; - std::cerr << std::endl; - break; - case 'U': - prefUserString = optarg; - std::cerr << "Opt for User Id "; - std::cerr << std::endl; - break; - case 'r': - RsInitConfig::RetroShareLink = optarg; - std::cerr << "Opt for RetroShare link"; - std::cerr << std::endl; - break; -#ifdef LOCALNET_TESTING - case 'R': - portRestrictions = optarg; - doPortRestrictions = true; - std::cerr << "Opt for Port Restrictions"; - std::cerr << std::endl; - break; -#endif case 'h': std::cerr << "Help: " << std::endl; std::cerr << "The commandline options are for retroshare-nogui, a headless server in a shell, or systems without QT." << std::endl << std::endl; @@ -510,32 +449,31 @@ int RsInit::InitRetroShare(int argcIgnored, char **argvIgnored, bool strictCheck } } } +#endif + setOutputLevel(RsInitConfig::debugLevel); - // set the default Debug Level... - if (RsInitConfig::haveDebugLevel) - { - if ((RsInitConfig::debugLevel > 0) && - (RsInitConfig::debugLevel <= PQL_DEBUG_ALL)) - { - std::cerr << "Setting Debug Level to: "; - std::cerr << RsInitConfig::debugLevel; - std::cerr << std::endl; - setOutputLevel(RsInitConfig::debugLevel); - } - else - { - std::cerr << "Ignoring Invalid Debug Level: "; - std::cerr << RsInitConfig::debugLevel; - std::cerr << std::endl; - } - } +// // set the default Debug Level... +// if (RsInitConfig::haveDebugLevel) +// { +// if ((RsInitConfig::debugLevel > 0) && +// (RsInitConfig::debugLevel <= PQL_DEBUG_ALL)) +// { +// std::cerr << "Setting Debug Level to: "; +// std::cerr << RsInitConfig::debugLevel; +// std::cerr << std::endl; +// } +// else +// { +// std::cerr << "Ignoring Invalid Debug Level: "; +// std::cerr << RsInitConfig::debugLevel; +// std::cerr << std::endl; +// } +// } // set the debug file. if (RsInitConfig::haveLogFile) - { setDebugFile(RsInitConfig::logfname.c_str()); - } /******************************** WINDOWS/UNIX SPECIFIC PART ******************/ #ifndef WINDOWS_SYS @@ -2599,7 +2537,7 @@ int RsServer::StartupRetroShare() laddr.sin_port = htons(RsInitConfig::port); // universal - laddr.sin_addr.s_addr = inet_addr(RsInitConfig::inet); + laddr.sin_addr.s_addr = inet_addr(RsInitConfig::inet.c_str()); mPeerMgr->setLocalAddress(ownId, laddr); } diff --git a/libretroshare/src/tests/common/argstream.h b/libretroshare/src/tests/common/argstream.h deleted file mode 100644 index 137856794..000000000 --- a/libretroshare/src/tests/common/argstream.h +++ /dev/null @@ -1,814 +0,0 @@ -/* Copyright (C) 2004 Xavier Décoret -* - * argsteam is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * Foobar is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Foobar; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#ifndef ARGSTREAM_H -#define ARGSTREAM_H - - -#include -#include -#include -#include -#include -#include -#include -#include - -namespace -{ - class argstream; - - template - class ValueHolder; - - template - argstream& operator>> (argstream&, const ValueHolder&); - //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - // Interface of ValueHolder - //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - template - class ValueHolder - { - public: - ValueHolder(char s, - const char* l, - T& b, - const char* desc, - bool mandatory); - ValueHolder(const char* l, - T& b, - const char* desc, - bool mandatory); - ValueHolder(char s, - T& b, - const char* desc, - bool mandatory); - friend argstream& operator>><>(argstream& s,const ValueHolder& v); - std::string name() const; - std::string description() const; - private: - std::string shortName_; - std::string longName_; - T* value_; - T initialValue_; - std::string description_; - bool mandatory_; - }; - template - inline ValueHolder - parameter(char s, - const char* l, - T& b, - const char* desc="", - bool mandatory = true) - { - return ValueHolder(s,l,b,desc,mandatory); - } - template - inline ValueHolder - parameter(char s, - T& b, - const char* desc="", - bool mandatory = true) - { - return ValueHolder(s,b,desc,mandatory); - } - template - inline ValueHolder - parameter(const char* l, - T& b, - const char* desc="", - bool mandatory = true) - { - return ValueHolder(l,b,desc,mandatory); - } - //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - // Interface of OptionHolder - //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - class OptionHolder - { - public: - inline OptionHolder(char s, - const char* l, - bool& b, - const char* desc); - inline OptionHolder(const char* l, - bool& b, - const char* desc); - inline OptionHolder(char s, - bool& b, - const char* desc); - friend argstream& operator>>(argstream& s,const OptionHolder& v); - inline std::string name() const; - inline std::string description() const; - protected: - inline OptionHolder(char s, - const char* l, - const char* desc); - friend OptionHolder help(char s='h', - const char* l="help", - const char* desc="Display this help"); - private: - std::string shortName_; - std::string longName_; - bool* value_; - std::string description_; - }; - inline OptionHolder - option(char s, - const char* l, - bool& b, - const char* desc="") - { - return OptionHolder(s,l,b,desc); - } - inline OptionHolder - option(char s, - bool& b, - const char* desc="") - { - return OptionHolder(s,b,desc); - } - inline OptionHolder - option(const char* l, - bool& b, - const char* desc="") - { - return OptionHolder(l,b,desc); - } - inline OptionHolder - help(char s, - const char* l, - const char* desc) - { - return OptionHolder(s,l,desc); - } - //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - // Interface of ValuesHolder - //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - template - class ValuesHolder - { - public: - ValuesHolder(const O& o, - const char* desc, - int len); - template friend argstream& operator>>(argstream& s,const ValuesHolder& v); - std::string name() const; - std::string description() const; - typedef T value_type; - private: - mutable O value_; - std::string description_; - int len_; - char letter_; - }; - template - inline ValuesHolder - values(const O& o, - const char* desc="", - int len=-1) - { - return ValuesHolder(o,desc,len); - } - //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - // Interface of ValueParser - //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - template - class ValueParser - { - public: - inline T operator()(const std::string& s) const - { - std::istringstream is(s); - T t; - is>>t; - return t; - } - }; - // We need to specialize for string otherwise parsing of a value that - // contains space (for example a string with space passed in quotes on the - // command line) would parse only the first element of the value!!! - template <> - class ValueParser - { - public: - inline std::string operator()(const std::string& s) const - { - return s; - } - }; - //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - // Interface of argstream - //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - class argstream - { - public: - inline argstream(int argc,char** argv); - inline argstream(const char* c); - template - friend argstream& operator>>(argstream& s,const ValueHolder& v); - friend inline argstream& operator>>(argstream& s,const OptionHolder& v); - template - friend argstream& operator>>(argstream& s,const ValuesHolder& v); - - inline bool helpRequested() const; - inline bool isOk() const; - inline std::string errorLog() const; - inline std::string usage() const; - inline void defaultErrorHandling(bool ignoreUnused=false) const; - static inline char uniqueLetter(); - protected: - void parse(int argc,char** argv); - private: - typedef std::list::iterator value_iterator; - typedef std::pair help_entry; - std::string progName_; - std::map options_; - std::list values_; - bool minusActive_; - bool isOk_; - std::deque argHelps_; - std::string cmdLine_; - std::deque errors_; - bool helpRequested_; - }; - //************************************************************ - // Implementation of ValueHolder - //************************************************************ - template - ValueHolder::ValueHolder(char s, - const char* l, - T& v, - const char* desc, - bool mandatory) - : shortName_(1,s), - longName_(l), - value_(&v), - initialValue_(v), - description_(desc), - mandatory_(mandatory) - { - } - template - ValueHolder::ValueHolder(const char* l, - T& v, - const char* desc, - bool mandatory) - : longName_(l), - value_(&v), - initialValue_(v), - description_(desc), - mandatory_(mandatory) - { - } - template - ValueHolder::ValueHolder(char s, - T& v, - const char* desc, - bool mandatory) - : shortName_(1,s), - value_(&v), - initialValue_(v), - description_(desc), - mandatory_(mandatory) - { - } - template - std::string - ValueHolder::name() const - { - std::ostringstream os; - if (!shortName_.empty()) os<<'-'< - std::string - ValueHolder::description() const - { - std::ostringstream os; - os< - //************************************************************ - template - ValuesHolder::ValuesHolder(const O& o, - const char* desc, - int len) - : value_(o), - description_(desc), - len_(len) - { - letter_ = argstream::uniqueLetter(); - } - template - std::string - ValuesHolder::name() const - { - std::ostringstream os; - os< - std::string - ValuesHolder::description() const - { - return description_; - } - //************************************************************ - // Implementation of argstream - //************************************************************ - inline - argstream::argstream(int argc,char** argv) - : progName_(argv[0]), - minusActive_(true), - isOk_(true) - { - parse(argc,argv); - } - inline - argstream::argstream(const char* c) - : progName_(""), - minusActive_(true), - isOk_(true) - { - std::string s(c); - // Build argc, argv from s. We must add a dummy first element for - // progName because parse() expects it!! - std::deque args; - args.push_back(""); - std::istringstream is(s); - while (is.good()) - { - std::string t; - is>>t; - args.push_back(t); - } - char* pargs[args.size()]; - char** p = pargs; - for (std::deque::const_iterator - iter = args.begin(); - iter != args.end();++iter) - { - *p++ = const_cast(iter->c_str()); - } - parse(args.size(),pargs); - } - inline void - argstream::parse(int argc,char** argv) - { - // Run thru all arguments. - // * it has -- in front : it is a long name option, if remainder is empty, - // it is an error - // * it has - in front : it is a sequence of short name options, if - // remainder is empty, deactivates option (- will - // now be considered a char). - // * if any other char, or if option was deactivated - // : it is a value. Values are split in parameters - // (immediately follow an option) and pure values. - // Each time a value is parsed, if the previously parsed argument was an - // option, then the option is linked to the value in case of it is a - // option with parameter. The subtle point is that when several options - // are given with short names (ex: -abc equivalent to -a -b -c), the last - // parsed option is -c). - // Since we use map for option, any successive call overides the previous - // one: foo -a -b -a hello is equivalent to foo -b -a hello - // For values it is not true since we might have several times the same - // value. - value_iterator* lastOption = NULL; - for (char** a = argv,**astop=a+argc;++a!=astop;) - { - std::string s(*a); - if (minusActive_ && s[0] == '-') - { - if (s.size() > 1 && s[1] == '-') - { - if (s.size() == 2) - { - minusActive_ = false; - continue; - } - lastOption = &(options_[s.substr(2)] = values_.end()); - } - else - { - if (s.size() > 1) - { - // Parse all chars, if it is a minus we have an error - for (std::string::const_iterator cter = s.begin(); - ++cter != s.end();) - { - if (*cter == '-') - { - isOk_ = false; - std::ostringstream os; - os<<"- in the middle of a switch "<::const_iterator - iter = options_.begin();iter != options_.end();++iter) - { - std::cout<<"DEBUG: option "<first; - if (iter->second != values_.end()) - { - std::cout<<" -> "<<*(iter->second); - } - std::cout<::const_iterator - iter = values_.begin();iter != values_.end();++iter) - { - std::cout<<"DEBUG: value "<<*iter<::const_iterator - iter = argHelps_.begin();iter != argHelps_.end();++iter) - { - if (lmaxfirst.size()) lmax = iter->first.size(); - } - for (std::deque::const_iterator - iter = argHelps_.begin();iter != argHelps_.end();++iter) - { - os<<'\t'<first<first.size(),' ') - <<" : "<second<<'\n'; - } - return os.str(); - } - inline std::string - argstream::errorLog() const - { - std::string s; - for(std::deque::const_iterator iter = errors_.begin(); - iter != errors_.end();++iter) - { - s += *iter; - s += '\n'; - } - return s; - } - inline char - argstream::uniqueLetter() - { - static unsigned int c = 'a'; - return c++; - } - template - argstream& - operator>>(argstream& s,const ValueHolder& v) - { - // Search in the options if there is any such option defined either with a - // short name or a long name. If both are found, only the last one is - // used. -#ifdef ARGSTREAM_DEBUG - std::cout<<"DEBUG: searching "<::iterator iter = - s.options_.find(v.shortName_); - if (iter == s.options_.end()) - { - iter = s.options_.find(v.longName_); - } - if (iter != s.options_.end()) - { - // If we find counterpart for value holder on command line, either it - // has an associated value in which case we assign it, or it has not, in - // which case we have an error. - if (iter->second != s.values_.end()) - { -#ifdef ARGSTREAM_DEBUG - std::cout<<"DEBUG: found value "<<*(iter->second)< p; - *(v.value_) = p(*(iter->second)); - // The option and its associated value are removed, the subtle thing - // is that someother options might have this associated value too, - // which we must invalidate. - s.values_.erase(iter->second); - for (std::map::iterator - jter = s.options_.begin();jter != s.options_.end();++jter) - { - if (jter->second == iter->second) - { - jter->second = s.values_.end(); - } - } - s.options_.erase(iter); - } - else - { - s.isOk_ = false; - std::ostringstream os; - os<<"No value following switch "<first - <<" on command line"; - s.errors_.push_back(os.str()); - } - } - else - { - if (v.mandatory_) - { - s.isOk_ = false; - std::ostringstream os; - os<<"Mandatory parameter "; - if (!v.shortName_.empty()) os<<'-'<>(argstream& s,const OptionHolder& v) - { - // Search in the options if there is any such option defined either with a - // short name or a long name. If both are found, only the last one is - // used. -#ifdef ARGSTREAM_DEBUG - std::cout<<"DEBUG: searching "<::iterator iter = - s.options_.find(v.shortName_); - if (iter == s.options_.end()) - { - iter = s.options_.find(v.longName_); - } - if (iter != s.options_.end()) - { - // If we find counterpart for value holder on command line then the - // option is true and if an associated value was found, it is ignored - if (v.value_ != NULL) - { - *(v.value_) = true; - } - else - { - s.helpRequested_ = true; - } - // The option only is removed - s.options_.erase(iter); - } - else - { - if (v.value_ != NULL) - { - *(v.value_) = false; - } - else - { - s.helpRequested_ = false; - } - } - return s; - } - template - argstream& - operator>>(argstream& s,const ValuesHolder& v) - { - s.argHelps_.push_back(argstream::help_entry(v.name(),v.description())); - { - std::ostringstream os; - os<<' '<::iterator first = s.values_.begin(); - // We add to the iterator as much values as we can, limited to the length - // specified (if different of -1) - int n = v.len_ != -1?v.len_:s.values_.size(); - while (first != s.values_.end() && n-->0) - { - // Read the value from the string *first - ValueParser p; - *(v.value_++) = p(*first ); - s.argHelps_.push_back(argstream::help_entry(v.name(),v.description())); - // The value we just removed was maybe "remembered" by an option so we - // remove it now. - for (std::map::iterator - jter = s.options_.begin();jter != s.options_.end();++jter) - { - if (jter->second == first) - { - jter->second = s.values_.end(); - } - } - ++first; - } - // Check if we have enough values - if (n != 0) - { - s.isOk_ = false; - std::ostringstream os; - os<<"Expecting "< -#include +#include INITTEST() ; diff --git a/libretroshare/src/tests/pgp/test_certificate.cc b/libretroshare/src/tests/pgp/test_certificate.cc index b86735a43..04b121479 100644 --- a/libretroshare/src/tests/pgp/test_certificate.cc +++ b/libretroshare/src/tests/pgp/test_certificate.cc @@ -2,7 +2,7 @@ #include #include -#include +#include //#include #include #include diff --git a/libretroshare/src/tests/pgp/test_key_parsing.cc b/libretroshare/src/tests/pgp/test_key_parsing.cc index 5706f55d3..8e4a8ff64 100644 --- a/libretroshare/src/tests/pgp/test_key_parsing.cc +++ b/libretroshare/src/tests/pgp/test_key_parsing.cc @@ -11,7 +11,7 @@ extern "C" } #include -#include +#include INITTEST() ; diff --git a/libretroshare/src/tests/pgp/test_pgp_handler.cc b/libretroshare/src/tests/pgp/test_pgp_handler.cc index 702f6bd65..b78adc5f5 100644 --- a/libretroshare/src/tests/pgp/test_pgp_handler.cc +++ b/libretroshare/src/tests/pgp/test_pgp_handler.cc @@ -6,7 +6,7 @@ #include #include #include -#include +#include INITTEST() ; diff --git a/libretroshare/src/tests/util/aes_test.cc b/libretroshare/src/tests/util/aes_test.cc index f7e2531fd..cb0d00447 100644 --- a/libretroshare/src/tests/util/aes_test.cc +++ b/libretroshare/src/tests/util/aes_test.cc @@ -28,7 +28,7 @@ #include "util/rsaes.h" #include "util/utest.h" -#include +#include #include #include diff --git a/libretroshare/src/tests/util/sha1_test.cc b/libretroshare/src/tests/util/sha1_test.cc index bd95dc12d..84481aec5 100644 --- a/libretroshare/src/tests/util/sha1_test.cc +++ b/libretroshare/src/tests/util/sha1_test.cc @@ -28,7 +28,7 @@ #include "util/rsdir.h" #include "util/utest.h" -#include +#include #include #include diff --git a/libretroshare/src/util/argstream.h b/libretroshare/src/util/argstream.h new file mode 100644 index 000000000..08310ef72 --- /dev/null +++ b/libretroshare/src/util/argstream.h @@ -0,0 +1,839 @@ +/* Copyright (C) 2004 Xavier Décoret + * + * argsteam is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * Foobar is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Foobar; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef ARGSTREAM_H +#define ARGSTREAM_H + + +#include +#include +#include +#include +#include +#include +#include +#include + +namespace +{ + class argstream; + + template + class ValueHolder; + + template + argstream& operator>> (argstream&, const ValueHolder&); + //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + // Interface of ValueHolder + //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + template + class ValueHolder + { + public: + ValueHolder(char s, + const char* l, + T& b, + const char *valueName, + const char* desc, + bool mandatory); + ValueHolder(const char* l, + T& b, + const char *valueName, + const char* desc, + bool mandatory); + ValueHolder(char s, + T& b, + const char *valueName, + const char* desc, + bool mandatory); + friend argstream& operator>><>(argstream& s,const ValueHolder& v); + std::string name() const; + std::string description() const; + private: + std::string shortName_; + std::string longName_; + std::string valueName_; + T* value_; + T initialValue_; + std::string description_; + bool mandatory_; + }; + template + inline ValueHolder + parameter(char s, + const char* l, + T& b, + const char* desc="", + bool mandatory = true) + { + return ValueHolder(s,l,b,"value",desc,mandatory); + } + template + inline ValueHolder + parameter(char s, + const char* l, + T& b, + const char* valueName="value", + const char* desc="", + bool mandatory = true) + { + return ValueHolder(s,l,b,valueName,desc,mandatory); + } + template + inline ValueHolder + parameter(char s, + T& b, + const char* valueName="value", + const char* desc="", + bool mandatory = true) + { + return ValueHolder(s,b,valueName,desc,mandatory); + } + template + inline ValueHolder + parameter(const char* l, + T& b, + const char* valueName="value", + const char* desc="", + bool mandatory = true) + { + return ValueHolder(l,b,desc,mandatory); + } + //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + // Interface of OptionHolder + //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + class OptionHolder + { + public: + inline OptionHolder(char s, + const char* l, + bool& b, + const char* desc); + inline OptionHolder(const char* l, + bool& b, + const char* desc); + inline OptionHolder(char s, + bool& b, + const char* desc); + friend argstream& operator>>(argstream& s,const OptionHolder& v); + inline std::string name() const; + inline std::string description() const; + protected: + inline OptionHolder(char s, + const char* l, + const char* desc); + friend OptionHolder help(char s='h', + const char* l="help", + const char* desc="Display this help"); + private: + std::string shortName_; + std::string longName_; + bool* value_; + std::string description_; + }; + inline OptionHolder + option(char s, + const char* l, + bool& b, + const char* desc="") + { + return OptionHolder(s,l,b,desc); + } + inline OptionHolder + option(char s, + bool& b, + const char* desc="") + { + return OptionHolder(s,b,desc); + } + inline OptionHolder + option(const char* l, + bool& b, + const char* desc="") + { + return OptionHolder(l,b,desc); + } + inline OptionHolder + help(char s, + const char* l, + const char* desc) + { + return OptionHolder(s,l,desc); + } + //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + // Interface of ValuesHolder + //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + template + class ValuesHolder + { + public: + ValuesHolder(const O& o, + const char* desc, + int len); + template friend argstream& operator>>(argstream& s,const ValuesHolder& v); + std::string name() const; + std::string description() const; + typedef T value_type; + private: + mutable O value_; + std::string description_; + int len_; + char letter_; + }; + template + inline ValuesHolder + values(const O& o, + const char* desc="", + int len=-1) + { + return ValuesHolder(o,desc,len); + } + //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + // Interface of ValueParser + //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + template + class ValueParser + { + public: + inline T operator()(const std::string& s) const + { + std::istringstream is(s); + T t; + is>>t; + return t; + } + }; + // We need to specialize for string otherwise parsing of a value that + // contains space (for example a string with space passed in quotes on the + // command line) would parse only the first element of the value!!! + template <> + class ValueParser + { + public: + inline std::string operator()(const std::string& s) const + { + return s; + } + }; + //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + // Interface of argstream + //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + class argstream + { + public: + inline argstream(int argc,char** argv); + inline argstream(const char* c); + template + friend argstream& operator>>(argstream& s,const ValueHolder& v); + friend inline argstream& operator>>(argstream& s,const OptionHolder& v); + template + friend argstream& operator>>(argstream& s,const ValuesHolder& v); + + inline bool helpRequested() const; + inline bool isOk() const; + inline std::string errorLog() const; + inline std::string usage() const; + inline bool defaultErrorHandling(bool ignoreUnused=false) const; + static inline char uniqueLetter(); + protected: + void parse(int argc,char** argv); + private: + typedef std::list::iterator value_iterator; + typedef std::pair help_entry; + std::string progName_; + std::map options_; + std::list values_; + bool minusActive_; + bool isOk_; + std::deque argHelps_; + std::string cmdLine_; + std::deque errors_; + bool helpRequested_; + }; + //************************************************************ + // Implementation of ValueHolder + //************************************************************ + template + ValueHolder::ValueHolder(char s, + const char* l, + T& v, + const char* valueName, + const char* desc, + bool mandatory) + : shortName_(1,s), + longName_(l), + valueName_(valueName), + value_(&v), + initialValue_(v), + description_(desc), + mandatory_(mandatory) + { + } + template + ValueHolder::ValueHolder(const char* l, + T& v, + const char* valueName, + const char* desc, + bool mandatory) + : longName_(l), + value_(&v), + valueName_(valueName), + initialValue_(v), + description_(desc), + mandatory_(mandatory) + { + } + template + ValueHolder::ValueHolder(char s, + T& v, + const char* valueName, + const char* desc, + bool mandatory) + : shortName_(1,s), + value_(&v), + initialValue_(v), + valueName_(valueName), + description_(desc), + mandatory_(mandatory) + { + } + template + std::string + ValueHolder::name() const + { + std::ostringstream os; + if (!shortName_.empty()) os<<'-'< + std::string + ValueHolder::description() const + { + std::ostringstream os; + os< + //************************************************************ + template + ValuesHolder::ValuesHolder(const O& o, + const char* desc, + int len) + : value_(o), + description_(desc), + len_(len) + { + letter_ = argstream::uniqueLetter(); + } + template + std::string + ValuesHolder::name() const + { + std::ostringstream os; + os< + std::string + ValuesHolder::description() const + { + return description_; + } + //************************************************************ + // Implementation of argstream + //************************************************************ + inline + argstream::argstream(int argc,char** argv) + : progName_(argv[0]), + minusActive_(true), + isOk_(true), + helpRequested_(false) + { + parse(argc,argv); + } + inline + argstream::argstream(const char* c) + : progName_(""), + minusActive_(true), + isOk_(true) + { + std::string s(c); + // Build argc, argv from s. We must add a dummy first element for + // progName because parse() expects it!! + std::deque args; + args.push_back(""); + std::istringstream is(s); + while (is.good()) + { + std::string t; + is>>t; + args.push_back(t); + } + char* pargs[args.size()]; + char** p = pargs; + for (std::deque::const_iterator + iter = args.begin(); + iter != args.end();++iter) + { + *p++ = const_cast(iter->c_str()); + } + parse(args.size(),pargs); + } + inline void + argstream::parse(int argc,char** argv) + { + // Run thru all arguments. + // * it has -- in front : it is a long name option, if remainder is empty, + // it is an error + // * it has - in front : it is a sequence of short name options, if + // remainder is empty, deactivates option (- will + // now be considered a char). + // * if any other char, or if option was deactivated + // : it is a value. Values are split in parameters + // (immediately follow an option) and pure values. + // Each time a value is parsed, if the previously parsed argument was an + // option, then the option is linked to the value in case of it is a + // option with parameter. The subtle point is that when several options + // are given with short names (ex: -abc equivalent to -a -b -c), the last + // parsed option is -c). + // Since we use map for option, any successive call overides the previous + // one: foo -a -b -a hello is equivalent to foo -b -a hello + // For values it is not true since we might have several times the same + // value. + value_iterator* lastOption = NULL; + for (char** a = argv,**astop=a+argc;++a!=astop;) + { + std::string s(*a); + if (minusActive_ && s[0] == '-') + { + if (s.size() > 1 && s[1] == '-') + { + if (s.size() == 2) + { + minusActive_ = false; + continue; + } + lastOption = &(options_[s.substr(2)] = values_.end()); + } + else + { + if (s.size() > 1) + { + // Parse all chars, if it is a minus we have an error + for (std::string::const_iterator cter = s.begin(); + ++cter != s.end();) + { + if (*cter == '-') + { + isOk_ = false; + std::ostringstream os; + os<<"- in the middle of a switch "<::const_iterator + iter = options_.begin();iter != options_.end();++iter) + { + std::cout<<"DEBUG: option "<first; + if (iter->second != values_.end()) + { + std::cout<<" -> "<<*(iter->second); + } + std::cout<::const_iterator + iter = values_.begin();iter != values_.end();++iter) + { + std::cout<<"DEBUG: value "<<*iter<::const_iterator + iter = argHelps_.begin();iter != argHelps_.end();++iter) + { + if (lmaxfirst.size()) lmax = iter->first.size(); + } + for (std::deque::const_iterator + iter = argHelps_.begin();iter != argHelps_.end();++iter) + { + os<<'\t'<first<first.size(),' ') + <<" : "<second<<'\n'; + } + return os.str(); + } + inline std::string + argstream::errorLog() const + { + std::string s; + for(std::deque::const_iterator iter = errors_.begin(); + iter != errors_.end();++iter) + { + s += *iter; + s += '\n'; + } + return s; + } + inline char + argstream::uniqueLetter() + { + static unsigned int c = 'a'; + return c++; + } + template + argstream& + operator>>(argstream& s,const ValueHolder& v) + { + // Search in the options if there is any such option defined either with a + // short name or a long name. If both are found, only the last one is + // used. +#ifdef ARGSTREAM_DEBUG + std::cout<<"DEBUG: searching "<::iterator iter = + s.options_.find(v.shortName_); + if (iter == s.options_.end()) + { + iter = s.options_.find(v.longName_); + } + if (iter != s.options_.end()) + { + // If we find counterpart for value holder on command line, either it + // has an associated value in which case we assign it, or it has not, in + // which case we have an error. + if (iter->second != s.values_.end()) + { +#ifdef ARGSTREAM_DEBUG + std::cout<<"DEBUG: found value "<<*(iter->second)< p; + *(v.value_) = p(*(iter->second)); + // The option and its associated value are removed, the subtle thing + // is that someother options might have this associated value too, + // which we must invalidate. + s.values_.erase(iter->second); + for (std::map::iterator + jter = s.options_.begin();jter != s.options_.end();++jter) + { + if (jter->second == iter->second) + { + jter->second = s.values_.end(); + } + } + s.options_.erase(iter); + } + else + { + s.isOk_ = false; + std::ostringstream os; + os<<"No value following switch "<first + <<" on command line"; + s.errors_.push_back(os.str()); + } + } + else + { + if (v.mandatory_) + { + s.isOk_ = false; + std::ostringstream os; + os<<"Mandatory parameter "; + if (!v.shortName_.empty()) os<<'-'<>(argstream& s,const OptionHolder& v) + { + // Search in the options if there is any such option defined either with a + // short name or a long name. If both are found, only the last one is + // used. +#ifdef ARGSTREAM_DEBUG + std::cout<<"DEBUG: searching "<::iterator iter = + s.options_.find(v.shortName_); + if (iter == s.options_.end()) + { + iter = s.options_.find(v.longName_); + } + if (iter != s.options_.end()) + { + // If we find counterpart for value holder on command line then the + // option is true and if an associated value was found, it is ignored + if (v.value_ != NULL) + { + *(v.value_) = true; + } + else + { + s.helpRequested_ = true; + } + // The option only is removed + s.options_.erase(iter); + } + else + { + if (v.value_ != NULL) + { + *(v.value_) = false; + } + else + { + s.helpRequested_ = false; + } + } + return s; + } + template + argstream& + operator>>(argstream& s,const ValuesHolder& v) + { + s.argHelps_.push_back(argstream::help_entry(v.name(),v.description())); + { + std::ostringstream os; + os<<' '<::iterator first = s.values_.begin(); + // We add to the iterator as much values as we can, limited to the length + // specified (if different of -1) + int n = v.len_ != -1?v.len_:s.values_.size(); + while (first != s.values_.end() && n-->0) + { + // Read the value from the string *first + ValueParser p; + *(v.value_++) = p(*first ); + s.argHelps_.push_back(argstream::help_entry(v.name(),v.description())); + // The value we just removed was maybe "remembered" by an option so we + // remove it now. + for (std::map::iterator + jter = s.options_.begin();jter != s.options_.end();++jter) + { + if (jter->second == first) + { + jter->second = s.values_.end(); + } + } + ++first; + } + // Check if we have enough values + if (n != 0) + { + s.isOk_ = false; + std::ostringstream os; + os<<"Expecting "<& found_files); diff --git a/retroshare-nogui/src/retroshare.cc b/retroshare-nogui/src/retroshare.cc index bf570bcfd..a9bd4aa67 100644 --- a/retroshare-nogui/src/retroshare.cc +++ b/retroshare-nogui/src/retroshare.cc @@ -31,6 +31,7 @@ #include "notifytxt.h" #include +#include #include #ifdef WINDOWS_SYS #include @@ -53,6 +54,10 @@ #endif +#ifdef RS_SSH_SERVER +void generatePasswordHash() ; +#endif + /* Basic instructions for running libretroshare as background thread. * ******************************************************************* * * This allows your program to communicate with authenticated peers. @@ -102,7 +107,6 @@ int main(int argc, char **argv) bool enableRpc = false; bool enableSsh = false; bool enableSshHtml = false; - bool enableSshPwd = false; bool enableTerminal = false; bool enableSshRsa = false; bool genPwdHash = false; @@ -112,167 +116,75 @@ int main(int argc, char **argv) std::string sshPortStr = "0"; uint16_t extPort = 0; + uint16_t sshPort = 7022; bool extPortSet = false; + bool displayRPCInfo = false ; - while((c = getopt(argc, argv,"ChTL:P:K:GS:E:")) != -1) - { - switch(c) - { - case 'C': - enableRpc = true; - strictCheck = false; - break; - case 'S': - enableSsh = true; - sshPortStr = optarg; // no longer optional. - strictCheck = false; - break; - case 'E': - extPort = atoi(optarg); - extPortSet = true; - strictCheck = false; - break; - case 'H': - enableSshHtml = true; - strictCheck = false; - break; - case 'T': - enableTerminal = true; - strictCheck = false; - break; - case 'L': - sshUser = optarg; - strictCheck = false; - break; - case 'P': - enableSshPwd = true; - sshPwdHash = optarg; - strictCheck = false; - break; -#if 0 // NOT FINISHED YET. - case 'K': - enableSshRsa = true; - sshRsaFile = optarg; - strictCheck = false; - break; + argstream as(argc,argv) ; + + as >> option('X',"enable-ssh" ,enableSsh ,"Enable SSH" ) + >> option('T',"enable-terminal",enableTerminal ,"Enable terminal interface." ) + >> option('C',"enable-rpc" ,enableRpc ,"Enable RPC protocol. To be used with e.g. -X (SSH).") + >> option('G',"gen-password" ,genPwdHash ,"Generate password hash (to supply to option -P)") +#if 0 + >> option('H',"enable-ssh-html",enableSshHtml ,"Enable SSH html." ) #endif - case 'G': - genPwdHash = true; - break; - case 'h': - /* nogui help */ - std::cerr << argv[0] << std::endl; - std::cerr << "Specific Help Options: " << std::endl; - std::cerr << "\t-G Generate a Password Hash for SSH Server" << std::endl; - std::cerr << "\t-T Enable Terminal Interface" << std::endl; - std::cerr << "\t-S Enable SSH Server on specified port" << std::endl; - std::cerr << "\t-E Specify Alternative External Port (provided to Clients)" << std::endl; - std::cerr << "\t-L Specify SSH login user (default:user)" << std::endl; - std::cerr << "\t-P Enable SSH login via Password" << std::endl; - std::cerr << "\t-C Enable RPC Protocol (requires -S too)" << std::endl; - //std::cerr << "\t-K [rsapubkeyfile] Enable SSH login via RSA key" << std::endl; - //std::cerr << "\t NB: Two Factor Auth, specify both -P & -K" << std::endl; - std::cerr << std::endl; - std::cerr << "\t To setup rs-nogui as a SSH Server is a three step process: " << std::endl; - std::cerr << "\t 1) \"ssh-keygen -t rsa -f rs_ssh_host_rsa_key\" " << std::endl; - std::cerr << "\t 2) \"./retroshare-nogui -G\" " << std::endl; - std::cerr << "\t 3) \"./retroshare-nogui -S [port] -L -P \" " << std::endl; - std::cerr << std::endl; - std::cerr << "Further Options "; - /* libretroshare will call exit(1) after printing its options */ - break; + >> parameter('S',"ssh-port" ,sshPort ,"port" ,"SSH port to contact the interface.",false) + >> parameter('E',"ext-port" ,extPort ,"port" ,"Specify Alternative External Port (provided to Clients)",false) + >> parameter('L',"ssh-user" ,sshUser ,"name" ,"Ssh login user",false) + >> parameter('P',"ssh-p-hash" ,sshPwdHash ,"hash" ,"Ssh login password hash (Generated by retroshare-nogui -G)",false) + >> parameter('K',"ssh-key-file" ,sshRsaFile ,"RSA key file", "RSA key file for SSH login (not yet implemented).",false )// NOT FINISHED YET. - default: - /* let others through - for libretroshare */ - break; - } + >> help() ; + + // Normally argstream would handle this by itself, if we called + // as.defaultErrorHandling() ; + // + // but we have other parameter handling functions after, so we don't want to quit if help is requested. + // + if (as.helpRequested()) + { + std::cerr << "\nSpecific Help Options:" << std::endl; + std::cerr << as.usage() << std::endl; + std::cerr << "\t To setup rs-nogui as a SSH Server is a three step process: " << std::endl; + std::cerr << "\t 1) Generate a RSA keypair in the current directory: \"ssh-keygen -t rsa -f rs_ssh_host_rsa_key\" " << std::endl; + std::cerr << "\t 2) Generate a password hash for the RPC login: \"./retroshare-nogui -G\" " << std::endl; + std::cerr << "\t 3) Launch the RS with remote control enabled: \"./retroshare-nogui -X/-T [-C] -S [port] -L -P \" " << std::endl; + + std::cerr << "\nAdditional options: \n" << std::endl; + } + if (!as.isOk()) + { + std::cerr << as.errorLog(); + return 1; } - // reset optind for Retroshare commandline arguments. - optind = 1; if (genPwdHash) { - std::string saltBin; - std::string pwdHashRadix64; - std::string sshPwdForHash = ""; - - std::cout << "Type in your Password:" << std::flush; - char pwd[1024]; - if (!fgets(pwd, 1024, stdin)) - { - std::cerr << "Error Reading Password"; - std::cerr << std::endl; - exit(1); - } - - // strip newline. - for(int i = 0; (i < 1024) && (pwd[i] != '\n') && (pwd[i] != '\0'); i++) - { - sshPwdForHash += pwd[i]; - } - - std::cerr << "Chosen Password : " << sshPwdForHash; - std::cerr << std::endl; - - - GenerateSalt(saltBin); - if (!GeneratePasswordHash(saltBin, sshPwdForHash, pwdHashRadix64)) - { - std::cerr << "Error Generating Password Hash, password probably too short"; - std::cerr << pwdHashRadix64; - std::cerr << std::endl; - exit(1); - } - - std::cout << "Generated Password Hash for rs-nogui: "; - std::cout << pwdHashRadix64; - std::cout << std::endl; - std::cout << std::endl; - - /* checking match */ - if (CheckPasswordHash(pwdHashRadix64, sshPwdForHash)) - { - std::cerr << "Passed Check Okay!"; - std::cerr << std::endl; - } - else - { - std::cerr << "ERROR: Failed CheckPassword!"; - std::cerr << std::endl; - exit(1); - } - - - std::cerr << "Usage:"; - std::cerr << std::endl; - std::cerr << " - for SSH access: ./retroshare-nogui -S [port] -L -P " << pwdHashRadix64; - std::cerr << std::endl; - std::cerr << " - for RPC access: ./retroshare-nogui -C -S [port] -L -P " << pwdHashRadix64; - std::cerr << std::endl; - exit(0); + generatePasswordHash() ; + return 0 ; } - /* enforce conditions */ - if (((enableSshRsa) || (enableSshPwd)) && (!enableSsh)) + if ((!sshRsaFile.empty() || !sshPwdHash.empty()) && (!enableSsh)) { - std::cerr << "ERROR: SSH Server (-S) must be enabled to specify SSH Pwd (-P) or SSH RSA (-K)"; + std::cerr << "ERROR: SSH Server (-X) must be enabled to specify SSH Pwd (-P) or SSH RSA (-K)"; std::cerr << std::endl; - exit(1); + return 1 ; } - if (enableSsh && (!enableSshRsa) && (!enableSshPwd)) + if (enableSsh && (!enableSshRsa) && sshPwdHash.empty()) { - std::cerr << "ERROR: One of (or both) SSH Pwd (-P) and SSH RSA (-K) must be specified with SSH Server (-S)"; + std::cerr << "ERROR: One of (or both) SSH Pwd (-P) and SSH RSA (-K) must be specified with SSH Server (-X)"; std::cerr << std::endl; - exit(1); + return 1 ; } if (enableRpc && (!enableSsh)) { - std::cerr << "ERROR: RPC Mode (-C) requires SSH Server (-S) enabled"; + std::cerr << "ERROR: RPC Mode (-C) requires SSH Server (-X) enabled"; std::cerr << std::endl; - exit(1); + return 1 ; } @@ -291,12 +203,8 @@ int main(int argc, char **argv) } - if (enableSshPwd) - { - /* try parse it */ - /* TODO */ - - } +#else + std::cerr << "\nRetroshare command line interface." << std::endl; #endif @@ -372,7 +280,7 @@ int main(int argc, char **argv) //ssh->adduser("anrsuser", "test"); } - if (enableSshPwd) + if (!sshPwdHash.empty()) { ssh->adduserpwdhash(sshUser, sshPwdHash); } @@ -385,8 +293,6 @@ int main(int argc, char **argv) // NASTY GLOBAL VARIABLE HACK - NEED TO THINK OF A BETTER SYSTEM. RpcProtoSystem::mExtPort = extPort; } - - #endif /* Start-up libretroshare server threads */ @@ -470,3 +376,71 @@ int main(int argc, char **argv) } return 1; } + +#ifdef RS_SSH_SERVER +void generatePasswordHash() +{ + std::string saltBin; + std::string pwdHashRadix64; + std::string sshPwdForHash = ""; + + std::string passwd1,passwd2 ; + + if(!NotifyTxt().askForPassword("Type your password (at least 8 chars) : ",false,passwd1)) exit(1) ; + + if(passwd1.length() < 8) + { + std::cerr << "Password must be at least 8 characters long." << std::endl; + exit(1); + } + + if(!NotifyTxt().askForPassword("Type your password (checking) : ",false,passwd2)) exit(1) ; + + if(passwd1 != passwd2) + { + std::cerr << "Passwords differ. Please retry." << std::endl; + exit(1); + } + + sshPwdForHash = passwd1 ; + + //std::cerr << "Chosen Password : " << sshPwdForHash; + std::cerr << std::endl; + + GenerateSalt(saltBin); + if (!GeneratePasswordHash(saltBin, sshPwdForHash, pwdHashRadix64)) + { + std::cerr << "Error Generating Password Hash, password probably too short"; + std::cerr << pwdHashRadix64; + std::cerr << std::endl; + exit(1); + } + + std::cout << "Generated Password Hash for rs-nogui: "; + std::cout << pwdHashRadix64; + std::cout << std::endl; + std::cout << std::endl; + + /* checking match */ + if (CheckPasswordHash(pwdHashRadix64, sshPwdForHash)) + { + std::cerr << "Passed Check Okay!"; + std::cerr << std::endl; + } + else + { + std::cerr << "ERROR: Failed CheckPassword!"; + std::cerr << std::endl; + exit(1); + } + + + std::cerr << "Usage:"; + std::cerr << std::endl; + std::cerr << " - for SSH access: ./retroshare-nogui -X -S [port] -L -P " << pwdHashRadix64; + std::cerr << std::endl; + std::cerr << " - for RPC access: ./retroshare-nogui -C -S [port] -L -P " << pwdHashRadix64; + std::cerr << std::endl; +} +#endif +