mirror of
https://github.com/RetroShare/RetroShare.git
synced 2024-12-28 08:59:37 -05:00
Merge pull request #937 from csoler/v0.6-ImprovedNoGUI
V0.6 improved no gui
This commit is contained in:
commit
98b0585ba4
@ -14,6 +14,8 @@
|
|||||||
|
|
||||||
#include "GetPluginInterfaces.h"
|
#include "GetPluginInterfaces.h"
|
||||||
|
|
||||||
|
//#define DEBUG_CONTROL_MODULE 1
|
||||||
|
|
||||||
namespace resource_api{
|
namespace resource_api{
|
||||||
|
|
||||||
RsControlModule::RsControlModule(int argc, char **argv, StateTokenServer* sts, ApiServer *apiserver, bool full_control):
|
RsControlModule::RsControlModule(int argc, char **argv, StateTokenServer* sts, ApiServer *apiserver, bool full_control):
|
||||||
@ -61,6 +63,9 @@ bool RsControlModule::processShouldExit()
|
|||||||
|
|
||||||
bool RsControlModule::askForPassword(const std::string &title, const std::string &key_details, bool prev_is_bad, std::string &password, bool& cancelled)
|
bool RsControlModule::askForPassword(const std::string &title, const std::string &key_details, bool prev_is_bad, std::string &password, bool& cancelled)
|
||||||
{
|
{
|
||||||
|
#ifdef DEBUG_CONTROL_MODULE
|
||||||
|
std::cerr << "RsControlModule::askForPassword(): current passwd is \"" << mPassword << "\"" << std::endl;
|
||||||
|
#endif
|
||||||
cancelled = false ;
|
cancelled = false ;
|
||||||
{
|
{
|
||||||
RS_STACK_MUTEX(mDataMtx); // ********** LOCKED **********
|
RS_STACK_MUTEX(mDataMtx); // ********** LOCKED **********
|
||||||
@ -114,7 +119,9 @@ bool RsControlModule::askForPassword(const std::string &title, const std::string
|
|||||||
|
|
||||||
void RsControlModule::run()
|
void RsControlModule::run()
|
||||||
{
|
{
|
||||||
|
#ifdef DEBUG_CONTROL_MODULE
|
||||||
std::cerr << "RsControlModule: initialising libretroshare..." << std::endl;
|
std::cerr << "RsControlModule: initialising libretroshare..." << std::endl;
|
||||||
|
#endif
|
||||||
|
|
||||||
RsInit::InitRsConfig();
|
RsInit::InitRsConfig();
|
||||||
int initResult = RsInit::InitRetroShare(argc, argv, true);
|
int initResult = RsInit::InitRetroShare(argc, argv, true);
|
||||||
@ -125,11 +132,11 @@ void RsControlModule::run()
|
|||||||
std::stringstream ss;
|
std::stringstream ss;
|
||||||
switch (initResult) {
|
switch (initResult) {
|
||||||
case RS_INIT_AUTH_FAILED:
|
case RS_INIT_AUTH_FAILED:
|
||||||
ss << "RsInit::InitRetroShare AuthGPG::InitAuth failed" << std::endl;
|
ss << "RsControlModule::run() AuthGPG::InitAuth failed" << std::endl;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
/* Unexpected return code */
|
/* Unexpected return code */
|
||||||
ss << "RsInit::InitRetroShare unexpected return code " << initResult << std::endl;
|
ss << "ControlModule::run() unexpected return code " << initResult << std::endl;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
// FATAL ERROR, we can't recover from this. Just send the message to the user.
|
// FATAL ERROR, we can't recover from this. Just send the message to the user.
|
||||||
@ -141,33 +148,57 @@ void RsControlModule::run()
|
|||||||
RsControl::earlyInitNotificationSystem();
|
RsControl::earlyInitNotificationSystem();
|
||||||
rsNotify->registerNotifyClient(this);
|
rsNotify->registerNotifyClient(this);
|
||||||
|
|
||||||
|
#ifdef DEBUG_CONTROL_MODULE
|
||||||
|
std::cerr << "RsControlModule::run() Entering login wait loop." << std::endl;
|
||||||
|
#endif
|
||||||
bool login_ok = false;
|
bool login_ok = false;
|
||||||
while(!login_ok)
|
while(!login_ok)
|
||||||
{
|
{
|
||||||
|
#ifdef DEBUG_CONTROL_MODULE
|
||||||
|
std::cerr << "RsControlModule::run() reseting passwd." << std::endl;
|
||||||
|
#endif
|
||||||
{
|
{
|
||||||
RsStackMutex stack(mDataMtx); // ********** LOCKED **********
|
RsStackMutex stack(mDataMtx); // ********** LOCKED **********
|
||||||
mPassword = "";
|
mPassword = "";
|
||||||
}
|
}
|
||||||
|
|
||||||
// skip account selection if autologin is available
|
// skip account selection if autologin is available
|
||||||
if(initResult != RS_INIT_HAVE_ACCOUNT)
|
bool wait_for_account_select = (initResult != RS_INIT_HAVE_ACCOUNT);
|
||||||
setRunState(WAITING_ACCOUNT_SELECT);
|
|
||||||
|
|
||||||
// wait for login request
|
// wait for login request
|
||||||
bool auto_login = false;
|
bool auto_login = false;
|
||||||
bool wait_for_account_select = (initResult != RS_INIT_HAVE_ACCOUNT);
|
|
||||||
|
if(wait_for_account_select)
|
||||||
|
{
|
||||||
|
#ifdef DEBUG_CONTROL_MODULE
|
||||||
|
std::cerr << "RsControlModule::run() wait_for_account_select=true => setting run state to WAITING_ACCOUNT_SELECT." << std::endl;
|
||||||
|
#endif
|
||||||
|
setRunState(WAITING_ACCOUNT_SELECT);
|
||||||
|
}
|
||||||
|
|
||||||
while(wait_for_account_select && !processShouldExit())
|
while(wait_for_account_select && !processShouldExit())
|
||||||
{
|
{
|
||||||
usleep(5*1000);
|
#ifdef DEBUG_CONTROL_MODULE
|
||||||
|
std::cerr << "RsControlModule::run() while(wait_for_account_select) mLoadPeerId=" << mLoadPeerId << std::endl;
|
||||||
|
#endif
|
||||||
|
usleep(500*1000);
|
||||||
RsStackMutex stack(mDataMtx); // ********** LOCKED **********
|
RsStackMutex stack(mDataMtx); // ********** LOCKED **********
|
||||||
wait_for_account_select = mLoadPeerId.isNull();
|
|
||||||
|
if(!mLoadPeerId.isNull())
|
||||||
|
{
|
||||||
|
wait_for_account_select = wait_for_account_select && !RsAccounts::SelectAccount(mLoadPeerId);
|
||||||
|
#ifdef DEBUG_CONTROL_MODULE
|
||||||
|
std::cerr << "RsControlModule::run() mLoadPeerId != NULL, account selection result: " << !wait_for_account_select << std::endl;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
auto_login = mAutoLoginNextTime;
|
auto_login = mAutoLoginNextTime;
|
||||||
if(!wait_for_account_select)
|
|
||||||
{
|
//if(!wait_for_account_select)
|
||||||
wait_for_account_select = !RsAccounts::SelectAccount(mLoadPeerId);
|
//{
|
||||||
if(wait_for_account_select)
|
// if(wait_for_account_select)
|
||||||
setRunState(WAITING_ACCOUNT_SELECT);
|
// setRunState(WAITING_ACCOUNT_SELECT);
|
||||||
}
|
//}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(processShouldExit())
|
if(processShouldExit())
|
||||||
@ -175,6 +206,9 @@ void RsControlModule::run()
|
|||||||
|
|
||||||
bool autoLogin = (initResult == RS_INIT_HAVE_ACCOUNT) | auto_login;
|
bool autoLogin = (initResult == RS_INIT_HAVE_ACCOUNT) | auto_login;
|
||||||
std::string lockFile;
|
std::string lockFile;
|
||||||
|
#ifdef DEBUG_CONTROL_MODULE
|
||||||
|
std::cerr << "RsControlModule::run() trying to load certificate..." << std::endl;
|
||||||
|
#endif
|
||||||
int retVal = RsInit::LockAndLoadCertificates(autoLogin, lockFile);
|
int retVal = RsInit::LockAndLoadCertificates(autoLogin, lockFile);
|
||||||
|
|
||||||
std::string error_string;
|
std::string error_string;
|
||||||
@ -199,16 +233,24 @@ void RsControlModule::run()
|
|||||||
std::cerr << "RsControlModule::run() LockAndLoadCertificates failed. Unexpected switch value: " << retVal << std::endl;
|
std::cerr << "RsControlModule::run() LockAndLoadCertificates failed. Unexpected switch value: " << retVal << std::endl;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
#ifdef DEBUG_CONTROL_MODULE
|
||||||
|
std::cerr << "RsControlModule::run() Error string: \"" << error_string << "\"" << std::endl;
|
||||||
|
#endif
|
||||||
|
|
||||||
{
|
{
|
||||||
RsStackMutex stack(mDataMtx); // ********** LOCKED **********
|
RsStackMutex stack(mDataMtx); // ********** LOCKED **********
|
||||||
mLoadPeerId.clear();
|
mLoadPeerId.clear();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#ifdef DEBUG_CONTROL_MODULE
|
||||||
|
std::cerr << "RsControlModule::run() login is ok. Starting up..." << std::endl;
|
||||||
|
#endif
|
||||||
|
|
||||||
{
|
{
|
||||||
RsStackMutex stack(mDataMtx); // ********** LOCKED **********
|
RsStackMutex stack(mDataMtx); // ********** LOCKED **********
|
||||||
mFixedPassword = mPassword;
|
mFixedPassword = mPassword;
|
||||||
|
|
||||||
|
std::cerr << "***Reseting mPasswd " << std::endl;
|
||||||
mPassword = "";
|
mPassword = "";
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -331,13 +373,20 @@ void RsControlModule::handlePassword(Request &req, Response &resp)
|
|||||||
RsStackMutex stack(mDataMtx); // ********** LOCKED **********
|
RsStackMutex stack(mDataMtx); // ********** LOCKED **********
|
||||||
std::string passwd;
|
std::string passwd;
|
||||||
req.mStream << makeKeyValueReference("password", passwd);
|
req.mStream << makeKeyValueReference("password", passwd);
|
||||||
if(passwd != "" && mWantPassword)
|
if(passwd != "")// && mWantPassword)
|
||||||
{
|
{
|
||||||
// client sends password
|
// client sends password
|
||||||
mPassword = passwd;
|
mPassword = passwd;
|
||||||
mWantPassword = false;
|
mWantPassword = false;
|
||||||
mStateTokenServer->replaceToken(mStateToken);
|
mStateTokenServer->replaceToken(mStateToken);
|
||||||
|
#ifdef DEBUG_CONTROL_MODULE
|
||||||
|
std::cerr << "RsControlModule::handlePassword(): setting mPasswd=\"" << mPassword << "\"" << std::endl;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
#ifdef DEBUG_CONTROL_MODULE
|
||||||
|
else
|
||||||
|
std::cerr << "RsControlModule::handlePassword(): not setting mPasswd=\"" << mPassword << "\"!!!" << std::endl;
|
||||||
|
#endif
|
||||||
|
|
||||||
resp.mDataStream
|
resp.mDataStream
|
||||||
<< makeKeyValueReference("want_password", mWantPassword)
|
<< makeKeyValueReference("want_password", mWantPassword)
|
||||||
|
@ -23,6 +23,8 @@ class ApiServer;
|
|||||||
class RsControlModule: public ResourceRouter, NotifyClient, private RsSingleJobThread
|
class RsControlModule: public ResourceRouter, NotifyClient, private RsSingleJobThread
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
enum RunState { WAITING_INIT, FATAL_ERROR, WAITING_ACCOUNT_SELECT, WAITING_STARTUP, RUNNING_OK, RUNNING_OK_NO_FULL_CONTROL};
|
||||||
|
|
||||||
// ApiServer will be called once RS is started, to load additional api modules
|
// ApiServer will be called once RS is started, to load additional api modules
|
||||||
// full_control: set to true if this module should handle rsinit and login
|
// full_control: set to true if this module should handle rsinit and login
|
||||||
// set to false if rsinit is handled by the Qt gui
|
// set to false if rsinit is handled by the Qt gui
|
||||||
@ -32,6 +34,9 @@ public:
|
|||||||
// returns true if the process should terminate
|
// returns true if the process should terminate
|
||||||
bool processShouldExit();
|
bool processShouldExit();
|
||||||
|
|
||||||
|
// returns the current state of the software booting process
|
||||||
|
RunState runState() const { return mRunState ; }
|
||||||
|
|
||||||
// from NotifyClient
|
// from NotifyClient
|
||||||
virtual bool askForPassword(const std::string &title, const std::string& key_details, bool prev_is_bad , std::string& password,bool& canceled) override;
|
virtual bool askForPassword(const std::string &title, const std::string& key_details, bool prev_is_bad , std::string& password,bool& canceled) override;
|
||||||
virtual bool askForDeferredSelfSignature(const void *data, const uint32_t len, unsigned char *sign, unsigned int *signlen,int& signature_result, std::string reason = "") override;
|
virtual bool askForDeferredSelfSignature(const void *data, const uint32_t len, unsigned char *sign, unsigned int *signlen,int& signature_result, std::string reason = "") override;
|
||||||
@ -42,7 +47,6 @@ protected:
|
|||||||
virtual void run();
|
virtual void run();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
enum RunState { WAITING_INIT, FATAL_ERROR, WAITING_ACCOUNT_SELECT, WAITING_STARTUP, RUNNING_OK, RUNNING_OK_NO_FULL_CONTROL};
|
|
||||||
void handleRunState(Request& req, Response& resp);
|
void handleRunState(Request& req, Response& resp);
|
||||||
void handleIdentities(Request& req, Response& resp);
|
void handleIdentities(Request& req, Response& resp);
|
||||||
void handleLocations(Request& req, Response& resp);
|
void handleLocations(Request& req, Response& resp);
|
||||||
|
@ -46,6 +46,8 @@
|
|||||||
#define LIMIT_CERTIFICATE_SIZE 1
|
#define LIMIT_CERTIFICATE_SIZE 1
|
||||||
#define MAX_CERTIFICATE_SIZE 10000
|
#define MAX_CERTIFICATE_SIZE 10000
|
||||||
|
|
||||||
|
//#define DEBUG_AUTHGPG 1
|
||||||
|
|
||||||
const time_t STORE_KEY_TIMEOUT = 1 * 60 * 60; //store key is call around every hour
|
const time_t STORE_KEY_TIMEOUT = 1 * 60 * 60; //store key is call around every hour
|
||||||
|
|
||||||
AuthGPG *AuthGPG::_instance = NULL ;
|
AuthGPG *AuthGPG::_instance = NULL ;
|
||||||
@ -88,7 +90,6 @@ bool AuthGPG::encryptTextToFile(const std::string& text,const std::string& outfi
|
|||||||
|
|
||||||
std::string pgp_pwd_callback(void * /*hook*/, const char *uid_title, const char *uid_hint, const char * /*passphrase_info*/, int prev_was_bad,bool *cancelled)
|
std::string pgp_pwd_callback(void * /*hook*/, const char *uid_title, const char *uid_hint, const char * /*passphrase_info*/, int prev_was_bad,bool *cancelled)
|
||||||
{
|
{
|
||||||
#define GPG_DEBUG2
|
|
||||||
#ifdef GPG_DEBUG2
|
#ifdef GPG_DEBUG2
|
||||||
fprintf(stderr, "pgp_pwd_callback() called.\n");
|
fprintf(stderr, "pgp_pwd_callback() called.\n");
|
||||||
#endif
|
#endif
|
||||||
@ -162,7 +163,9 @@ AuthGPG::AuthGPG(const std::string& path_to_public_keyring,const std::string& pa
|
|||||||
*/
|
*/
|
||||||
int AuthGPG::GPGInit(const RsPgpId &ownId)
|
int AuthGPG::GPGInit(const RsPgpId &ownId)
|
||||||
{
|
{
|
||||||
|
#ifdef DEBUG_AUTHGPG
|
||||||
std::cerr << "AuthGPG::GPGInit() called with own gpg id : " << ownId.toStdString() << std::endl;
|
std::cerr << "AuthGPG::GPGInit() called with own gpg id : " << ownId.toStdString() << std::endl;
|
||||||
|
#endif
|
||||||
|
|
||||||
mOwnGpgId = RsPgpId(ownId);
|
mOwnGpgId = RsPgpId(ownId);
|
||||||
|
|
||||||
@ -170,7 +173,9 @@ int AuthGPG::GPGInit(const RsPgpId &ownId)
|
|||||||
privateTrustCertificate(ownId, 5);
|
privateTrustCertificate(ownId, 5);
|
||||||
updateOwnSignatureFlag(mOwnGpgId) ;
|
updateOwnSignatureFlag(mOwnGpgId) ;
|
||||||
|
|
||||||
|
#ifdef DEBUG_AUTHGPG
|
||||||
std::cerr << "AuthGPG::GPGInit finished." << std::endl;
|
std::cerr << "AuthGPG::GPGInit finished." << std::endl;
|
||||||
|
#endif
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
@ -639,12 +644,12 @@ int AuthGPG::privateTrustCertificate(const RsPgpId& id, int trustlvl)
|
|||||||
{
|
{
|
||||||
RsStackMutex stack(gpgMtxData); /******* LOCKED ******/
|
RsStackMutex stack(gpgMtxData); /******* LOCKED ******/
|
||||||
|
|
||||||
/* The certificate should be in Peers list ??? */
|
// csoler: Why are we not allowing this when the peer is not in the accepted peers list??
|
||||||
|
// The trust level is only a user-defined property that has nothing to
|
||||||
|
// do with the fact that we allow connections or not.
|
||||||
|
|
||||||
if(!isGPGAccepted(id))
|
if(!isGPGAccepted(id))
|
||||||
{
|
|
||||||
std::cerr << "Invalid Certificate" << std::endl;
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
|
||||||
|
|
||||||
int res = PGPHandler::privateTrustCertificate(id,trustlvl) ;
|
int res = PGPHandler::privateTrustCertificate(id,trustlvl) ;
|
||||||
_force_sync_database = true ;
|
_force_sync_database = true ;
|
||||||
|
@ -109,6 +109,8 @@ bool RsAccountsDetail::checkAccountDirectory()
|
|||||||
return setupAccount(PathAccountDirectory());
|
return setupAccount(PathAccountDirectory());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#warning we need to clean that up. Login should only ask for a SSL id, instead of a std::string.
|
||||||
|
|
||||||
bool RsAccountsDetail::selectAccountByString(const std::string &prefUserString)
|
bool RsAccountsDetail::selectAccountByString(const std::string &prefUserString)
|
||||||
{
|
{
|
||||||
if (mAccountsLocked)
|
if (mAccountsLocked)
|
||||||
@ -137,9 +139,14 @@ bool RsAccountsDetail::selectAccountByString(const std::string &prefUserString)
|
|||||||
{
|
{
|
||||||
mPreferredId = it->second.mSslId;
|
mPreferredId = it->second.mSslId;
|
||||||
pgpNameFound = true;
|
pgpNameFound = true;
|
||||||
|
|
||||||
|
std::cerr << "Account selected: " << ssl_id << std::endl;
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return pgpNameFound;
|
std::cerr << "No suitable candidate found." << std::endl;
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -453,15 +460,19 @@ bool RsAccountsDetail::getPreferredAccountId(RsPeerId &id)
|
|||||||
bool RsAccountsDetail::getAccountIds(std::list<RsPeerId> &ids)
|
bool RsAccountsDetail::getAccountIds(std::list<RsPeerId> &ids)
|
||||||
{
|
{
|
||||||
std::map<RsPeerId, AccountDetails>::iterator it;
|
std::map<RsPeerId, AccountDetails>::iterator it;
|
||||||
|
#ifdef DEBUG_ACCOUNTS
|
||||||
std::cerr << "getAccountIds:" << std::endl;
|
std::cerr << "getAccountIds:" << std::endl;
|
||||||
|
#endif
|
||||||
|
|
||||||
for(it = mAccounts.begin(); it != mAccounts.end(); ++it)
|
for(it = mAccounts.begin(); it != mAccounts.end(); ++it)
|
||||||
{
|
{
|
||||||
|
#ifdef DEBUG_ACCOUNTS
|
||||||
std::cerr << "SSL Id: " << it->second.mSslId << " PGP Id " << it->second.mPgpId;
|
std::cerr << "SSL Id: " << it->second.mSslId << " PGP Id " << it->second.mPgpId;
|
||||||
std::cerr << " PGP Name: " << it->second.mPgpName;
|
std::cerr << " PGP Name: " << it->second.mPgpName;
|
||||||
std::cerr << " PGP Email: " << it->second.mPgpEmail;
|
std::cerr << " PGP Email: " << it->second.mPgpEmail;
|
||||||
std::cerr << " Location: " << it->second.mLocation;
|
std::cerr << " Location: " << it->second.mLocation;
|
||||||
std::cerr << std::endl;
|
std::cerr << std::endl;
|
||||||
|
#endif
|
||||||
|
|
||||||
ids.push_back(it->first);
|
ids.push_back(it->first);
|
||||||
}
|
}
|
||||||
@ -868,12 +879,16 @@ bool RsAccountsDetail::SelectPGPAccount(const RsPgpId& pgpId)
|
|||||||
if (0 < AuthGPG::getAuthGPG() -> GPGInit(pgpId))
|
if (0 < AuthGPG::getAuthGPG() -> GPGInit(pgpId))
|
||||||
{
|
{
|
||||||
retVal = true;
|
retVal = true;
|
||||||
|
#ifdef DEBUG_ACCOUNTS
|
||||||
std::cerr << "PGP Auth Success!";
|
std::cerr << "PGP Auth Success!";
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
std::cerr << "PGP Auth Failed!";
|
std::cerr << "PGP Auth Failed!";
|
||||||
|
|
||||||
|
#ifdef DEBUG_ACCOUNTS
|
||||||
std::cerr << " ID: " << pgpId << std::endl;
|
std::cerr << " ID: " << pgpId << std::endl;
|
||||||
|
#endif
|
||||||
|
|
||||||
return retVal;
|
return retVal;
|
||||||
}
|
}
|
||||||
|
@ -89,6 +89,7 @@
|
|||||||
// #define GPG_DEBUG
|
// #define GPG_DEBUG
|
||||||
// #define AUTHSSL_DEBUG
|
// #define AUTHSSL_DEBUG
|
||||||
// #define FIM_DEBUG
|
// #define FIM_DEBUG
|
||||||
|
// #define DEBUG_RSINIT
|
||||||
|
|
||||||
//std::map<std::string,std::vector<std::string> > RsInit::unsupported_keys ;
|
//std::map<std::string,std::vector<std::string> > RsInit::unsupported_keys ;
|
||||||
|
|
||||||
@ -270,303 +271,250 @@ bool doPortRestrictions = false;
|
|||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef WINDOWS_SYS
|
||||||
/******************************** WINDOWS/UNIX SPECIFIC PART ******************/
|
#ifdef PTW32_STATIC_LIB
|
||||||
#ifndef WINDOWS_SYS
|
#include <pthread.h>
|
||||||
int RsInit::InitRetroShare(int argc, char **argv, bool /* strictCheck */)
|
#endif
|
||||||
{
|
|
||||||
/******************************** WINDOWS/UNIX SPECIFIC PART ******************/
|
|
||||||
#else
|
|
||||||
|
|
||||||
/* for static PThreads under windows... we need to init the library...
|
|
||||||
*/
|
|
||||||
#ifdef PTW32_STATIC_LIB
|
|
||||||
#include <pthread.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
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];
|
|
||||||
char *wholeline = (char*)GetCommandLine();
|
|
||||||
int cmdlen = strlen(wholeline);
|
|
||||||
// duplicate line, so we can put in spaces..
|
|
||||||
char dupline[cmdlen+1];
|
|
||||||
strcpy(dupline, wholeline);
|
|
||||||
|
|
||||||
/* break wholeline down ....
|
|
||||||
* NB. This is very simplistic, and will not
|
|
||||||
* handle multiple spaces, or quotations etc, only for debugging purposes
|
|
||||||
*/
|
|
||||||
argv[0] = dupline;
|
|
||||||
for(i = 1, j = 0; (j + 1 < cmdlen) && (i < MAX_ARGS);)
|
|
||||||
{
|
|
||||||
/* find next space. */
|
|
||||||
for(;(j + 1 < cmdlen) && (dupline[j] != ' ');j++);
|
|
||||||
if (j + 1 < cmdlen)
|
|
||||||
{
|
|
||||||
dupline[j] = '\0';
|
|
||||||
argv[i++] = &(dupline[j+1]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
argc = i;
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
for( i=0; i<argc; i++)
|
int RsInit::InitRetroShare(int _argc, char **_argv, bool /* strictCheck */)
|
||||||
printf("%d: %s\n", i, argv[i]);
|
{
|
||||||
|
/******************************** WINDOWS/UNIX SPECIFIC PART ******************/
|
||||||
|
#ifdef WINDOWS_SYS
|
||||||
|
/* THIS IS A HACK TO ALLOW WINDOWS TO ACCEPT COMMANDLINE ARGUMENTS */
|
||||||
|
|
||||||
/* for static PThreads under windows... we need to init the library...
|
int argc;
|
||||||
*/
|
int i;
|
||||||
#ifdef PTW32_STATIC_LIB
|
const int MAX_ARGS = 32;
|
||||||
pthread_win32_process_attach_np();
|
int j;
|
||||||
#endif
|
char *argv[MAX_ARGS];
|
||||||
|
char *wholeline = (char*)GetCommandLine();
|
||||||
|
int cmdlen = strlen(wholeline);
|
||||||
|
// duplicate line, so we can put in spaces..
|
||||||
|
char dupline[cmdlen+1];
|
||||||
|
strcpy(dupline, wholeline);
|
||||||
|
|
||||||
|
/* break wholeline down ....
|
||||||
|
* NB. This is very simplistic, and will not
|
||||||
|
* handle multiple spaces, or quotations etc, only for debugging purposes
|
||||||
|
*/
|
||||||
|
argv[0] = dupline;
|
||||||
|
for(i = 1, j = 0; (j + 1 < cmdlen) && (i < MAX_ARGS);)
|
||||||
|
{
|
||||||
|
/* find next space. */
|
||||||
|
for(;(j + 1 < cmdlen) && (dupline[j] != ' ');j++);
|
||||||
|
if (j + 1 < cmdlen)
|
||||||
|
{
|
||||||
|
dupline[j] = '\0';
|
||||||
|
argv[i++] = &(dupline[j+1]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
argc = i;
|
||||||
|
#else
|
||||||
|
char **argv = _argv ;
|
||||||
|
int argc = _argc ;
|
||||||
#endif
|
#endif
|
||||||
/******************************** WINDOWS/UNIX SPECIFIC PART ******************/
|
|
||||||
|
|
||||||
std::string prefUserString = "";
|
#ifdef DEBUG_RSINIT
|
||||||
std::string opt_base_dir;
|
for(int i=0; i<argc; i++)
|
||||||
|
printf("%d: %s\n", i, argv[i]);
|
||||||
|
#endif
|
||||||
|
|
||||||
/* getopt info: every availiable option is listed here. if it is followed by a ':' it
|
/* for static PThreads under windows... we need to init the library... */
|
||||||
needs an argument. If it is followed by a '::' the argument is optional.
|
#ifdef PTW32_STATIC_LIB
|
||||||
*/
|
pthread_win32_process_attach_np();
|
||||||
//rsInitConfig->logfname = "" ;
|
#endif
|
||||||
//rsInitConfig->inet = "" ;
|
/******************************** WINDOWS/UNIX SPECIFIC PART ******************/
|
||||||
|
|
||||||
|
std::string prefUserString = "";
|
||||||
|
std::string opt_base_dir;
|
||||||
|
|
||||||
|
/* getopt info: every availiable option is listed here. if it is followed by a ':' it
|
||||||
|
needs an argument. If it is followed by a '::' the argument is optional.
|
||||||
|
*/
|
||||||
|
//rsInitConfig->logfname = "" ;
|
||||||
|
//rsInitConfig->inet = "" ;
|
||||||
|
|
||||||
#ifdef __APPLE__
|
#ifdef __APPLE__
|
||||||
/* HACK to avoid stupid OSX Finder behaviour
|
/* HACK to avoid stupid OSX Finder behaviour
|
||||||
* remove the commandline arguments - if we detect we are launched from Finder,
|
* remove the commandline arguments - if we detect we are launched from Finder,
|
||||||
* and we have the unparsable "-psn_0_12332" option.
|
* and we have the unparsable "-psn_0_12332" option.
|
||||||
* this is okay, as you cannot pass commandline arguments via Finder anyway
|
* this is okay, as you cannot pass commandline arguments via Finder anyway
|
||||||
*/
|
*/
|
||||||
if ((argc >= 2) && (0 == strncmp(argv[1], "-psn", 4)))
|
if ((argc >= 2) && (0 == strncmp(argv[1], "-psn", 4)))
|
||||||
{
|
{
|
||||||
argc = 1;
|
argc = 1;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
argstream as(argc,argv) ;
|
argstream as(argc,argv) ;
|
||||||
|
|
||||||
|
|
||||||
as >> option('a',"auto-login" ,rsInitConfig->autoLogin ,"AutoLogin (Windows Only) + StartMinimised")
|
as
|
||||||
>> option('m',"minimized" ,rsInitConfig->startMinimised ,"Start minimized." )
|
#ifdef RS_AUTOLOGIN
|
||||||
>> option('s',"stderr" ,rsInitConfig->outStderr ,"output to stderr instead of log file." )
|
>> option('a',"auto-login" ,rsInitConfig->autoLogin ,"AutoLogin (Windows Only) + StartMinimised")
|
||||||
>> option('u',"udp" ,rsInitConfig->udpListenerOnly,"Only listen to UDP." )
|
#endif
|
||||||
>> option('e',"external-port" ,rsInitConfig->forceExtPort ,"Use a forwarded external port." )
|
>> 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('l',"log-file" ,rsInitConfig->logfname ,"logfile" ,"Set Log filename." ,false)
|
||||||
>> parameter('d',"debug-level" ,rsInitConfig->debugLevel ,"level" ,"Set debug level." ,false)
|
>> parameter('d',"debug-level" ,rsInitConfig->debugLevel ,"level" ,"Set debug level." ,false)
|
||||||
>> parameter('w',"password" ,rsInitConfig->passwd ,"password" ,"Set Login Password." ,false)
|
#ifdef TO_REMOVE
|
||||||
>> parameter('i',"ip-address" ,rsInitConfig->inet ,"nnn.nnn.nnn.nnn", "Set IP address to use." ,false)
|
// This as removed because it is not used anymore.
|
||||||
>> parameter('p',"port" ,rsInitConfig->port ,"port", "Set listenning port to use." ,false)
|
|
||||||
>> parameter('c',"base-dir" ,opt_base_dir ,"directory", "Set base directory." ,false)
|
>> parameter('w',"password" ,rsInitConfig->passwd ,"password" ,"Set Login Password." ,false)
|
||||||
>> parameter('U',"user-id" ,prefUserString ,"ID", "[User Name/GPG id/SSL id] Sets Account to Use, Useful when Autologin is enabled",false)
|
#endif
|
||||||
// by rshare 'r' "link" "Link" "Open RsLink with protocol retroshare://"
|
>> parameter('i',"ip-address" ,rsInitConfig->inet ,"nnn.nnn.nnn.nnn", "Force IP address to use (if cannot be detected)." ,false)
|
||||||
// by rshare 'f' "rsfile" "RsFile" "Open RsFile like RsCollection"
|
>> parameter('p',"port" ,rsInitConfig->port ,"port", "Set listenning port to use." ,false)
|
||||||
|
>> parameter('c',"base-dir" ,opt_base_dir ,"directory", "Set base directory." ,false)
|
||||||
|
>> parameter('U',"user-id" ,prefUserString ,"ID", "[ocation Id] Sets Account to Use, Useful when Autologin is enabled.",false)
|
||||||
|
// by rshare 'r' "link" "Link" "Open RsLink with protocol retroshare://"
|
||||||
|
// by rshare 'f' "rsfile" "RsFile" "Open RsFile like RsCollection"
|
||||||
#ifdef LOCALNET_TESTING
|
#ifdef LOCALNET_TESTING
|
||||||
>> parameter('R',"restrict-port" ,portRestrictions ,"port1-port2","Apply port restriction" ,false)
|
>> parameter('R',"restrict-port" ,portRestrictions ,"port1-port2","Apply port restriction" ,false)
|
||||||
#endif
|
#endif
|
||||||
>> help('h',"help","Display this Help") ;
|
>> help('h',"help","Display this Help") ;
|
||||||
|
|
||||||
as.defaultErrorHandling(true) ;
|
as.defaultErrorHandling(true,true) ;
|
||||||
|
|
||||||
if(rsInitConfig->autoLogin) rsInitConfig->startMinimised = true ;
|
if(rsInitConfig->autoLogin) rsInitConfig->startMinimised = true ;
|
||||||
if(rsInitConfig->outStderr) rsInitConfig->haveLogFile = false ;
|
if(rsInitConfig->outStderr) rsInitConfig->haveLogFile = false ;
|
||||||
if(!rsInitConfig->logfname.empty()) rsInitConfig->haveLogFile = true;
|
if(!rsInitConfig->logfname.empty()) rsInitConfig->haveLogFile = true;
|
||||||
if(rsInitConfig->inet != "127.0.0.1") rsInitConfig->forceLocalAddr = true;
|
if(rsInitConfig->inet != "127.0.0.1") rsInitConfig->forceLocalAddr = true;
|
||||||
#ifdef LOCALNET_TESTING
|
#ifdef LOCALNET_TESTING
|
||||||
if(!portRestrictions.empty()) doPortRestrictions = true;
|
if(!portRestrictions.empty()) doPortRestrictions = true;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef SUSPENDED_CODE
|
setOutputLevel((RsLog::logLvl)rsInitConfig->debugLevel);
|
||||||
#ifdef LOCALNET_TESTING
|
|
||||||
while((c = getopt(argc, argv,"hesamui:p:c:w:l:d:U:r:R:")) != -1)
|
|
||||||
#else
|
|
||||||
while((c = getopt(argc, argv,"hesamui:p:c:w:l:d:U:r:")) != -1)
|
|
||||||
#endif
|
|
||||||
{
|
|
||||||
switch (c)
|
|
||||||
{
|
|
||||||
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;
|
|
||||||
std::cerr << "-l [logfile] Set the logfilename" << std::endl;
|
|
||||||
std::cerr << "-w [password] Set the password" << std::endl;
|
|
||||||
std::cerr << "-i [ip_adress] Set IP Adress to use" << std::endl;
|
|
||||||
std::cerr << "-p [port] Set the Port to listen on" << std::endl;
|
|
||||||
std::cerr << "-c [basedir] Set the config basdir" << std::endl;
|
|
||||||
std::cerr << "-s Output to Stderr" << std::endl;
|
|
||||||
std::cerr << "-d [debuglevel] Set the debuglevel" << std::endl;
|
|
||||||
std::cerr << "-a AutoLogin (Windows Only) + StartMinimised" << std::endl;
|
|
||||||
std::cerr << "-m StartMinimised" << std::endl;
|
|
||||||
std::cerr << "-u Only listen to UDP" << std::endl;
|
|
||||||
std::cerr << "-e Use a forwarded external Port" << std::endl ;
|
|
||||||
std::cerr << "-U [User Name/GPG id/SSL id] Sets Account to Use, Useful when Autologin is enabled." << std::endl;
|
|
||||||
std::cerr << "-r link Use RetroShare link." << std::endl;
|
|
||||||
#ifdef LOCALNET_TESTING
|
|
||||||
std::cerr << "-R <lport-uport> Port Restrictions." << std::endl;
|
|
||||||
#endif
|
|
||||||
exit(1);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
if (strictCheck) {
|
|
||||||
std::cerr << "Unknown Option!" << std::endl;
|
|
||||||
std::cerr << "Use '-h' for help." << std::endl;
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
setOutputLevel((RsLog::logLvl)rsInitConfig->debugLevel);
|
// set the debug file.
|
||||||
|
if (rsInitConfig->haveLogFile)
|
||||||
|
setDebugFile(rsInitConfig->logfname.c_str());
|
||||||
|
|
||||||
// // set the default Debug Level...
|
/******************************** WINDOWS/UNIX SPECIFIC PART ******************/
|
||||||
// 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
|
#ifndef WINDOWS_SYS
|
||||||
/********************************** WINDOWS/UNIX SPECIFIC PART ******************/
|
/********************************** WINDOWS/UNIX SPECIFIC PART ******************/
|
||||||
#else
|
#else
|
||||||
// Windows Networking Init.
|
// Windows Networking Init.
|
||||||
WORD wVerReq = MAKEWORD(2,2);
|
WORD wVerReq = MAKEWORD(2,2);
|
||||||
WSADATA wsaData;
|
WSADATA wsaData;
|
||||||
|
|
||||||
if (0 != WSAStartup(wVerReq, &wsaData))
|
if (0 != WSAStartup(wVerReq, &wsaData))
|
||||||
{
|
{
|
||||||
std::cerr << "Failed to Startup Windows Networking";
|
std::cerr << "Failed to Startup Windows Networking";
|
||||||
std::cerr << std::endl;
|
std::cerr << std::endl;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
std::cerr << "Started Windows Networking";
|
std::cerr << "Started Windows Networking";
|
||||||
std::cerr << std::endl;
|
std::cerr << std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
/********************************** WINDOWS/UNIX SPECIFIC PART ******************/
|
/********************************** WINDOWS/UNIX SPECIFIC PART ******************/
|
||||||
// SWITCH off the SIGPIPE - kills process on Linux.
|
// SWITCH off the SIGPIPE - kills process on Linux.
|
||||||
/******************************** WINDOWS/UNIX SPECIFIC PART ******************/
|
/******************************** WINDOWS/UNIX SPECIFIC PART ******************/
|
||||||
#ifndef WINDOWS_SYS
|
#ifndef WINDOWS_SYS
|
||||||
struct sigaction sigact;
|
struct sigaction sigact;
|
||||||
sigact.sa_handler = SIG_IGN;
|
sigact.sa_handler = SIG_IGN;
|
||||||
sigact.sa_flags = 0;
|
sigact.sa_flags = 0;
|
||||||
|
|
||||||
sigset_t set;
|
sigset_t set;
|
||||||
sigemptyset(&set);
|
sigemptyset(&set);
|
||||||
//sigaddset(&set, SIGINT); // or whatever other signal
|
//sigaddset(&set, SIGINT); // or whatever other signal
|
||||||
sigact.sa_mask = set;
|
sigact.sa_mask = set;
|
||||||
|
|
||||||
if (0 == sigaction(SIGPIPE, &sigact, NULL))
|
if (0 == sigaction(SIGPIPE, &sigact, NULL))
|
||||||
{
|
{
|
||||||
std::cerr << "RetroShare:: Successfully installed the SIGPIPE Block" << std::endl;
|
std::cerr << "RetroShare:: Successfully installed the SIGPIPE Block" << std::endl;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
std::cerr << "RetroShare:: Failed to install the SIGPIPE Block" << std::endl;
|
std::cerr << "RetroShare:: Failed to install the SIGPIPE Block" << std::endl;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
/******************************** WINDOWS/UNIX SPECIFIC PART ******************/
|
/******************************** WINDOWS/UNIX SPECIFIC PART ******************/
|
||||||
|
|
||||||
// Hash the main executable.
|
// Hash the main executable.
|
||||||
|
|
||||||
uint64_t tmp_size ;
|
uint64_t tmp_size ;
|
||||||
|
|
||||||
if(!RsDirUtil::getFileHash(argv[0],rsInitConfig->main_executable_hash,tmp_size,NULL))
|
if(!RsDirUtil::getFileHash(argv[0],rsInitConfig->main_executable_hash,tmp_size,NULL))
|
||||||
std::cerr << "Cannot hash executable! Plugins will not be loaded correctly." << std::endl;
|
std::cerr << "Cannot hash executable! Plugins will not be loaded correctly." << std::endl;
|
||||||
else
|
else
|
||||||
std::cerr << "Hashed main executable: " << rsInitConfig->main_executable_hash << std::endl;
|
std::cerr << "Hashed main executable: " << rsInitConfig->main_executable_hash << std::endl;
|
||||||
|
|
||||||
/* At this point we want to.
|
/* At this point we want to.
|
||||||
* 1) Load up Dase Directory.
|
* 1) Load up Dase Directory.
|
||||||
* 3) Get Prefered Id.
|
* 3) Get Prefered Id.
|
||||||
* 2) Get List of Available Accounts.
|
* 2) Get List of Available Accounts.
|
||||||
* 4) Get List of GPG Accounts.
|
* 4) Get List of GPG Accounts.
|
||||||
*/
|
*/
|
||||||
/* create singletons */
|
/* create singletons */
|
||||||
AuthSSL::AuthSSLInit();
|
AuthSSL::AuthSSLInit();
|
||||||
AuthSSL::getAuthSSL() -> InitAuth(NULL, NULL, NULL, "");
|
AuthSSL::getAuthSSL() -> InitAuth(NULL, NULL, NULL, "");
|
||||||
|
|
||||||
rsAccounts = new RsAccountsDetail();
|
rsAccounts = new RsAccountsDetail();
|
||||||
|
|
||||||
// first check config directories, and set bootstrap values.
|
// first check config directories, and set bootstrap values.
|
||||||
if(!rsAccounts->setupBaseDirectory(opt_base_dir))
|
if(!rsAccounts->setupBaseDirectory(opt_base_dir))
|
||||||
return RS_INIT_BASE_DIR_ERROR ;
|
return RS_INIT_BASE_DIR_ERROR ;
|
||||||
|
|
||||||
// Setup PGP stuff.
|
// Setup PGP stuff.
|
||||||
std::string pgp_dir = rsAccounts->PathPGPDirectory();
|
std::string pgp_dir = rsAccounts->PathPGPDirectory();
|
||||||
|
|
||||||
if(!RsDirUtil::checkCreateDirectory(pgp_dir))
|
if(!RsDirUtil::checkCreateDirectory(pgp_dir))
|
||||||
throw std::runtime_error("Cannot create pgp directory " + pgp_dir) ;
|
throw std::runtime_error("Cannot create pgp directory " + pgp_dir) ;
|
||||||
|
|
||||||
AuthGPG::init( pgp_dir + "/retroshare_public_keyring.gpg",
|
AuthGPG::init( pgp_dir + "/retroshare_public_keyring.gpg",
|
||||||
pgp_dir + "/retroshare_secret_keyring.gpg",
|
pgp_dir + "/retroshare_secret_keyring.gpg",
|
||||||
pgp_dir + "/retroshare_trustdb.gpg",
|
pgp_dir + "/retroshare_trustdb.gpg",
|
||||||
pgp_dir + "/lock");
|
pgp_dir + "/lock");
|
||||||
|
|
||||||
// load Accounts.
|
// load Accounts.
|
||||||
if (!rsAccounts->loadAccounts())
|
if (!rsAccounts->loadAccounts())
|
||||||
{
|
return RS_INIT_NO_KEYRING ;
|
||||||
return RS_INIT_NO_KEYRING ;
|
|
||||||
}
|
|
||||||
|
|
||||||
// choose alternative account.
|
// choose alternative account.
|
||||||
if(prefUserString != "")
|
if(prefUserString != "")
|
||||||
{
|
|
||||||
if (!rsAccounts->selectAccountByString(prefUserString))
|
|
||||||
{
|
{
|
||||||
std::cerr << "Invalid User name/GPG id/SSL id: not found in list";
|
RsPeerId ssl_id(prefUserString);
|
||||||
std::cerr << std::endl;
|
|
||||||
return RS_INIT_AUTH_FAILED ;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* check that we have selected someone */
|
if(ssl_id.isNull())
|
||||||
RsPeerId preferredId;
|
{
|
||||||
bool existingUser = rsAccounts->getPreferredAccountId(preferredId);
|
std::cerr << "Invalid User location id: not found in list";
|
||||||
|
std::cerr << std::endl;
|
||||||
|
return RS_INIT_AUTH_FAILED ;
|
||||||
|
}
|
||||||
|
|
||||||
if (existingUser)
|
if(rsAccounts->selectId(ssl_id))
|
||||||
{
|
{
|
||||||
if (rsInitConfig->passwd != "")
|
std::cerr << "Auto-selectng account ID " << ssl_id << std::endl;
|
||||||
{
|
return RS_INIT_HAVE_ACCOUNT;
|
||||||
return RS_INIT_HAVE_ACCOUNT;
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(RsLoginHandler::getSSLPassword(preferredId,false,rsInitConfig->passwd))
|
#ifdef TO_REMOVE
|
||||||
|
/* check that we have selected someone */
|
||||||
|
RsPeerId preferredId;
|
||||||
|
bool existingUser = rsAccounts->getPreferredAccountId(preferredId);
|
||||||
|
|
||||||
|
if (existingUser)
|
||||||
{
|
{
|
||||||
RsInit::setAutoLogin(true);
|
if (rsInitConfig->passwd != "")
|
||||||
std::cerr << "Autologin has succeeded" << std::endl;
|
|
||||||
return RS_INIT_HAVE_ACCOUNT;
|
if(RsLoginHandler::getSSLPassword(preferredId,false,rsInitConfig->passwd))
|
||||||
|
{
|
||||||
|
RsInit::setAutoLogin(true);
|
||||||
|
std::cerr << "Autologin has succeeded" << std::endl;
|
||||||
|
return RS_INIT_HAVE_ACCOUNT;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
#endif
|
||||||
return RS_INIT_OK;
|
return RS_INIT_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -705,7 +653,9 @@ int RsInit::LoadCertificates(bool autoLoginNT)
|
|||||||
|
|
||||||
if(rsInitConfig->passwd == "") {
|
if(rsInitConfig->passwd == "") {
|
||||||
if (RsLoginHandler::getSSLPassword(preferredId,true,rsInitConfig->passwd) == false) {
|
if (RsLoginHandler::getSSLPassword(preferredId,true,rsInitConfig->passwd) == false) {
|
||||||
|
#ifdef DEBUG_RSINIT
|
||||||
std::cerr << "RsLoginHandler::getSSLPassword() Failed!";
|
std::cerr << "RsLoginHandler::getSSLPassword() Failed!";
|
||||||
|
#endif
|
||||||
return 0 ;
|
return 0 ;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
@ -5,6 +5,8 @@
|
|||||||
#include "util/rsdir.h"
|
#include "util/rsdir.h"
|
||||||
#include "rsaccounts.h"
|
#include "rsaccounts.h"
|
||||||
|
|
||||||
|
//#define DEBUG_RSLOGINHANDLER 1
|
||||||
|
|
||||||
bool RsLoginHandler::getSSLPassword( const RsPeerId& ssl_id,
|
bool RsLoginHandler::getSSLPassword( const RsPeerId& ssl_id,
|
||||||
bool enable_gpg_ask_passwd,
|
bool enable_gpg_ask_passwd,
|
||||||
std::string& ssl_passwd )
|
std::string& ssl_passwd )
|
||||||
@ -59,15 +61,21 @@ bool RsLoginHandler::getSSLPasswdFromGPGFile(const RsPeerId& ssl_id,std::string&
|
|||||||
|
|
||||||
fclose(sslPassphraseFile);
|
fclose(sslPassphraseFile);
|
||||||
|
|
||||||
|
#ifdef DEBUG_RSLOGINHANDLER
|
||||||
std::cerr << "opening sslPassphraseFile : "
|
std::cerr << "opening sslPassphraseFile : "
|
||||||
<< getSSLPasswdFileName(ssl_id).c_str() << std::endl;
|
<< getSSLPasswdFileName(ssl_id).c_str() << std::endl;
|
||||||
|
#endif
|
||||||
|
|
||||||
std::string plain;
|
std::string plain;
|
||||||
if ( AuthGPG::getAuthGPG()->decryptTextFromFile(
|
if ( AuthGPG::getAuthGPG()->decryptTextFromFile( plain, getSSLPasswdFileName(ssl_id)) )
|
||||||
plain, getSSLPasswdFileName(ssl_id)) )
|
|
||||||
{
|
{
|
||||||
std::cerr << "Decrypting went ok !" << std::endl;
|
|
||||||
sslPassword = plain;
|
sslPassword = plain;
|
||||||
|
#ifdef DEBUG_RSLOGINHANDLER
|
||||||
|
if(sslPassword.length() > 0)
|
||||||
|
std::cerr << "Decrypting went ok !" << std::endl;
|
||||||
|
else
|
||||||
|
std::cerr << "Passphrase is empty!" << std::endl;
|
||||||
|
#endif
|
||||||
|
|
||||||
return sslPassword.length() > 0 ;
|
return sslPassword.length() > 0 ;
|
||||||
}
|
}
|
||||||
@ -185,7 +193,9 @@ extern BOOL WINAPI CryptUnprotectData(
|
|||||||
|
|
||||||
bool RsLoginHandler::tryAutoLogin(const RsPeerId& ssl_id,std::string& ssl_passwd)
|
bool RsLoginHandler::tryAutoLogin(const RsPeerId& ssl_id,std::string& ssl_passwd)
|
||||||
{
|
{
|
||||||
|
#ifdef DEBUG_RSLOGINHANDLER
|
||||||
std::cerr << "RsTryAutoLogin()" << std::endl;
|
std::cerr << "RsTryAutoLogin()" << std::endl;
|
||||||
|
#endif
|
||||||
|
|
||||||
/******************************** WINDOWS/UNIX SPECIFIC PART ******************/
|
/******************************** WINDOWS/UNIX SPECIFIC PART ******************/
|
||||||
#ifndef __HAIKU__
|
#ifndef __HAIKU__
|
||||||
@ -194,7 +204,9 @@ bool RsLoginHandler::tryAutoLogin(const RsPeerId& ssl_id,std::string& ssl_passwd
|
|||||||
|
|
||||||
gchar *passwd = NULL;
|
gchar *passwd = NULL;
|
||||||
|
|
||||||
|
#ifdef DEBUG_RSLOGINHANDLER
|
||||||
std::cerr << "Using attribute: " << ssl_id << std::endl;
|
std::cerr << "Using attribute: " << ssl_id << std::endl;
|
||||||
|
#endif
|
||||||
if( gnome_keyring_find_password_sync(&my_schema, &passwd,"RetroShare SSL Id",ssl_id.toStdString().c_str(),NULL) == GNOME_KEYRING_RESULT_OK )
|
if( gnome_keyring_find_password_sync(&my_schema, &passwd,"RetroShare SSL Id",ssl_id.toStdString().c_str(),NULL) == GNOME_KEYRING_RESULT_OK )
|
||||||
{
|
{
|
||||||
std::cerr << "Got SSL passwd ********************" /*<< passwd*/ << " from gnome keyring" << std::endl;
|
std::cerr << "Got SSL passwd ********************" /*<< passwd*/ << " from gnome keyring" << std::endl;
|
||||||
@ -203,7 +215,9 @@ bool RsLoginHandler::tryAutoLogin(const RsPeerId& ssl_id,std::string& ssl_passwd
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
#ifdef DEBUG_RSLOGINHANDLER
|
||||||
std::cerr << "Could not get passwd from gnome keyring" << std::endl;
|
std::cerr << "Could not get passwd from gnome keyring" << std::endl;
|
||||||
|
#endif
|
||||||
return false ;
|
return false ;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -252,8 +252,8 @@ namespace
|
|||||||
inline bool helpRequested() const;
|
inline bool helpRequested() const;
|
||||||
inline bool isOk() const;
|
inline bool isOk() const;
|
||||||
inline std::string errorLog() const;
|
inline std::string errorLog() const;
|
||||||
inline std::string usage() const;
|
inline std::string usage(bool skipCommandLine = false) const;
|
||||||
inline bool defaultErrorHandling(bool ignoreUnused=false) const;
|
inline bool defaultErrorHandling(bool ignoreUnused=false,bool skipCommandLine=false) const;
|
||||||
static inline char uniqueLetter();
|
static inline char uniqueLetter();
|
||||||
protected:
|
protected:
|
||||||
void parse(int argc,char** argv);
|
void parse(int argc,char** argv);
|
||||||
@ -569,10 +569,12 @@ namespace
|
|||||||
return helpRequested_;
|
return helpRequested_;
|
||||||
}
|
}
|
||||||
inline std::string
|
inline std::string
|
||||||
argstream::usage() const
|
argstream::usage(bool skipCommandLine) const
|
||||||
{
|
{
|
||||||
std::ostringstream os;
|
std::ostringstream os;
|
||||||
os<<"usage: "<<progName_<<cmdLine_<<'\n';
|
|
||||||
|
if(!skipCommandLine)
|
||||||
|
os<<"usage: "<<progName_<<cmdLine_<<'\n';
|
||||||
unsigned int lmax = 0;
|
unsigned int lmax = 0;
|
||||||
for (std::deque<help_entry>::const_iterator
|
for (std::deque<help_entry>::const_iterator
|
||||||
iter = argHelps_.begin();iter != argHelps_.end();++iter)
|
iter = argHelps_.begin();iter != argHelps_.end();++iter)
|
||||||
@ -820,11 +822,11 @@ namespace
|
|||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
inline bool
|
inline bool
|
||||||
argstream::defaultErrorHandling(bool ignoreUnused) const
|
argstream::defaultErrorHandling(bool ignoreUnused,bool skipCommandLine) const
|
||||||
{
|
{
|
||||||
if (helpRequested_)
|
if (helpRequested_)
|
||||||
{
|
{
|
||||||
std::cout<<usage();
|
std::cout<<usage(skipCommandLine);
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
if (!isOk_)
|
if (!isOk_)
|
||||||
|
@ -3247,7 +3247,7 @@ int ops_parse(ops_parse_info_t *pinfo,ops_boolean_t limit_packets)
|
|||||||
} while (r > 0);
|
} while (r > 0);
|
||||||
|
|
||||||
return pinfo->errors ? 0 : 1;
|
return pinfo->errors ? 0 : 1;
|
||||||
return r == -1 ? 0 : 1;
|
//return r == -1 ? 0 : 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -2,6 +2,8 @@
|
|||||||
|
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
|
#include <cmath>
|
||||||
|
#include <iomanip>
|
||||||
|
|
||||||
#include <api/JsonStream.h>
|
#include <api/JsonStream.h>
|
||||||
|
|
||||||
@ -52,7 +54,7 @@ public:
|
|||||||
// restore terminal settings
|
// restore terminal settings
|
||||||
tcsetattr(STDIN_FILENO, TCSANOW, &mOldTermSettings);
|
tcsetattr(STDIN_FILENO, TCSANOW, &mOldTermSettings);
|
||||||
#ifdef TERMINALINPUT_DEBUG
|
#ifdef TERMINALINPUT_DEBUG
|
||||||
std::cerr << "Terminal restored" << std::endl;
|
std::cerr << "Terminal killed" << std::endl;
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
@ -85,10 +87,8 @@ private:
|
|||||||
|
|
||||||
namespace resource_api {
|
namespace resource_api {
|
||||||
|
|
||||||
TerminalApiClient::TerminalApiClient(ApiServer *api):
|
TerminalApiClient::TerminalApiClient(ApiServer *api): mApiServer(api)
|
||||||
mApiServer(api)
|
|
||||||
{
|
{
|
||||||
start("resapi terminal");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
TerminalApiClient::~TerminalApiClient()
|
TerminalApiClient::~TerminalApiClient()
|
||||||
@ -96,6 +96,24 @@ TerminalApiClient::~TerminalApiClient()
|
|||||||
fullstop();
|
fullstop();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static std::string readStringFromKeyboard(bool passwd_mode)
|
||||||
|
{
|
||||||
|
int c ;
|
||||||
|
std::string s;
|
||||||
|
|
||||||
|
while((c=getchar()) != '\n')
|
||||||
|
{
|
||||||
|
if(passwd_mode)
|
||||||
|
putchar('*') ;
|
||||||
|
else
|
||||||
|
putchar(c) ;
|
||||||
|
|
||||||
|
s += c ;
|
||||||
|
}
|
||||||
|
putchar('\n');
|
||||||
|
return s ;
|
||||||
|
}
|
||||||
|
|
||||||
void TerminalApiClient::data_tick()
|
void TerminalApiClient::data_tick()
|
||||||
{
|
{
|
||||||
// values in milliseconds
|
// values in milliseconds
|
||||||
@ -109,16 +127,21 @@ void TerminalApiClient::data_tick()
|
|||||||
int last_char = 0;
|
int last_char = 0;
|
||||||
std::string inbuf;
|
std::string inbuf;
|
||||||
bool enter_was_pressed = false;
|
bool enter_was_pressed = false;
|
||||||
|
bool prev_is_bad = false ;
|
||||||
|
int account_number_size = 1 ;
|
||||||
|
int selected_account_number = 0 ;
|
||||||
|
int account_number_typed = 0 ;
|
||||||
|
|
||||||
StateToken runstate_state_token;
|
StateToken runstate_state_token;
|
||||||
std::string runstate;
|
std::string runstate;
|
||||||
|
|
||||||
std::vector<std::string> accounts;
|
std::vector<AccountInfo> accounts;
|
||||||
|
|
||||||
StateToken password_state_token;
|
StateToken password_state_token;
|
||||||
bool ask_for_password = false;
|
bool ask_for_password = false;
|
||||||
std::string key_name;
|
std::string key_name;
|
||||||
|
|
||||||
|
// This is only used to remove echo from the input and allow us to replace it by what we want.
|
||||||
TerminalInput term;
|
TerminalInput term;
|
||||||
|
|
||||||
while(!shouldStop())
|
while(!shouldStop())
|
||||||
@ -126,9 +149,12 @@ void TerminalApiClient::data_tick()
|
|||||||
// assuming sleep_time >> work_time
|
// assuming sleep_time >> work_time
|
||||||
// so we don't have to check the absolute time, just sleep every cycle
|
// so we don't have to check the absolute time, just sleep every cycle
|
||||||
usleep(MIN_WAIT_TIME * 1000);
|
usleep(MIN_WAIT_TIME * 1000);
|
||||||
last_io_poll += MIN_WAIT_TIME;
|
|
||||||
last_event_api_poll += MIN_WAIT_TIME;
|
last_event_api_poll += MIN_WAIT_TIME;
|
||||||
|
|
||||||
|
#ifdef TO_REMOVE
|
||||||
|
last_io_poll += MIN_WAIT_TIME;
|
||||||
|
|
||||||
if(last_io_poll >= IO_POLL_PERIOD)
|
if(last_io_poll >= IO_POLL_PERIOD)
|
||||||
{
|
{
|
||||||
last_io_poll = 0;
|
last_io_poll = 0;
|
||||||
@ -147,13 +173,20 @@ void TerminalApiClient::data_tick()
|
|||||||
enter_was_pressed = false;
|
enter_was_pressed = false;
|
||||||
// send echo
|
// send echo
|
||||||
if(ask_for_password)
|
if(ask_for_password)
|
||||||
|
{
|
||||||
std::cout << "*";
|
std::cout << "*";
|
||||||
|
std::cout.flush();
|
||||||
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
std::cout << (char) last_char;
|
std::cout << (char) last_char;
|
||||||
|
std::cout.flush();
|
||||||
|
}
|
||||||
|
|
||||||
//std::cout << "you pressed key " << (char) last_char << " as integer: " << last_char << std::endl;
|
//std::cout << "you pressed key " << (char) last_char << " as integer: " << last_char << std::endl;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
if(last_event_api_poll >= API_EVENT_POLL_PERIOD)
|
if(last_event_api_poll >= API_EVENT_POLL_PERIOD)
|
||||||
{
|
{
|
||||||
@ -165,141 +198,178 @@ void TerminalApiClient::data_tick()
|
|||||||
password_state_token = StateToken();
|
password_state_token = StateToken();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// If the core has started, we leave. Maybe we should not use this in the future if we want to allow to
|
||||||
|
// log out and then log in again?
|
||||||
|
|
||||||
|
if(runstate == "running_ok")
|
||||||
|
{
|
||||||
|
std::cerr << "Terminating terminal thread because the runstate says that the core is running." << std::endl;
|
||||||
|
shutdown();
|
||||||
|
}
|
||||||
|
|
||||||
bool edge = false;
|
bool edge = false;
|
||||||
if(runstate_state_token.isNull())
|
if(runstate_state_token.isNull())
|
||||||
{
|
{
|
||||||
edge = true;
|
edge = true;
|
||||||
JsonStream reqs;
|
readRunState(runstate_state_token,runstate) ;
|
||||||
JsonStream resps;
|
}
|
||||||
Request req(reqs);
|
|
||||||
std::stringstream ss;
|
|
||||||
Response resp(resps, ss);
|
|
||||||
|
|
||||||
req.mPath.push("runstate");
|
|
||||||
req.mPath.push("control");
|
|
||||||
reqs.switchToDeserialisation();
|
|
||||||
|
|
||||||
ApiServer::RequestId id = mApiServer->handleRequest(req, resp);
|
|
||||||
waitForResponse(id);
|
|
||||||
|
|
||||||
resps.switchToDeserialisation();
|
|
||||||
resps << makeKeyValueReference("runstate", runstate);
|
|
||||||
runstate_state_token = resp.mStateToken;
|
|
||||||
}
|
|
||||||
if(password_state_token.isNull())
|
if(password_state_token.isNull())
|
||||||
{
|
{
|
||||||
edge = true;
|
edge = true;
|
||||||
JsonStream reqs;
|
readPasswordState(password_state_token,ask_for_password,key_name,prev_is_bad) ;
|
||||||
JsonStream resps;
|
}
|
||||||
Request req(reqs);
|
|
||||||
std::stringstream ss;
|
|
||||||
Response resp(resps, ss);
|
|
||||||
|
|
||||||
req.mPath.push("password");
|
|
||||||
req.mPath.push("control");
|
|
||||||
reqs.switchToDeserialisation();
|
|
||||||
|
|
||||||
ApiServer::RequestId id = mApiServer->handleRequest(req, resp);
|
|
||||||
waitForResponse(id);
|
|
||||||
|
|
||||||
resps.switchToDeserialisation();
|
|
||||||
resps << makeKeyValueReference("want_password", ask_for_password);
|
|
||||||
resps << makeKeyValueReference("key_name", key_name);
|
|
||||||
password_state_token = resp.mStateToken;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(!ask_for_password && edge && runstate == "waiting_account_select")
|
if(!ask_for_password && edge && runstate == "waiting_account_select")
|
||||||
{
|
{
|
||||||
JsonStream reqs;
|
readAvailableAccounts(accounts) ;
|
||||||
JsonStream resps;
|
account_number_size = (int)ceil(log(accounts.size())/log(10.0f)) ;
|
||||||
Request req(reqs);
|
|
||||||
std::stringstream ss;
|
|
||||||
Response resp(resps, ss);
|
|
||||||
|
|
||||||
req.mPath.push("locations");
|
for(uint32_t i=0;i<accounts.size();++i)
|
||||||
req.mPath.push("control");
|
std::cout << "[" << std::setw(account_number_size) << std::setfill('0') << i << "] Location Id: " << accounts[i].ssl_id << " \"" << accounts[i].name << "\" (" << accounts[i].location << ")" << std::endl;
|
||||||
reqs.switchToDeserialisation();
|
|
||||||
|
|
||||||
ApiServer::RequestId id = mApiServer->handleRequest(req, resp);
|
selected_account_number = accounts.size() ;
|
||||||
waitForResponse(id);
|
account_number_typed = 0 ;
|
||||||
|
|
||||||
resps.switchToDeserialisation();
|
while(selected_account_number >= accounts.size())
|
||||||
std::cout << "Type a number to select an account" << std::endl;
|
{
|
||||||
if(!resps.hasMore())
|
std::cout << std::endl << "Type account number: " ;
|
||||||
std::cout << "Error: No Accounts. Use the Qt-GUI or the webinterface to create an account." << std::endl;
|
std::cout.flush() ;
|
||||||
int i = 0;
|
|
||||||
accounts.clear();
|
std::string s = readStringFromKeyboard(false) ;
|
||||||
while(resps.hasMore())
|
|
||||||
{
|
if(sscanf(s.c_str(),"%d",&selected_account_number) != 1)
|
||||||
std::string id;
|
continue ;
|
||||||
std::string name;
|
|
||||||
std::string location;
|
if(selected_account_number >= accounts.size())
|
||||||
resps.getStreamToMember()
|
{
|
||||||
<< makeKeyValueReference("id", id)
|
std::cerr << ": invalid account number (should be between " << std::setw(account_number_size) << std::setfill('0')
|
||||||
<< makeKeyValueReference("name", name)
|
<< 0 << " and " << std::setw(account_number_size) << std::setfill('0') << accounts.size()-1 << ")" << std::endl;
|
||||||
<< makeKeyValueReference("location", location);
|
std::cout << std::endl << "Type account number: " ;
|
||||||
std::cout << "[" << i << "] " << name << "(" << location << ")" << std::endl;
|
std::cout.flush() ;
|
||||||
accounts.push_back(id);
|
|
||||||
i++;
|
selected_account_number = accounts.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::cout << std::endl << "Selected account: " << accounts[selected_account_number].name << " (" << accounts[selected_account_number].location << ") SSL id: " << accounts[selected_account_number].ssl_id << std::endl;
|
||||||
|
}
|
||||||
|
// now ask for passphrase
|
||||||
|
|
||||||
|
std::string prompt = "Enter the password for key " + key_name + " : " ;
|
||||||
|
std::cout << prompt ;
|
||||||
|
std::cout.flush();
|
||||||
|
std::string passwd = readStringFromKeyboard(true);
|
||||||
|
|
||||||
|
// now we have passwd and account number, so send it to the core.
|
||||||
|
|
||||||
|
std::string acc_ssl_id = accounts[selected_account_number].ssl_id.toStdString();
|
||||||
|
|
||||||
|
sendPassword(passwd) ;
|
||||||
|
sendSelectedAccount(acc_ssl_id) ;
|
||||||
}
|
}
|
||||||
|
else if(ask_for_password)
|
||||||
|
{
|
||||||
|
std::string prompt = "Enter the password for key " + key_name + " : " ;
|
||||||
|
std::cout << prompt ;
|
||||||
|
std::cout.flush();
|
||||||
|
std::string passwd = readStringFromKeyboard(true);
|
||||||
|
|
||||||
if(!ask_for_password && runstate == "waiting_account_select"
|
// now we have passwd and account number, so send it to the core.
|
||||||
&& last_char >= '0' && last_char <= '9'
|
|
||||||
&& static_cast<uint32_t>(last_char-'0') < accounts.size())
|
|
||||||
{
|
|
||||||
std::string acc = accounts[last_char-'0'];
|
|
||||||
JsonStream reqs;
|
|
||||||
JsonStream resps;
|
|
||||||
Request req(reqs);
|
|
||||||
std::stringstream ss;
|
|
||||||
Response resp(resps, ss);
|
|
||||||
|
|
||||||
req.mPath.push("login");
|
sendPassword(passwd) ;
|
||||||
req.mPath.push("control");
|
}
|
||||||
reqs << makeKeyValueReference("id", acc);
|
|
||||||
reqs.switchToDeserialisation();
|
|
||||||
|
|
||||||
ApiServer::RequestId id = mApiServer->handleRequest(req, resp);
|
|
||||||
waitForResponse(id);
|
|
||||||
|
|
||||||
inbuf.clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
if(edge && ask_for_password)
|
|
||||||
{
|
|
||||||
std::cout << "Enter the password for key " << key_name << std::endl;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(ask_for_password && enter_was_pressed && !inbuf.empty())
|
|
||||||
{
|
|
||||||
std::cout << "TerminalApiClient: got a password" << std::endl;
|
|
||||||
JsonStream reqs;
|
|
||||||
JsonStream resps;
|
|
||||||
Request req(reqs);
|
|
||||||
std::stringstream ss;
|
|
||||||
Response resp(resps, ss);
|
|
||||||
|
|
||||||
req.mPath.push("password");
|
|
||||||
req.mPath.push("control");
|
|
||||||
reqs << makeKeyValueReference("password", inbuf);
|
|
||||||
reqs.switchToDeserialisation();
|
|
||||||
|
|
||||||
ApiServer::RequestId id = mApiServer->handleRequest(req, resp);
|
|
||||||
waitForResponse(id);
|
|
||||||
|
|
||||||
inbuf.clear();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void TerminalApiClient::waitForResponse(ApiServer::RequestId id)
|
void TerminalApiClient::waitForResponse(ApiServer::RequestId id) const
|
||||||
{
|
{
|
||||||
while(!mApiServer->isRequestDone(id))
|
while(!mApiServer->isRequestDone(id))
|
||||||
usleep(20*1000);
|
usleep(20*1000);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool TerminalApiClient::isTokenValid(StateToken runstate_state_token)
|
void TerminalApiClient::sendPassword(const std::string& passwd) const
|
||||||
|
{
|
||||||
|
JsonStream reqs;
|
||||||
|
JsonStream resps;
|
||||||
|
Request req(reqs);
|
||||||
|
std::stringstream ss;
|
||||||
|
Response resp(resps, ss);
|
||||||
|
|
||||||
|
req.mPath.push("password");
|
||||||
|
req.mPath.push("control");
|
||||||
|
|
||||||
|
std::string pass(passwd) ;
|
||||||
|
|
||||||
|
reqs << makeKeyValueReference("password", pass);
|
||||||
|
reqs.switchToDeserialisation();
|
||||||
|
|
||||||
|
ApiServer::RequestId id = mApiServer->handleRequest(req, resp);
|
||||||
|
waitForResponse(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
void TerminalApiClient::sendSelectedAccount(const std::string& ssl_id) const
|
||||||
|
{
|
||||||
|
JsonStream reqs;
|
||||||
|
JsonStream resps;
|
||||||
|
Request req(reqs);
|
||||||
|
std::stringstream ss;
|
||||||
|
Response resp(resps, ss);
|
||||||
|
|
||||||
|
std::string acc_ssl_id(ssl_id) ;
|
||||||
|
req.mPath.push("login");
|
||||||
|
req.mPath.push("control");
|
||||||
|
reqs << makeKeyValueReference("id", acc_ssl_id);
|
||||||
|
reqs.switchToDeserialisation();
|
||||||
|
|
||||||
|
ApiServer::RequestId id = mApiServer->handleRequest(req, resp);
|
||||||
|
waitForResponse(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
void TerminalApiClient::readAvailableAccounts(std::vector<AccountInfo>& accounts) const
|
||||||
|
{
|
||||||
|
JsonStream reqs;
|
||||||
|
JsonStream resps;
|
||||||
|
Request req(reqs);
|
||||||
|
std::stringstream ss;
|
||||||
|
Response resp(resps, ss);
|
||||||
|
|
||||||
|
req.mPath.push("locations");
|
||||||
|
req.mPath.push("control");
|
||||||
|
reqs.switchToDeserialisation();
|
||||||
|
|
||||||
|
ApiServer::RequestId id = mApiServer->handleRequest(req, resp);
|
||||||
|
waitForResponse(id);
|
||||||
|
|
||||||
|
resps.switchToDeserialisation();
|
||||||
|
|
||||||
|
if(!resps.hasMore())
|
||||||
|
std::cout << "Error: No Accounts. Use the Qt-GUI or the webinterface to create an account." << std::endl;
|
||||||
|
|
||||||
|
int i = 0;
|
||||||
|
accounts.clear();
|
||||||
|
|
||||||
|
while(resps.hasMore())
|
||||||
|
{
|
||||||
|
std::string id;
|
||||||
|
std::string name;
|
||||||
|
std::string location;
|
||||||
|
|
||||||
|
resps.getStreamToMember()
|
||||||
|
<< makeKeyValueReference("id", id)
|
||||||
|
<< makeKeyValueReference("name", name)
|
||||||
|
<< makeKeyValueReference("location", location);
|
||||||
|
|
||||||
|
AccountInfo info ;
|
||||||
|
info.location = location ;
|
||||||
|
info.name = name ;
|
||||||
|
info.ssl_id = RsPeerId(id) ;
|
||||||
|
|
||||||
|
accounts.push_back(info);
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool TerminalApiClient::isTokenValid(StateToken runstate_state_token) const
|
||||||
{
|
{
|
||||||
JsonStream reqs;
|
JsonStream reqs;
|
||||||
JsonStream resps;
|
JsonStream resps;
|
||||||
@ -321,4 +391,50 @@ bool TerminalApiClient::isTokenValid(StateToken runstate_state_token)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void TerminalApiClient::readPasswordState(StateToken& password_state_token,bool& ask_for_password,std::string& key_name,bool& prev_is_bad) const
|
||||||
|
{
|
||||||
|
JsonStream reqs;
|
||||||
|
JsonStream resps;
|
||||||
|
Request req(reqs);
|
||||||
|
std::stringstream ss;
|
||||||
|
Response resp(resps, ss);
|
||||||
|
|
||||||
|
req.mPath.push("password");
|
||||||
|
req.mPath.push("control");
|
||||||
|
reqs.switchToDeserialisation();
|
||||||
|
|
||||||
|
ApiServer::RequestId id = mApiServer->handleRequest(req, resp);
|
||||||
|
waitForResponse(id);
|
||||||
|
|
||||||
|
resps.switchToDeserialisation();
|
||||||
|
resps << makeKeyValueReference("want_password", ask_for_password);
|
||||||
|
resps << makeKeyValueReference("key_name", key_name);
|
||||||
|
resps << makeKeyValueReference("prev_is_bad", prev_is_bad);
|
||||||
|
password_state_token = resp.mStateToken;
|
||||||
|
|
||||||
|
std::cerr << "****** Passwd state changed: want_passwd=" << ask_for_password << " key_name=" << key_name << " prev_is_bad=" << prev_is_bad << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
void TerminalApiClient::readRunState(StateToken& runstate_state_token,std::string& runstate) const
|
||||||
|
{
|
||||||
|
JsonStream reqs;
|
||||||
|
JsonStream resps;
|
||||||
|
Request req(reqs);
|
||||||
|
std::stringstream ss;
|
||||||
|
Response resp(resps, ss);
|
||||||
|
|
||||||
|
req.mPath.push("runstate");
|
||||||
|
req.mPath.push("control");
|
||||||
|
reqs.switchToDeserialisation();
|
||||||
|
|
||||||
|
ApiServer::RequestId id = mApiServer->handleRequest(req, resp);
|
||||||
|
waitForResponse(id);
|
||||||
|
|
||||||
|
resps.switchToDeserialisation();
|
||||||
|
resps << makeKeyValueReference("runstate", runstate);
|
||||||
|
runstate_state_token = resp.mStateToken;
|
||||||
|
|
||||||
|
std::cerr << "****** Run State changed to \"" << runstate << "\"" << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace resource_api
|
} // namespace resource_api
|
||||||
|
@ -8,7 +8,7 @@ namespace resource_api {
|
|||||||
// - account selection
|
// - account selection
|
||||||
// - login
|
// - login
|
||||||
// - shutdown
|
// - shutdown
|
||||||
class TerminalApiClient: private RsTickingThread{
|
class TerminalApiClient: public RsTickingThread{
|
||||||
public:
|
public:
|
||||||
// zero setup: create an instance of this class and destroy it when not needed anymore
|
// zero setup: create an instance of this class and destroy it when not needed anymore
|
||||||
// no need to call start or stop or something
|
// no need to call start or stop or something
|
||||||
@ -19,9 +19,26 @@ protected:
|
|||||||
// from RsThread
|
// from RsThread
|
||||||
virtual void data_tick(); /* called once the thread is started. Should be overloaded by subclasses. */
|
virtual void data_tick(); /* called once the thread is started. Should be overloaded by subclasses. */
|
||||||
private:
|
private:
|
||||||
void waitForResponse(ApiServer::RequestId id);
|
struct AccountInfo
|
||||||
bool isTokenValid(StateToken st);
|
{
|
||||||
|
std::string name ;
|
||||||
|
std::string location ;
|
||||||
|
RsPeerId ssl_id ;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
void waitForResponse(ApiServer::RequestId id) const;
|
||||||
|
bool isTokenValid(StateToken st) const;
|
||||||
ApiServer* mApiServer;
|
ApiServer* mApiServer;
|
||||||
|
|
||||||
|
// Methods to talk to the ApiServer
|
||||||
|
|
||||||
|
void sendPassword(const std::string& passwd) const;
|
||||||
|
void sendSelectedAccount(const std::string& ssl_id) const;
|
||||||
|
void readAvailableAccounts(std::vector<AccountInfo>& accounts) const;
|
||||||
|
void getRunningState() const ;
|
||||||
|
void readPasswordState(StateToken& password_state_token,bool& ask_for_password,std::string& key_name,bool& prev_is_bad) const;
|
||||||
|
void readRunState(StateToken& runstate_state_token, std::string& runstate) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace resource_api
|
} // namespace resource_api
|
||||||
|
@ -100,9 +100,18 @@ int main(int argc, char **argv)
|
|||||||
}
|
}
|
||||||
|
|
||||||
resource_api::TerminalApiClient tac(&api);
|
resource_api::TerminalApiClient tac(&api);
|
||||||
|
tac.start();
|
||||||
|
bool already = false ;
|
||||||
|
|
||||||
while(ctrl_mod.processShouldExit() == false)
|
while(ctrl_mod.processShouldExit() == false)
|
||||||
{
|
{
|
||||||
usleep(20*1000);
|
usleep(1000*1000);
|
||||||
|
|
||||||
|
if(!tac.isRunning() && !already)
|
||||||
|
{
|
||||||
|
std::cerr << "Terminal API client terminated." << std::endl;
|
||||||
|
already = true ;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(httpd)
|
if(httpd)
|
||||||
|
Loading…
Reference in New Issue
Block a user