mirror of
https://github.com/RetroShare/RetroShare.git
synced 2025-05-17 13:30:36 -04:00
Added first version of RPC system for external control of retroshare-nogui.
The protocol message format is as follows: [HEADER: 16 bytes: 4 x Network Order uint32_t][ VARIABLE LENGTH BODY ] [ MAGIC_CODE ] [ MSG_ID ] [ REQ_ID ] [ BODY_SIZE ] [ ........ BODY ......... ] MagicCode = 0x137f0001 ... this will be incremented for new versions of the protocol. MsgID = Corresponds to the format of the Body. ReqID = Generated by Requester, Returned in Response, make sure its unique. (undefined behaviour for duplicates) BodySize = Byte Length of Body. The Body will consist of a protobuf encoded message. For the moment, the RPC server just ECHOs the request back to the sender - for testing purposes. Usage: * Create SSH connection to retroshare-nogui. * Create Request Message(s), and send over SSH channel - You can send as meny requests as you want. * They will processed, and responses sent back (potentially in an arbitary order). Specific Changes here: * Modified rssshd to support arbitary recv/send applications. (interface is RpcComms). * Added rpc directory, with server, setup and echo service. * Modified Menu System to use the new interface to rssshd * Wrote new matching interface for Terminal Usage. - NOTE: Strange BUG in Terminal version.... causes stderr to disappear. TODO. * Added -C commandline option to switch on RPC system. This is the first version - so I expect there will be bugs. Please report for a prompt fix! git-svn-id: http://svn.code.sf.net/p/retroshare/code/branches/v0.5-gxs-b1@5444 b45a01b8-16f6-495d-af2f-9b41ad6348cc
This commit is contained in:
parent
c17460d1b1
commit
bb10b6b400
20 changed files with 1612 additions and 72 deletions
|
@ -26,6 +26,8 @@ clients must be made or how a client should react.
|
|||
|
||||
#define RSSSHD_STATE_NULL 0
|
||||
#define RSSSHD_STATE_INIT_OK 1
|
||||
#define RSSSHD_STATE_CONNECTED 2
|
||||
#define RSSSHD_STATE_ERROR 3
|
||||
|
||||
RsSshd *rsSshd = NULL; // External Reference Variable.
|
||||
|
||||
|
@ -54,8 +56,9 @@ RsSshd::RsSshd(std::string portStr)
|
|||
|
||||
mState = RSSSHD_STATE_NULL;
|
||||
mBindState = 0;
|
||||
mTermServer = NULL;
|
||||
mRpcSystem = NULL;
|
||||
|
||||
setSleepPeriods(0.01, 0.1);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -104,6 +107,7 @@ void RsSshd::run()
|
|||
std::cerr << "RsSshd::run() setup mSession => interactive";
|
||||
std::cerr << std::endl;
|
||||
|
||||
mState = RSSSHD_STATE_CONNECTED;
|
||||
interactive();
|
||||
}
|
||||
else
|
||||
|
@ -195,7 +199,7 @@ int RsSshd::interactive()
|
|||
std::cerr << "RsSshd::interactive()";
|
||||
std::cerr << std::endl;
|
||||
|
||||
doTermServer();
|
||||
doRpcSystem();
|
||||
//doEcho();
|
||||
return 1;
|
||||
}
|
||||
|
@ -318,7 +322,36 @@ int RsSshd::setupShell()
|
|||
return 1;
|
||||
}
|
||||
|
||||
// CLEANUP
|
||||
int RsSshd::cleanupSession()
|
||||
{
|
||||
std::cerr << "RsSshd::cleanupSession()";
|
||||
std::cerr << std::endl;
|
||||
|
||||
ssh_disconnect(mSession);
|
||||
ssh_free(mSession);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
int RsSshd::cleanupAll()
|
||||
{
|
||||
std::cerr << "RsSshd::cleanupAll()";
|
||||
std::cerr << std::endl;
|
||||
|
||||
cleanupSession();
|
||||
if (mBindState)
|
||||
{
|
||||
ssh_bind_free(mBind);
|
||||
mBindState = 0;
|
||||
}
|
||||
ssh_finalize();
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Various Operating Modes.
|
||||
int RsSshd::doEcho()
|
||||
{
|
||||
std::cerr << "RsSshd::doEcho()";
|
||||
|
@ -354,13 +387,14 @@ int RsSshd::doEcho()
|
|||
}
|
||||
|
||||
|
||||
int RsSshd::setTermServer(RsTermServer *s)
|
||||
int RsSshd::setRpcSystem(RpcSystem *s)
|
||||
{
|
||||
mTermServer = s;
|
||||
mRpcSystem = s;
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
#if 0
|
||||
|
||||
int RsSshd::doTermServer()
|
||||
{
|
||||
|
@ -422,33 +456,161 @@ int RsSshd::doTermServer()
|
|||
return 1;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
int RsSshd::cleanupSession()
|
||||
|
||||
int RsSshd::doRpcSystem()
|
||||
{
|
||||
std::cerr << "RsSshd::cleanupSession()";
|
||||
std::cerr << "RsSshd::doRpcSystem()";
|
||||
std::cerr << std::endl;
|
||||
|
||||
ssh_disconnect(mSession);
|
||||
ssh_free(mSession);
|
||||
return 1;
|
||||
if (!mRpcSystem)
|
||||
{
|
||||
std::cerr << "RsSshd::doRpcSystem() ERROR Not Set";
|
||||
std::cerr << std::endl;
|
||||
return 0;
|
||||
}
|
||||
|
||||
mRpcSystem->reset(); // clear everything for new user.
|
||||
|
||||
bool okay = true;
|
||||
while(okay)
|
||||
{
|
||||
int rt = mRpcSystem->tick();
|
||||
if (rt)
|
||||
{
|
||||
// Working - so small sleep,
|
||||
usleep(mBusyUSleep);
|
||||
}
|
||||
else
|
||||
{
|
||||
// No work cycle, longer break.
|
||||
usleep(mIdleUSleep);
|
||||
}
|
||||
|
||||
if (rt < 0)
|
||||
{
|
||||
okay = false; // exit.
|
||||
}
|
||||
|
||||
if (!isOkay())
|
||||
{
|
||||
okay = false;
|
||||
}
|
||||
}
|
||||
|
||||
std::cerr << "RsSshd::doRpcSystem() Finished";
|
||||
std::cerr << std::endl;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
// RpcComms Interface....
|
||||
int RsSshd::isOkay()
|
||||
{
|
||||
return (mState == RSSSHD_STATE_CONNECTED);
|
||||
}
|
||||
|
||||
|
||||
int RsSshd::cleanupAll()
|
||||
int RsSshd::error(std::string msg)
|
||||
{
|
||||
std::cerr << "RsSshd::cleanupAll()";
|
||||
std::cerr << "RsSshd::error(" << msg << ")";
|
||||
std::cerr << std::endl;
|
||||
|
||||
cleanupSession();
|
||||
if (mBindState)
|
||||
{
|
||||
ssh_bind_free(mBind);
|
||||
mBindState = 0;
|
||||
}
|
||||
ssh_finalize();
|
||||
return 1;
|
||||
mState = RSSSHD_STATE_ERROR;
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
int RsSshd::recv_ready()
|
||||
{
|
||||
int bytes = ssh_channel_poll(mChannel, 0);
|
||||
return bytes;
|
||||
}
|
||||
|
||||
|
||||
int RsSshd::recv(uint8_t *buffer, int bytes)
|
||||
{
|
||||
#if LIBSSH_VERSION_INT >= SSH_VERSION_INT(0,5,0)
|
||||
int size = ssh_channel_read_nonblocking(mChannel, buffer, bytes, 0);
|
||||
#else
|
||||
int size = channel_read_nonblocking(mChannel, buffer, bytes, 0);
|
||||
#endif
|
||||
return size;
|
||||
}
|
||||
|
||||
|
||||
int RsSshd::recv(std::string &buffer, int bytes)
|
||||
{
|
||||
char input[bytes];
|
||||
#if LIBSSH_VERSION_INT >= SSH_VERSION_INT(0,5,0)
|
||||
int size = ssh_channel_read_nonblocking(mChannel, input, bytes, 0);
|
||||
#else
|
||||
int size = channel_read_nonblocking(mChannel, input, bytes, 0);
|
||||
#endif
|
||||
for(int i = 0; i < size; i++)
|
||||
{
|
||||
buffer += input[i];
|
||||
}
|
||||
return size;
|
||||
}
|
||||
|
||||
|
||||
int RsSshd::recv_blocking(uint8_t *buffer, int bytes)
|
||||
{
|
||||
#if LIBSSH_VERSION_INT >= SSH_VERSION_INT(0,5,0)
|
||||
int size = ssh_channel_read(mChannel, buffer, bytes, 0);
|
||||
#else
|
||||
int size = channel_read(mChannel, buffer, bytes, 0);
|
||||
#endif
|
||||
return size;
|
||||
}
|
||||
|
||||
|
||||
int RsSshd::recv_blocking(std::string &buffer, int bytes)
|
||||
{
|
||||
char input[bytes];
|
||||
#if LIBSSH_VERSION_INT >= SSH_VERSION_INT(0,5,0)
|
||||
int size = ssh_channel_read(mChannel, input, bytes, 0);
|
||||
#else
|
||||
int size = channel_read(mChannel, input, bytes, 0);
|
||||
#endif
|
||||
for(int i = 0; i < size; i++)
|
||||
{
|
||||
buffer += input[i];
|
||||
}
|
||||
return size;
|
||||
}
|
||||
|
||||
int RsSshd::send(uint8_t *buffer, int bytes)
|
||||
{
|
||||
#if LIBSSH_VERSION_INT >= SSH_VERSION_INT(0,5,0)
|
||||
ssh_channel_write(mChannel, buffer, bytes);
|
||||
#else
|
||||
channel_write(mChannel, buffer, bytes);
|
||||
#endif
|
||||
return 1;
|
||||
}
|
||||
|
||||
int RsSshd::send(const std::string &buffer)
|
||||
{
|
||||
#if LIBSSH_VERSION_INT >= SSH_VERSION_INT(0,5,0)
|
||||
ssh_channel_write(mChannel, buffer.c_str(), buffer.size());
|
||||
#else
|
||||
channel_write(mChannel, buffer.c_str(), buffer.size());
|
||||
#endif
|
||||
return 1;
|
||||
}
|
||||
|
||||
int RsSshd::setSleepPeriods(float busy, float idle)
|
||||
{
|
||||
mBusyUSleep = busy * 1000000;
|
||||
mIdleUSleep = idle * 1000000;
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/***********************************************************************************/
|
||||
/* PASSWORDS */
|
||||
/***********************************************************************************/
|
||||
|
@ -682,7 +844,7 @@ int CheckPasswordHash(std::string pwdHashRadix64, std::string password)
|
|||
char *buf = NULL;
|
||||
size_t len = 1024;
|
||||
Radix64::decode(pwdHashRadix64, buf, len);
|
||||
for(int i = 0; (i < len) && (i < 1024); i++)
|
||||
for(unsigned int i = 0; (i < len) && (i < 1024); i++)
|
||||
{
|
||||
output[i] = buf[i];
|
||||
}
|
||||
|
|
|
@ -34,7 +34,7 @@ clients must be made or how a client should react.
|
|||
#include <string>
|
||||
#include <map>
|
||||
|
||||
#include "rstermserver.h"
|
||||
#include "rpcsystem.h"
|
||||
|
||||
#ifndef KEYS_FOLDER
|
||||
#ifdef _WIN32
|
||||
|
@ -66,24 +66,36 @@ int CheckPasswordHash(std::string pwdHashRadix64, std::string password);
|
|||
int GeneratePasswordHash(std::string saltBin, std::string password, std::string &pwdHashRadix64);
|
||||
int GenerateSalt(std::string &saltBin);
|
||||
|
||||
class RsSshd: public RsThread
|
||||
class RsSshd: public RsThread, public RpcComms
|
||||
{
|
||||
public:
|
||||
|
||||
int adduserpwdhash(std::string username, std::string hash);
|
||||
#ifdef ALLOW_CLEARPWDS
|
||||
int adduser(std::string username, std::string password);
|
||||
#endif // ALLOW_CLEARPWDS
|
||||
|
||||
|
||||
|
||||
virtual void run(); /* overloaded from RsThread => called once the thread is started */
|
||||
|
||||
// NB: This must be called EARLY before all the threads are launched.
|
||||
static RsSshd *InitRsSshd(std::string portstr, std::string rsakeyfile);
|
||||
|
||||
// Terminal Handling!
|
||||
int setTermServer(RsTermServer *s);
|
||||
|
||||
// Interface.
|
||||
int setRpcSystem(RpcSystem *s);
|
||||
int adduserpwdhash(std::string username, std::string hash);
|
||||
|
||||
// RsThreads Interface.
|
||||
virtual void run(); /* called once the thread is started */
|
||||
|
||||
// RsComms Interface.
|
||||
virtual int isOkay();
|
||||
virtual int error(std::string msg);
|
||||
|
||||
virtual int recv_ready();
|
||||
|
||||
virtual int recv(uint8_t *buffer, int bytes);
|
||||
virtual int recv(std::string &buffer, int bytes);
|
||||
virtual int recv_blocking(uint8_t *buffer, int bytes);
|
||||
virtual int recv_blocking(std::string &buffer, int bytes);
|
||||
|
||||
virtual int send(uint8_t *buffer, int bytes);
|
||||
virtual int send(const std::string &buffer);
|
||||
|
||||
virtual int setSleepPeriods(float busy, float idle);
|
||||
|
||||
private:
|
||||
RsSshd(std::string portStr); /* private constructor => so can only create with */
|
||||
|
@ -102,7 +114,8 @@ int setupShell();
|
|||
int doEcho();
|
||||
|
||||
// Terminal Handling!
|
||||
int doTermServer();
|
||||
//int doTermServer();
|
||||
int doRpcSystem();
|
||||
|
||||
int cleanupSession();
|
||||
int cleanupAll();
|
||||
|
@ -117,6 +130,9 @@ int auth_password_basic(char *name, char *pwd);
|
|||
// DATA.
|
||||
|
||||
RsMutex mSshMtx;
|
||||
|
||||
uint32_t mBusyUSleep;
|
||||
uint32_t mIdleUSleep;
|
||||
|
||||
uint32_t mState;
|
||||
uint32_t mBindState;
|
||||
|
@ -126,7 +142,8 @@ int auth_password_basic(char *name, char *pwd);
|
|||
ssh_bind mBind;
|
||||
ssh_channel mChannel;
|
||||
|
||||
RsTermServer *mTermServer;
|
||||
RpcSystem *mRpcSystem;
|
||||
|
||||
#ifdef ALLOW_CLEARPWDS
|
||||
std::map<std::string, std::string> mPasswords;
|
||||
#endif // ALLOW_CLEARPWDS
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue