Merge pull request #836 from sehraf/pr-add-i2p-bob-v2.1

Add I2P BOB support to libretroashare and RetroShare GUI
This commit is contained in:
csoler 2017-05-25 22:20:18 +02:00 committed by GitHub
commit 873131f487
31 changed files with 4150 additions and 959 deletions

View File

@ -443,8 +443,10 @@ void RsControlModule::handleCreateLocation(Request &req, Response &resp)
}
}
if(hidden_port)
RsInit::SetHiddenLocation(hidden_address, hidden_port);
if(hidden_port) {
/// TODO add bob to webui
RsInit::SetHiddenLocation(hidden_address, hidden_port, false);
}
std::string ssl_password = RSRandom::random_alphaNumericString(RsInit::getSslPwdLen()) ;

View File

@ -140,7 +140,6 @@ PUBLIC_HEADERS = retroshare/rsdisc.h \
retroshare/rsversion.h \
retroshare/rsservicecontrol.h \
HEADERS += plugins/pluginmanager.h \
plugins/dlfcn_win32.h \
rsitems/rspluginitems.h \
@ -429,6 +428,7 @@ HEADERS += pqi/authssl.h \
pqi/pqissl.h \
pqi/pqissllistener.h \
pqi/pqisslpersongrp.h \
pqi/pqissli2pbob.h \
pqi/pqissludp.h \
pqi/pqisslproxy.h \
pqi/pqistore.h \
@ -493,7 +493,9 @@ HEADERS += rsitems/rsitem.h \
rsitems/rsgxsupdateitems.h \
rsitems/rsserviceinfoitems.h \
HEADERS += services/p3msgservice.h \
HEADERS += services/autoproxy/p3i2pbob.h \
services/autoproxy/rsautoproxymonitor.h \
services/p3msgservice.h \
services/p3service.h \
services/p3statusservice.h \
services/p3banlist.h \
@ -518,6 +520,9 @@ HEADERS += util/folderiterator.h \
util/rsnet.h \
util/extaddrfinder.h \
util/dnsresolver.h \
util/radix32.h \
util/radix64.h \
util/rsinitedptr.h \
util/rsprint.h \
util/rsstring.h \
util/rsstd.h \
@ -525,7 +530,6 @@ HEADERS += util/folderiterator.h \
util/rsversioninfo.h \
util/rswin.h \
util/rsrandom.h \
util/radix64.h \
util/pugiconfig.h \
util/rsmemcache.h \
util/rstickevent.h \
@ -580,6 +584,7 @@ SOURCES += pqi/authgpg.cc \
pqi/pqissl.cc \
pqi/pqissllistener.cc \
pqi/pqisslpersongrp.cc \
pqi/pqissli2pbob.cpp \
pqi/pqissludp.cc \
pqi/pqisslproxy.cc \
pqi/pqistore.cc \
@ -638,7 +643,9 @@ SOURCES += serialiser/rsbaseserial.cc \
rsitems/rsgxsupdateitems.cc \
rsitems/rsserviceinfoitems.cc \
SOURCES += services/p3msgservice.cc \
SOURCES += services/autoproxy/rsautoproxymonitor.cc \
services/autoproxy/p3i2pbob.cc \
services/p3msgservice.cc \
services/p3service.cc \
services/p3statusservice.cc \
services/p3banlist.cc \

View File

@ -1586,20 +1586,26 @@ bool AuthSSLimpl::FailedCertificate(X509 *x509, const RsPgpId& gpgid,
switch(auth_diagnostic)
{
case RS_SSL_HANDSHAKE_DIAGNOSTIC_CERTIFICATE_MISSING: RsServer::notify()->AddFeedItem(RS_FEED_ITEM_SEC_MISSING_CERTIFICATE, gpgid.toStdString(), sslid.toStdString(), sslcn, ip_address);
break ;
case RS_SSL_HANDSHAKE_DIAGNOSTIC_CERTIFICATE_NOT_VALID: RsServer::notify()->AddFeedItem(RS_FEED_ITEM_SEC_BAD_CERTIFICATE, gpgid.toStdString(), sslid.toStdString(), sslcn, ip_address);
break ;
case RS_SSL_HANDSHAKE_DIAGNOSTIC_ISSUER_UNKNOWN: RsServer::notify()->AddFeedItem(RS_FEED_ITEM_SEC_UNKNOWN_IN , gpgid.toStdString(), sslid.toStdString(), sslcn, ip_address);
break ;
case RS_SSL_HANDSHAKE_DIAGNOSTIC_MALLOC_ERROR: RsServer::notify()->AddFeedItem(RS_FEED_ITEM_SEC_INTERNAL_ERROR , gpgid.toStdString(), sslid.toStdString(), sslcn, ip_address);
break ;
case RS_SSL_HANDSHAKE_DIAGNOSTIC_WRONG_SIGNATURE: RsServer::notify()->AddFeedItem(RS_FEED_ITEM_SEC_WRONG_SIGNATURE, gpgid.toStdString(), sslid.toStdString(), sslcn, ip_address);
break ;
case RS_SSL_HANDSHAKE_DIAGNOSTIC_OK:
case RS_SSL_HANDSHAKE_DIAGNOSTIC_UNKNOWN:
default:
RsServer::notify()->AddFeedItem(RS_FEED_ITEM_SEC_CONNECT_ATTEMPT, gpgid.toStdString(), sslid.toStdString(), sslcn, ip_address);
case RS_SSL_HANDSHAKE_DIAGNOSTIC_CERTIFICATE_MISSING:
RsServer::notify()->notifyConnectionWithoutCert();
RsServer::notify()->AddFeedItem(RS_FEED_ITEM_SEC_MISSING_CERTIFICATE, gpgid.toStdString(), sslid.toStdString(), sslcn, ip_address);
break ;
case RS_SSL_HANDSHAKE_DIAGNOSTIC_CERTIFICATE_NOT_VALID:
RsServer::notify()->AddFeedItem(RS_FEED_ITEM_SEC_BAD_CERTIFICATE, gpgid.toStdString(), sslid.toStdString(), sslcn, ip_address);
break ;
case RS_SSL_HANDSHAKE_DIAGNOSTIC_ISSUER_UNKNOWN:
RsServer::notify()->AddFeedItem(RS_FEED_ITEM_SEC_UNKNOWN_IN , gpgid.toStdString(), sslid.toStdString(), sslcn, ip_address);
break ;
case RS_SSL_HANDSHAKE_DIAGNOSTIC_MALLOC_ERROR:
RsServer::notify()->AddFeedItem(RS_FEED_ITEM_SEC_INTERNAL_ERROR , gpgid.toStdString(), sslid.toStdString(), sslcn, ip_address);
break ;
case RS_SSL_HANDSHAKE_DIAGNOSTIC_WRONG_SIGNATURE:
RsServer::notify()->AddFeedItem(RS_FEED_ITEM_SEC_WRONG_SIGNATURE, gpgid.toStdString(), sslid.toStdString(), sslcn, ip_address);
break ;
case RS_SSL_HANDSHAKE_DIAGNOSTIC_OK:
case RS_SSL_HANDSHAKE_DIAGNOSTIC_UNKNOWN:
default:
RsServer::notify()->AddFeedItem(RS_FEED_ITEM_SEC_CONNECT_ATTEMPT, gpgid.toStdString(), sslid.toStdString(), sslcn, ip_address);
}
#ifdef AUTHSSL_DEBUG

View File

@ -237,6 +237,7 @@ void p3Notify::notifyOwnStatusMessageChanged()
void p3Notify::notifyDiskFull (uint32_t location , uint32_t size_limit_in_MB ) { FOR_ALL_NOTIFY_CLIENTS (*it)->notifyDiskFull (location,size_limit_in_MB) ; }
void p3Notify::notifyPeerStatusChanged (const std::string& peer_id , uint32_t status ) { FOR_ALL_NOTIFY_CLIENTS (*it)->notifyPeerStatusChanged (peer_id,status) ; }
void p3Notify::notifyGxsChange (const RsGxsChanges& changes) {FOR_ALL_NOTIFY_CLIENTS (*it)->notifyGxsChange(changes) ;}
void p3Notify::notifyConnectionWithoutCert () { FOR_ALL_NOTIFY_CLIENTS (*it)->notifyConnectionWithoutCert(); }
void p3Notify::notifyPeerStatusChangedSummary () { FOR_ALL_NOTIFY_CLIENTS (*it)->notifyPeerStatusChangedSummary() ; }
void p3Notify::notifyDiscInfoChanged () { FOR_ALL_NOTIFY_CLIENTS (*it)->notifyDiscInfoChanged () ; }

View File

@ -112,6 +112,7 @@ class p3Notify: public RsNotify
void notifyDiskFull (uint32_t /* location */, uint32_t /* size limit in MB */) ;
void notifyPeerStatusChanged (const std::string& /* peer_id */, uint32_t /* status */) ;
void notifyGxsChange (const RsGxsChanges& /* changes */);
void notifyConnectionWithoutCert ();
void notifyPeerStatusChangedSummary () ;
void notifyDiscInfoChanged () ;

View File

@ -521,12 +521,14 @@ int pqiperson::connect(uint32_t type, const sockaddr_storage &raddr,
return 0;
}
pqiconnect *pqi = it->second;
#ifdef PERSON_DEBUG
std::cerr << "pqiperson::connect() resetting for new connection attempt" << std::endl;
#endif
/* set the parameters */
(it->second)->reset();
pqi->reset();
#ifdef PERSON_DEBUG
std::cerr << "pqiperson::connect() clearing rate cap" << std::endl;
@ -538,22 +540,22 @@ int pqiperson::connect(uint32_t type, const sockaddr_storage &raddr,
#endif
// These two are universal.
(it->second)->connect_parameter(NET_PARAM_CONNECT_DELAY, delay);
(it->second)->connect_parameter(NET_PARAM_CONNECT_TIMEOUT, timeout);
pqi->connect_parameter(NET_PARAM_CONNECT_DELAY, delay);
pqi->connect_parameter(NET_PARAM_CONNECT_TIMEOUT, timeout);
// these 5 are only used by UDP connections.
(it->second)->connect_parameter(NET_PARAM_CONNECT_PERIOD, period);
(it->second)->connect_parameter(NET_PARAM_CONNECT_FLAGS, flags);
(it->second)->connect_parameter(NET_PARAM_CONNECT_BANDWIDTH, bandwidth);
pqi->connect_parameter(NET_PARAM_CONNECT_PERIOD, period);
pqi->connect_parameter(NET_PARAM_CONNECT_FLAGS, flags);
pqi->connect_parameter(NET_PARAM_CONNECT_BANDWIDTH, bandwidth);
(it->second)->connect_additional_address(NET_PARAM_CONNECT_PROXY, proxyaddr);
(it->second)->connect_additional_address(NET_PARAM_CONNECT_SOURCE, srcaddr);
pqi->connect_additional_address(NET_PARAM_CONNECT_PROXY, proxyaddr);
pqi->connect_additional_address(NET_PARAM_CONNECT_SOURCE, srcaddr);
// These are used by Proxy/Hidden
(it->second)->connect_parameter(NET_PARAM_CONNECT_DOMAIN_ADDRESS, domain_addr);
(it->second)->connect_parameter(NET_PARAM_CONNECT_REMOTE_PORT, domain_port);
pqi->connect_parameter(NET_PARAM_CONNECT_DOMAIN_ADDRESS, domain_addr);
pqi->connect_parameter(NET_PARAM_CONNECT_REMOTE_PORT, domain_port);
(it->second)->connect(raddr);
pqi->connect(raddr);
// flag if we started a new connectionAttempt.
inConnectAttempt = true;

View File

@ -0,0 +1,31 @@
#include "pqissli2pbob.h"
bool pqissli2pbob::connect_parameter(uint32_t type, const std::string &value)
{
if (type == NET_PARAM_CONNECT_DOMAIN_ADDRESS)
{
RS_STACK_MUTEX(mSslMtx);
// a new line must be appended!
mI2pAddr = value + '\n';
return true;
}
return pqissl::connect_parameter(type, value);
}
int pqissli2pbob::Basic_Connection_Complete()
{
int ret;
if ((ret = pqissl::Basic_Connection_Complete()) != 1)
{
// basic connection not complete.
return ret;
}
// send addr. (new line is already appended)
ret = send(sockfd, mI2pAddr.c_str(), mI2pAddr.length(), 0);
if (ret != (int)mI2pAddr.length())
return -1;
return 1;
}

View File

@ -0,0 +1,31 @@
#ifndef PQISSLI2PBOB_H
#define PQISSLI2PBOB_H
#include "pqi/pqissl.h"
/*
* This class is a minimal varied version of pqissl to work with I2P BOB tunnels.
* The only difference is that the [.b32].i2p addresses must be sent first.
*
* Everything else is untouched.
*/
class pqissli2pbob : public pqissl
{
public:
pqissli2pbob(pqissllistener *l, PQInterface *parent, p3LinkMgr *lm)
: pqissl(l, parent, lm) {}
// NetInterface interface
public:
bool connect_parameter(uint32_t type, const std::string &value);
// pqissl interface
protected:
int Basic_Connection_Complete();
private:
std::string mI2pAddr;
};
#endif // PQISSLI2PBOB_H

View File

@ -24,6 +24,7 @@
*/
#include "serialiser/rsserializer.h"
#include "services/autoproxy/rsautoproxymonitor.h"
#include "util/rsdebug.h"
#include "pqi/pqisslpersongrp.h"
@ -49,6 +50,7 @@ static struct RsLog::logInfo pqipersongrpzoneInfo = {RsLog::Default, "pqipersong
#endif
#include "pqi/pqisslproxy.h"
#include "pqi/pqissli2pbob.h"
pqilistener * pqisslpersongrp::locked_createListener(const struct sockaddr_storage &laddr)
{
@ -76,29 +78,34 @@ pqiperson * pqisslpersongrp::locked_createPerson(const RsPeerId& id, pqilistener
std::cerr << std::endl;
#endif
pqisslproxy *pqis = new pqisslproxy((pqissllistener *) listener, pqip, mLinkMgr);
// Use pqicI2PBOB for I2P
pqiconnect *pqicSOCKSProxy, *pqicI2PBOB;
{
pqisslproxy *pqis = new pqisslproxy((pqissllistener *) listener, pqip, mLinkMgr);
RsSerialiser *rss = new RsSerialiser();
rss->addSerialType(new RsRawSerialiser());
pqicSOCKSProxy = new pqiconnect(pqip, rss, pqis);
}
if (rsAutoProxyMonitor::instance()->isEnabled(autoProxyType::I2PBOB))
{
pqissli2pbob *pqis = new pqissli2pbob((pqissllistener *) listener, pqip, mLinkMgr);
RsSerialiser *rss = new RsSerialiser();
rss->addSerialType(new RsRawSerialiser());
/* construct the serialiser ....
* Needs:
* * FileItem
* * FileData
* * ServiceGeneric
*/
pqicI2PBOB = new pqiconnect(pqip, rss, pqis);
} else {
pqicI2PBOB = pqicSOCKSProxy;
}
RsSerialiser *rss = new RsSerialiser();
rss->addSerialType(new RsRawSerialiser());
pqiconnect *pqisc = new pqiconnect(pqip, rss, pqis);
/* first select type based on peer */
uint32_t typePeer = mPeerMgr->getHiddenType(id);
switch (typePeer) {
case RS_HIDDEN_TYPE_TOR:
pqip -> addChildInterface(PQI_CONNECT_HIDDEN_TOR_TCP, pqisc);
pqip -> addChildInterface(PQI_CONNECT_HIDDEN_TOR_TCP, pqicSOCKSProxy);
break;
case RS_HIDDEN_TYPE_I2P:
pqip -> addChildInterface(PQI_CONNECT_HIDDEN_I2P_TCP, pqisc);
pqip -> addChildInterface(PQI_CONNECT_HIDDEN_I2P_TCP, pqicI2PBOB);
break;
default:
/* peer is not a hidden one but we are */
@ -106,7 +113,7 @@ pqiperson * pqisslpersongrp::locked_createPerson(const RsPeerId& id, pqilistener
uint32_t typeOwn = mPeerMgr->getHiddenType(AuthSSL::getAuthSSL()->OwnId());
switch (typeOwn) {
case RS_HIDDEN_TYPE_I2P:
pqip -> addChildInterface(PQI_CONNECT_HIDDEN_I2P_TCP, pqisc);
pqip -> addChildInterface(PQI_CONNECT_HIDDEN_I2P_TCP, pqicI2PBOB);
break;
default:
/* this case shouldn't happen! */
@ -117,7 +124,7 @@ pqiperson * pqisslpersongrp::locked_createPerson(const RsPeerId& id, pqilistener
std::cerr << " - hidden types: peer=" << typePeer << " own=" << typeOwn << std::endl;
std::cerr << " --> falling back to Tor" << std::endl;
case RS_HIDDEN_TYPE_TOR:
pqip -> addChildInterface(PQI_CONNECT_HIDDEN_TOR_TCP, pqisc);
pqip -> addChildInterface(PQI_CONNECT_HIDDEN_TOR_TCP, pqicSOCKSProxy);
break;
}
}

View File

@ -81,7 +81,7 @@ private:
uint32_t mProxyState;
std::string mDomainAddress;
uint16_t mRemotePort;
uint16_t mRemotePort;
};
#endif // MRK_PQI_SSL_PROXY_HEADER

View File

@ -78,7 +78,7 @@ class RsInit
/*!
* Setup Hidden Location;
*/
static bool SetHiddenLocation(const std::string& hiddenaddress, uint16_t port);
static void SetHiddenLocation(const std::string& hiddenaddress, uint16_t port, bool useBob);
static bool LoadPassword(const std::string& passwd) ;

View File

@ -228,6 +228,7 @@ class NotifyClient
virtual void notifyDiskFull (uint32_t /* location */, uint32_t /* size limit in MB */) {}
virtual void notifyPeerStatusChanged (const std::string& /* peer_id */, uint32_t /* status */) {}
virtual void notifyGxsChange (const RsGxsChanges& /* changes */) {}
virtual void notifyConnectionWithoutCert () {}
/* one or more peers has changed the states */
virtual void notifyPeerStatusChangedSummary () {}

View File

@ -45,6 +45,8 @@ const int p3facemsgzone = 11453;
// TO SHUTDOWN THREADS.
#ifdef RS_ENABLE_GXS
#include "services/autoproxy/rsautoproxymonitor.h"
#include "services/p3idservice.h"
#include "services/p3gxscircles.h"
#include "services/p3wiki.h"
@ -89,6 +91,8 @@ void RsServer::rsGlobalShutDown()
mNetMgr->shutdown(); /* Handles UPnP */
rsAutoProxyMonitor::instance()->stopAllRSShutdown();
fullstop() ;
// kill all registered service threads

View File

@ -46,6 +46,7 @@
class p3heartbeat;
class p3discovery2;
class p3I2pBob;
/* GXS Classes - just declare the classes.
so we don't have to totally recompile to switch */
@ -164,6 +165,7 @@ class RsServer: public RsControl, public RsTickingThread
p3ChatService *chatSrv;
p3StatusService *mStatusSrv;
p3GxsTunnelService *mGxsTunnels;
p3I2pBob *mI2pBob;
// This list contains all threaded services. It will be used to shut them down properly.

View File

@ -121,6 +121,8 @@ class RsInitConfig
std::string hiddenNodeAddress;
uint16_t hiddenNodePort;
bool hiddenNodeI2PBOB;
/* Logging */
bool haveLogFile;
bool outStderr;
@ -790,13 +792,13 @@ void RsInit::setAutoLogin(bool autoLogin){
}
/* Setup Hidden Location; */
bool RsInit::SetHiddenLocation(const std::string& hiddenaddress, uint16_t port)
void RsInit::SetHiddenLocation(const std::string& hiddenaddress, uint16_t port, bool useBob)
{
/* parse the bugger (todo) */
rsInitConfig->hiddenNodeSet = true;
rsInitConfig->hiddenNodeAddress = hiddenaddress;
rsInitConfig->hiddenNodePort = port;
return true;
rsInitConfig->hiddenNodeI2PBOB = useBob;
}
@ -851,6 +853,9 @@ RsGRouter *rsGRouter = NULL ;
#endif
#endif
#include "services/autoproxy/p3i2pbob.h"
#include "services/autoproxy/rsautoproxymonitor.h"
#include "services/p3gxsreputation.h"
#include "services/p3serviceinfo.h"
#include "services/p3heartbeat.h"
@ -1046,6 +1051,9 @@ int RsServer::StartupRetroShare()
mPeerMgr->setManagers(mLinkMgr, mNetMgr);
mNetMgr->setManagers(mPeerMgr, mLinkMgr);
rsAutoProxyMonitor *autoProxy = rsAutoProxyMonitor::instance();
mI2pBob = new p3I2pBob(mPeerMgr);
autoProxy->addProxy(autoProxyType::I2PBOB, mI2pBob);
//load all the SSL certs as friends
// std::list<std::string> sslIds;
@ -1260,12 +1268,6 @@ int RsServer::StartupRetroShare()
rsFiles = ftserver;
/* create Cache Services */
std::string config_dir = rsAccounts->PathAccountDirectory();
std::string localcachedir = config_dir + "/cache/local";
std::string remotecachedir = config_dir + "/cache/remote";
std::vector<std::string> plugins_directories ;
#ifdef __APPLE__
@ -1672,6 +1674,7 @@ int RsServer::StartupRetroShare()
//mConfigMgr->addConfiguration("photo.cfg", photo_ns);
//mConfigMgr->addConfiguration("wire.cfg", wire_ns);
#endif
mConfigMgr->addConfiguration("I2PBOB.cfg", mI2pBob);
mPluginsManager->addConfigurations(mConfigMgr) ;
@ -1717,12 +1720,46 @@ int RsServer::StartupRetroShare()
{
mPeerMgr->setOwnNetworkMode(RS_NET_MODE_EXT);
mPeerMgr->setOwnVisState(RS_VS_DISC_FULL, RS_VS_DHT_FULL);
}
if (rsInitConfig->hiddenNodeSet)
{
mPeerMgr->setupHiddenNode(rsInitConfig->hiddenNodeAddress, rsInitConfig->hiddenNodePort);
std::cout << "RsServer::StartupRetroShare setting up hidden locations" << std::endl;
if (rsInitConfig->hiddenNodeI2PBOB) {
std::cout << "RsServer::StartupRetroShare setting up BOB" << std::endl;
// we need a local port!
mNetMgr->checkNetAddress();
// add i2p proxy
// bob will use this address
sockaddr_storage i2pInstance;
sockaddr_storage_ipv4_aton(i2pInstance, rsInitConfig->hiddenNodeAddress.c_str());
mPeerMgr->setProxyServerAddress(RS_HIDDEN_TYPE_I2P, i2pInstance);
std::string addr; // will be set by auto proxy service
uint16_t port = rsInitConfig->hiddenNodePort; // unused by bob
bool r = autoProxy->initialSetup(autoProxyType::I2PBOB, addr, port);
if (r && !addr.empty()) {
mPeerMgr->setupHiddenNode(addr, port);
// now enable bob
bobSettings bs;
autoProxy->taskSync(autoProxyType::I2PBOB, autoProxyTask::getSettings, &bs);
bs.enableBob = true;
autoProxy->taskSync(autoProxyType::I2PBOB, autoProxyTask::setSettings, &bs);
} else {
std::cerr << "RsServer::StartupRetroShare failed to receive keys" << std::endl;
/// TODO add notify for failed bob setup
}
} else {
mPeerMgr->setupHiddenNode(rsInitConfig->hiddenNodeAddress, rsInitConfig->hiddenNodePort);
}
std::cout << "RsServer::StartupRetroShare hidden location set up" << std::endl;
}
else if (isHiddenNode)
{
@ -1731,15 +1768,27 @@ int RsServer::StartupRetroShare()
mNetMgr -> checkNetAddress();
if (rsInitConfig->hiddenNodeSet) {
// newly created location
// mNetMgr->checkNetAddress() will setup ports for us
// trigger updates for auto proxy services
std::vector<autoProxyType::autoProxyType_enum> types;
// i2p bob need to rebuild its command map
types.push_back(autoProxyType::I2PBOB);
rsAutoProxyMonitor::taskSync(types, autoProxyTask::reloadConfig);
}
/**************************************************************************/
/* startup (stuff dependent on Ids/peers is after this point) */
/**************************************************************************/
autoProxy->startAll();
pqih->init_listener();
mNetMgr->addNetListener(pqih); /* add listener so we can reset all sockets later */
/**************************************************************************/
/* load caches and secondary data */
/**************************************************************************/
@ -1766,8 +1815,10 @@ int RsServer::StartupRetroShare()
/* Start up Threads */
/**************************************************************************/
#ifdef RS_ENABLE_GXS
// auto proxy threads
startServiceThread(mI2pBob, "I2P-BOB");
#ifdef RS_ENABLE_GXS
// Must Set the GXS pointers before starting threads.
rsIdentity = mGxsIdService;
rsGxsCircles = mGxsCircles;

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,248 @@
#ifndef P3I2PBOB_H
#define P3I2PBOB_H
#include <map>
#include <queue>
#include <sys/types.h>
#include <sys/socket.h>
#include <time.h>
#include "services/autoproxy/rsautoproxymonitor.h"
#include "util/rsthreads.h"
#include "pqi/p3cfgmgr.h"
/*
* This class implements I2P BOB (BASIC OPEN BRIDGE) communication to allow RS
* to automatically remote control I2P to setup the needed tunnel.
* BOB is a simple text-based interface: https://geti2p.net/en/docs/api/bob
*
* Note 1:
* One tunnel is enough even for hidden locations since it can be used
* bidirectional. (In contrast to what RS I2P users had to set up manually.)
*
* Note 2:
* BOB tunnels are no SOCKS tunnel. Therefore pqissli2pbob implements a simplified
* proxy specially for BOB tunnels.
*
* Note 3:
* BOB needs a unique name as an ID for each tunnel.
* We use 'RetroShare-' + 8 base32 characters.
*
* Design:
* The service uses three state machines to manage its task:
* int stateMachineBOB();
* mBOBState
* int stateMachineController();
* mState
* mTask
*
* stateMachineBOB:
* This state machine manages the low level communication with BOB. It basically has a linked
* list (currently a implemented as a std::map) that contains a command and the next
* state.
* Each high level operation (start up / shut down / get keys) is represented by a
* chain of states. E.g. the chain to retrieve new keys:
* mCommands[bobState::setnickN] = {setnick, bobState::newkeysN};
* mCommands[bobState::newkeysN] = {newkeys, bobState::getkeys};
* mCommands[bobState::getkeys] = {getkeys, bobState::clear};
* mCommands[bobState::clear] = {clear, bobState::quit};
* mCommands[bobState::quit] = {quit, bobState::cleared};
*
* stateMachineController:
* This state machone manages the high level tasks.
* It is controlled by mState and mTask.
*
* mTast:
* Tracks the high level operation (like start up).
* It will keep its value even when a task is done to track
* the requested BOB state.
* When other operations are performed like a conection check
* the last task gets backed up and is later restored again
*
* mState:
* This state lives only for one operation an manages the communication
* with the BOB instance. This is basically connecting, starting BOB
* protocol and disconnecting
*
* How a task looks like:
* 1) RS sets task using the ticket system
* 2) stateMachineController connects to BOBs control port, sets mBobState to a lists head
* 3) stateMachineBOB processes command chain
* 4) stateMachineBOB is done and sets mBobState to cleared signaling that the connection
* is cleared and can be closed
* 5) stateMachineController disconnects from BOBs control port and updates mState
*/
///
/// \brief The controllerState enum
/// States for the controller to keep track of what he is currently doing
enum controllerState {
csIdel,
csDoConnect,
csConnected,
csWaitForBob,
csDoDisconnect,
csDisconnected,
csError
};
///
/// \brief The controllerTask enum
/// This state tracks the controllers tast (e.g. setup a BOB tunnel or shut down
/// an existing one).
enum controllerTask {
ctIdle,
ctRunSetUp,
ctRunShutDown,
ctRunGetKeys,
ctRunCheck
};
///
/// \brief The bobState enum
/// One state for each message
///
enum bobState {
bsCleared,
bsSetnickC, // chain head for only client tunnel
bsSetnickN, // chain head for getting new (server) keys
bsSetnickS, // chain head for client and server tunnel
bsGetnick,
bsNewkeysC, // part of chain for only client tunnel
bsNewkeysN, // part of chain for getting new (server) keys
bsGetkeys,
bsSetkeys,
bsInhost,
bsOuthost,
bsInport,
bsOutport,
bsInlength,
bsOutlength,
bsInvariance,
bsOutvariance,
bsInquantity,
bsOutquantity,
bsQuiet,
bsStart,
bsStop,
bsClear,
bsList, // chain head for 'list' command
bsQuit
};
///
/// \brief The bobStateInfo struct
/// State machine with commands
/// \todo This could be replaced by a linked list instead of a map
struct bobStateInfo {
std::string command;
bobState nextState;
};
struct bobSettings {
bool enableBob; ///< This field is used by the pqi subsystem to determinine whether SOCKS proxy or BOB is used for I2P connections
std::string keys; ///< (optional) server keys
std::string addr; ///< (optional) hidden service addr. in base32 form
int8_t inLength;
int8_t inQuantity;
int8_t inVariance;
int8_t outLength;
int8_t outQuantity;
int8_t outVariance;
};
///
/// \brief The bobStates struct
/// This container struct is used to pass all states.
/// Additionally, the tunnel name is included to to show it in the GUI.
/// The advantage of a struct is that it can be forward declared.
struct bobStates {
bobState bs;
controllerState cs;
controllerTask ct;
std::string tunnelName;
};
class p3PeerMgr;
class p3I2pBob : public RsTickingThread, public p3Config, public autoProxyService
{
public:
p3I2pBob(p3PeerMgr *peerMgr);
// autoProxyService interface
public:
bool isEnabled();
bool initialSetup(std::string &addr, uint16_t &);
void processTaskAsync(taskTicket *ticket);
void processTaskSync(taskTicket *ticket);
static std::string keyToBase32Addr(const std::string &key);
// RsTickingThread interface
public:
void data_tick();
private:
int stateMachineBOB();
int stateMachineBOB_locked_failure(const std::string &answer, const bobStateInfo &currentState);
int stateMachineController();
int stateMachineController_locked_idle();
int stateMachineController_locked_connected();
int stateMachineController_locked_disconnected();
int stateMachineController_locked_error();
// p3Config interface
protected:
RsSerialiser *setupSerialiser();
bool saveList(bool &cleanup, std::list<RsItem *> &lst);
bool loadList(std::list<RsItem *> &load);
private:
// helpers
void getBOBSettings(bobSettings *settings);
void setBOBSettings(const bobSettings *settings);
void getStates(bobStates *bs);
std::string executeCommand(const std::string &command);
bool connectI2P();
bool disconnectI2P();
void finalizeSettings_locked();
void updateSettings_locked();
std::string recv();
// states for state machines
controllerState mState;
controllerTask mTask;
// used to store old state when in error state
// mStateOld is also used as a flag when an error occured in BOB protocol
controllerState mStateOld;
// mTaskOld is used to keep the previous task (start up / shut down) when requesting keys or checking the connection
controllerTask mTaskOld;
bobSettings mSetting;
bobState mBOBState;
// used variables
p3PeerMgr *mPeerMgr;
bool mConfigLoaded;
int mSocket;
time_t mLastProxyCheck;
sockaddr_storage mI2PProxyAddr;
std::map<bobState, bobStateInfo> mCommands;
std::string mErrorMsg;
std::string mTunnelName;
std::queue<taskTicket *> mPending;
taskTicket *mProcessing;
// mutex
RsMutex mLock;
};
#endif // P3I2PBOB_H

View File

@ -0,0 +1,305 @@
#include "rsautoproxymonitor.h"
rsAutoProxyMonitor *rsAutoProxyMonitor::mInstance = NULL;
rsAutoProxyMonitor::rsAutoProxyMonitor()
: mRSShutDown(false), mLock("rs auto proxy monitor")
{
mProxies.clear();
}
rsAutoProxyMonitor *rsAutoProxyMonitor::instance()
{
if (mInstance == NULL)
mInstance = new rsAutoProxyMonitor();
return mInstance;
}
void rsAutoProxyMonitor::addProxy(autoProxyType::autoProxyType_enum type, autoProxyService *service)
{
RS_STACK_MUTEX(mLock);
if (mProxies.find(type) != mProxies.end())
std::cerr << "sAutoProxyMonitor::addProxy type " << type << " already added - OVERWRITING" << std::endl;
mProxies[type] = service;
}
void rsAutoProxyMonitor::startAll()
{
// create ticket
taskTicket *tt = getTicket();
tt->cb = this;
tt->task = autoProxyTask::start;
{
std::map<autoProxyType::autoProxyType_enum, autoProxyService*>::const_iterator it;
// fill types
RS_STACK_MUTEX(mLock);
for (it = mProxies.begin(); it != mProxies.end(); ++it)
if (it->second->isEnabled())
tt->types.push_back(it->first);
}
task(tt);
}
void rsAutoProxyMonitor::stopAll()
{
// create ticket
taskTicket *tt = getTicket();
tt->cb = this;
tt->task = autoProxyTask::stop;
{
std::map<autoProxyType::autoProxyType_enum, autoProxyService*>::const_iterator it;
// fill types
RS_STACK_MUTEX(mLock);
for (it = mProxies.begin(); it != mProxies.end(); ++it)
if (it->second->isEnabled())
tt->types.push_back(it->first);
}
task(tt);
}
void rsAutoProxyMonitor::stopAllRSShutdown()
{
{
RS_STACK_MUTEX(mLock);
mRSShutDown = true;
// remove disabled services
std::vector<autoProxyType::autoProxyType_enum> toRemove;
std::map<autoProxyType::autoProxyType_enum, autoProxyService*>::const_iterator it;
for (it = mProxies.begin(); it != mProxies.end(); ++it) {
if (!it->second->isEnabled()) {
toRemove.push_back(it->first);
}
}
std::vector<autoProxyType::autoProxyType_enum>::const_iterator it2;
for (it2 = toRemove.begin(); it2 != toRemove.end(); ++it2) {
mProxies.erase(*it2);
}
}
// stop all remaining
stopAll();
// wait for shutdown of all services
uint32_t t = 0, timeout = 15;
do {
#ifndef WINDOWS_SYS
usleep(1000 * 1000);
#else
Sleep(1000);
#endif
RS_STACK_MUTEX(mLock);
std::cout << "(II) waiting for auto proxy service(s) to shut down " << t << "/" << timeout << " (remaining: " << mProxies.size() << ")" << std::endl;
if (mProxies.empty())
break;
t++;
} while (t < timeout );
}
bool rsAutoProxyMonitor::isEnabled(autoProxyType::autoProxyType_enum t)
{
autoProxyService *s = lookUpService(t);
if (s == NULL)
return false;
return s->isEnabled();
}
bool rsAutoProxyMonitor::initialSetup(autoProxyType::autoProxyType_enum t, std::string &addr, uint16_t &port)
{
autoProxyService *s = lookUpService(t);
if (s == NULL)
return false;
return s->initialSetup(addr, port);
}
void rsAutoProxyMonitor::task(taskTicket *ticket)
{
// sanity checks
if (!ticket->async && ticket->types.size() > 1) {
std::cerr << "(WW) rsAutoProxyMonitor::task synchronous call to multiple services. This can cause problems!" << std::endl;
}
if (ticket->async && !ticket->cb && ticket->data) {
std::cerr << "(WW) rsAutoProxyMonitor::task asynchronous call with data but no callback. This will likely causes memory leak!" << std::endl;
}
if (ticket->types.size() > 1 && ticket->data) {
std::cerr << "(WW) rsAutoProxyMonitor::task call with data to multiple services. This will likely causes memory leak!" << std::endl;
}
std::vector<autoProxyType::autoProxyType_enum>::const_iterator it;
for (it = ticket->types.begin(); it != ticket->types.end(); ++it) {
autoProxyService* s = lookUpService(*it);
if (s == NULL)
continue;
if (ticket->async) {
// copy ticket
taskTicket *tt = new taskTicket();
*tt = *ticket;
tt->types.clear();
tt->types.push_back(*it);
s->processTaskAsync(tt);
} else {
s->processTaskSync(ticket);
}
}
}
void rsAutoProxyMonitor::taskAsync(autoProxyType::autoProxyType_enum type, autoProxyTask::autoProxyTask_enum task, autoProxyCallback *cb, void *data)
{
std::vector<autoProxyType::autoProxyType_enum> types;
types.push_back(type);
taskAsync(types, task, cb, data);
}
void rsAutoProxyMonitor::taskAsync(std::vector<autoProxyType::autoProxyType_enum> types, autoProxyTask::autoProxyTask_enum task, autoProxyCallback *cb, void *data)
{
if (!isAsyncTask(task)) {
// Usually the services will reject this ticket.
// Just print a warning - maybe there is some special case where this is a good idea.
std::cerr << "(WW) rsAutoProxyMonitor::taskAsync called with a synchronous task!" << std::endl;
}
taskTicket *tt = getTicket();
tt->task = task;
tt->types = types;
if (cb)
tt->cb = cb;
if (data)
tt->data = data;
instance()->task(tt);
// tickets were copied, clean up
delete tt;
}
void rsAutoProxyMonitor::taskSync(autoProxyType::autoProxyType_enum type, autoProxyTask::autoProxyTask_enum task, void *data)
{
std::vector<autoProxyType::autoProxyType_enum> types;
types.push_back(type);
taskSync(types, task, data);
}
void rsAutoProxyMonitor::taskSync(std::vector<autoProxyType::autoProxyType_enum> types, autoProxyTask::autoProxyTask_enum task, void *data)
{
if (isAsyncTask(task)) {
// Usually the services will reject this ticket.
// Just print a warning - maybe there is some special case where this is a good idea.
std::cerr << "(WW) rsAutoProxyMonitor::taskSync called with an asynchronous task!" << std::endl;
}
taskTicket *tt = getTicket();
tt->async = false;
tt->task = task;
tt->types = types;
if (data)
tt->data = data;
instance()->task(tt);
// call done, clean up
delete tt;
}
void rsAutoProxyMonitor::taskError(taskTicket *t)
{
taskDone(t, autoProxyStatus::error);
}
void rsAutoProxyMonitor::taskDone(taskTicket *t, autoProxyStatus::autoProxyStatus_enum status)
{
bool cleanUp = false;
t->result = status;
if (t->cb) {
t->cb->taskFinished(t);
if (t != NULL) {
// callack did not clean up properly
std::cerr << "(WW) rsAutoProxyMonitor::taskFinish callback did not clean up!" << std::endl;
cleanUp = true;
}
} else if (t->async){
// async and no callback
// we must take care of deleting
cleanUp = true;
if(t->data)
std::cerr << "(WW) rsAutoProxyMonitor::taskFinish async call with data attached but no callback set!" << std::endl;
}
if (cleanUp) {
if (t->data) {
std::cerr << "(WW) rsAutoProxyMonitor::taskFinish will try to delete void pointer!" << std::endl;
#pragma GCC diagnostic ignored "-Wdelete-incomplete"
delete t->data;
#pragma GCC diagnostic pop
t->data = NULL;
}
delete t;
t = NULL;
}
}
taskTicket *rsAutoProxyMonitor::getTicket()
{
taskTicket *tt = new taskTicket();
tt->cb = NULL;
tt->data = NULL;
tt->async = true;
tt->result = autoProxyStatus::undefined;
return tt;
}
void rsAutoProxyMonitor::taskFinished(taskTicket *&ticket)
{
{
RS_STACK_MUTEX(mLock);
if (mRSShutDown && ticket->task == autoProxyTask::stop) {
mProxies.erase(ticket->types.front());
}
}
// clean up
if (ticket->data) {
std::cerr << "rsAutoProxyMonitor::taskFinished data set. Will try to delete void pointer" << std::endl;
#pragma GCC diagnostic ignored "-Wdelete-incomplete"
delete ticket->data;
#pragma GCC diagnostic pop
ticket->data = NULL;
}
delete ticket;
ticket = NULL;
}
autoProxyService *rsAutoProxyMonitor::lookUpService(autoProxyType::autoProxyType_enum t)
{
RS_STACK_MUTEX(mLock);
std::map<autoProxyType::autoProxyType_enum, autoProxyService*>::const_iterator itService;
if ((itService = mProxies.find(t)) != mProxies.end()) {
return itService->second;
}
std::cerr << "sAutoProxyMonitor::lookUpService no service for type " << t << " found!" << std::endl;
return NULL;
}
bool rsAutoProxyMonitor::isAsyncTask(autoProxyTask::autoProxyTask_enum t)
{
switch (t) {
case autoProxyTask::start:
case autoProxyTask::stop:
case autoProxyTask::receiveKey:
return true;
break;
default:
break;
}
return false;
}

View File

@ -0,0 +1,216 @@
#ifndef RSAUTOPROXYMONITOR_H
#define RSAUTOPROXYMONITOR_H
#include <vector>
#include <map>
#include <util/rsthreads.h>
class autoProxyCallback;
namespace autoProxyType {
enum autoProxyType_enum {
I2PBOB
};
}
namespace autoProxyTask {
enum autoProxyTask_enum {
/* async tasks */
start, ///< start up proxy
stop, ///< shut down proxy
receiveKey, ///< renew proxy key (if any)
proxyStatusCheck, ///< use to check if the proxy is still running
/* sync tasks */
status, ///< get status from auto proxy
getSettings, ///< get setting from auto proxy
setSettings, ///< set setting of auto proxy
reloadConfig, ///< signal config reload/rebuild
getErrorInfo ///< get error information from auto proxy
};
}
namespace autoProxyStatus {
enum autoProxyStatus_enum {
undefined, ///< undefined - usually not yet set
disabled, ///< used when a task cannot be done (e.g. a disabled service cannot be startet or stopped)
offline, ///< proxy is not set up
online, ///< proxy is set up
ok, ///< generic ok
error ///< generic error
};
}
struct taskTicket {
///
/// \brief types auto proxy service types that should get the ticket
///
std::vector<autoProxyType::autoProxyType_enum> types;
///
/// \brief task the task to satisfy
///
autoProxyTask::autoProxyTask_enum task;
///
/// \brief cb (optional) callback that gets called once the task is done
///
autoProxyCallback *cb;
///
/// \brief result (optional) result
///
autoProxyStatus::autoProxyStatus_enum result;
///
/// \brief data (optional) service dependent data
///
/// Needs to be allocated and freed by caller!
///
void *data;
///
/// \brief async is the call Asynchronous
///
/// Will create a copy of the ticket for each
/// service and delete the original ticket.
///
bool async;
};
class autoProxyCallback {
public:
///
/// \brief taskFinished called when a task is finished
/// \param ticket
///
/// Remove everything: ticket and attached data if any!
///
virtual void taskFinished(taskTicket *&ticket) = 0;
};
class autoProxyService {
public:
///
/// \brief isEnabled must be provided to directly get a result without going through the ticket system
/// \return whether the auto proxy service is enabled or not
///
virtual bool isEnabled() = 0;
///
/// \brief initialSetup used when creating a node
/// \param addr new address for the hidden service
/// \param port new port for the hidden service
/// \return true on success
///
/// This function is used to do an initial setup when creating a new hidden node.
/// Nothing has been set up at this point to the auto proxy service must take care
/// of everything (e.g. starting (and stoping) of needed threads)
///
virtual bool initialSetup(std::string &addr, uint16_t &port) = 0;
///
/// \brief processTaskAsync adds a ticket to the auto proxies task list
/// \param ticket
///
/// Don't call the callback in this function as this can cause dead locks!
///
virtual void processTaskAsync(taskTicket *ticket) = 0;
///
/// \brief processTaskSync taskTicket must be satisfied immediately
/// \param ticket
///
virtual void processTaskSync(taskTicket *ticket) = 0;
};
class rsAutoProxyMonitor : autoProxyCallback
{
public:
static rsAutoProxyMonitor *instance();
///
/// \brief addProxy adds a new auto proxy service to the monitor
/// \param type type of the new auto proxy service
/// \param service pointer to the service
///
void addProxy(autoProxyType::autoProxyType_enum type, autoProxyService *service);
// global functions
void startAll();
void stopAll();
void stopAllRSShutdown();
bool isEnabled(autoProxyType::autoProxyType_enum t);
// use this when creating a new node
bool initialSetup(autoProxyType::autoProxyType_enum t, std::string &addr, uint16_t &port);
///
/// \brief task Sends a task to all requested services
/// \param ticket Ticket containing required information
///
/// There are two kind of tasks: asyn and sync.
/// All tasks that involve communication with the target program (e.g. I2P or Tor) are asynchronous.
/// All other task are synchronous (e.g. getting settings)
///
///
/// Synchronous:
/// When you want to get the settings from a service you can call task() with a ticket only listing
/// one service and data pointing to the service's settings class/struct. Set async to false so
/// that the service gets your original ticket. Ther service will process the request (get settings)
/// immediately and when the call to task() is done you can access the settings from your ticket.
///
/// When additionally a call back is set the service will also call it. This can cause deadlocks!
///
///
/// Asynchronous:
/// When you want to start up all services or request new keys for all services you can call task() with a list
/// of services and set async to true. When each service has fullfilled the resquest he will
/// use the callback. The original caller ticket will be copied and each call to the callback
/// will use its copy of the original ticket. The attached data is not copied so each service gets
/// the same pointer!
///
///
/// Note:
/// Services should not delet or allocate anything unless no call back is provided and it is an
/// async call. In that case the service should delete the ticket and the attacked data.
/// Otherwise the caller must take care of cleaning up.
/// This class provides two wrappers to take care of this that should be used: taskError and taskDone
///
/// Note2:
/// This function is private so that each user must use the wrappers taskAsync and taskSync that include
/// more sanity checks
///
private:
void task(taskTicket *ticket);
public:
static void taskAsync(autoProxyType::autoProxyType_enum type, autoProxyTask::autoProxyTask_enum task, autoProxyCallback *cb = NULL, void *data = NULL);
static void taskAsync(std::vector<autoProxyType::autoProxyType_enum> types, autoProxyTask::autoProxyTask_enum task, autoProxyCallback *cb = NULL, void *data = NULL);
static void taskSync (autoProxyType::autoProxyType_enum type, autoProxyTask::autoProxyTask_enum task, void *data = NULL);
static void taskSync (std::vector<autoProxyType::autoProxyType_enum> types, autoProxyTask::autoProxyTask_enum task, void *data = NULL);
// usefull helpers
static void taskError(taskTicket *t);
static void taskDone(taskTicket *t, autoProxyStatus::autoProxyStatus_enum status);
static taskTicket *getTicket();
// autoProxyCallback interface
public:
void taskFinished(taskTicket *&ticket);
private:
rsAutoProxyMonitor();
autoProxyService *lookUpService(autoProxyType::autoProxyType_enum t);
static bool isAsyncTask(autoProxyTask::autoProxyTask_enum t);
std::map<autoProxyType::autoProxyType_enum, autoProxyService*> mProxies;
bool mRSShutDown;
RsMutex mLock;
static rsAutoProxyMonitor *mInstance;
};
#endif // RSAUTOPROXYMONITOR_H

View File

@ -0,0 +1,50 @@
#ifndef RADIX32_H
#define RADIX32_H
#include <string>
#include <string.h>
#include <vector>
#include <stdint.h>
class Radix32
{
public:
static std::string encode(const std::vector<uint8_t> &in) {
return encode(in.data(), in.size());
}
static std::string encode(const uint8_t *data, size_t len) {
std::string out = "";
size_t pos = 1;
uint8_t bits = 8, index;
uint16_t tmp = data[0]; // need min. 16 bits here
while (bits > 0 || pos < len) {
if (bits < 5) {
if (pos < len) {
tmp <<= 8;
tmp |= data[pos++] & 0xFF;
bits += 8;
} else { // last byte
tmp <<= (5 - bits);
bits = 5;
}
}
bits -= 5;
index = (tmp >> bits) & 0x1F;
out.push_back(bintoasc()[index]);
}
// append padding
while(out.length() % 4 != 0)
out.push_back('=');
return out;
}
private:
static const inline char *bintoasc() { static const char bta[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ234567"; return bta ; }
};
#endif // RADIX32_H

View File

@ -126,3 +126,24 @@ std::string RsUtil::HashId(const std::string &id, bool reverse)
// out << std::setprecision(15) << getCurrentTS();
// return out.str();
//}
std::vector<uint8_t> RsUtil::BinToSha256(const std::vector<uint8_t> &in)
{
std::vector<uint8_t> out;
SHA256_CTX *sha_ctx = new SHA256_CTX;
uint8_t sha_hash[SHA256_DIGEST_LENGTH] = {0};
SHA256_Init(sha_ctx);
SHA256_Update(sha_ctx, in.data(), in.size());
SHA256_Final(sha_hash, sha_ctx);
for(uint16_t i = 0; i < SHA256_DIGEST_LENGTH; i++)
{
out.push_back(sha_hash[i]);
}
/* cleanup */
delete sha_ctx;
return out;
}

View File

@ -30,6 +30,7 @@
#include <inttypes.h>
#include <string>
#include <vector>
namespace RsUtil {
@ -38,6 +39,7 @@ std::string BinToHex(const char *arr, const uint32_t len);
std::string BinToHex(const unsigned char *arr, const uint32_t len);
std::string NumberToString(uint64_t n, bool hex=false);
std::string HashId(const std::string &id, bool reverse = false);
std::vector<uint8_t> BinToSha256(const std::vector<uint8_t> &in);
//std::string AccurateTimeString();

View File

@ -149,6 +149,8 @@ GenCertDialog::GenCertDialog(bool onlyGenerateIdentity, QWidget *parent)
connect(ui.node_input, SIGNAL(textChanged(QString)), this, SLOT(updateCheckLabels()));
connect(ui.reuse_existing_node_CB, SIGNAL(toggled(bool)), this, SLOT(updateCheckLabels()));
connect(ui.cbUseBob, SIGNAL(clicked(bool)), this, SLOT(useBobChecked(bool)));;
entropy_timer = new QTimer ;
entropy_timer->start(20) ;
QObject::connect(entropy_timer,SIGNAL(timeout()),this,SLOT(grabMouse())) ;
@ -240,7 +242,7 @@ void GenCertDialog::mouseMoveEvent(QMouseEvent *e)
void GenCertDialog::setupState()
{
bool adv_state = ui.adv_checkbox->isChecked();
bool adv_state = ui.adv_checkbox->isChecked();
if(!adv_state)
{
@ -300,6 +302,7 @@ void GenCertDialog::setupState()
ui.hiddenaddr_label->setVisible(hidden_state);
ui.hiddenport_label->setVisible(hidden_state);
ui.hiddenport_spinBox->setVisible(hidden_state);
ui.cbUseBob->setVisible(hidden_state);
if(mEntropyOk && mAllFieldsOk)
{
@ -379,7 +382,22 @@ void GenCertDialog::updateCheckLabels()
else
ui.randomness_check_LB->setPixmap(QPixmap(IMAGE_BAD)) ;
setupState();
setupState();
}
void GenCertDialog::useBobChecked(bool checked)
{
if (checked) {
ui.hiddenaddr_input->setPlaceholderText(tr("I2P instance address with BOB enabled"));
ui.hiddenaddr_label->setText(tr("I2P instance address"));
ui.hiddenport_spinBox->setEnabled(false);
} else {
ui.hiddenaddr_input->setPlaceholderText(tr("hidden service address"));
ui.hiddenaddr_label->setText(tr("hidden address"));
ui.hiddenport_spinBox->setEnabled(true);
}
}
bool GenCertDialog::importIdentity()
@ -454,15 +472,13 @@ void GenCertDialog::genPerson()
{
std::string hl = ui.hiddenaddr_input->text().toStdString();
uint16_t port = ui.hiddenport_spinBox->value();
if (!RsInit::SetHiddenLocation(hl, port)) /* parses it */
{
/* Message Dialog */
QMessageBox::warning(this,
tr("Invalid hidden node"),
tr("Please enter a valid address of the form: 31769173498.onion:7800 or [52 characters].b32.i2p"),
QMessageBox::Ok);
return;
}
bool useBob = ui.cbUseBob->isChecked();
if (useBob && hl.empty())
hl = "127.0.0.1";
RsInit::SetHiddenLocation(hl, port, useBob); /* parses it */
isHiddenLoc = true;
}

View File

@ -45,6 +45,7 @@ private slots:
void switchReuseExistingNode();
void grabMouse();
void updateCheckLabels();
void useBobChecked(bool checked);
private:
void initKeyList();

View File

@ -450,6 +450,13 @@
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="cbUseBob">
<property name="text">
<string>Use BOB</string>
</property>
</widget>
</item>
</layout>
</item>
<item row="9" column="2">

View File

@ -487,6 +487,20 @@ void NotifyQt::notifyChatLobbyTimeShift(int shift)
emit chatLobbyTimeShift(shift) ;
}
void NotifyQt::notifyConnectionWithoutCert()
{
{
QMutexLocker m(&_mutex) ;
if(!_enabled)
return ;
}
#ifdef NOTIFY_DEBUG
std::cerr << "notifyQt: Received notifyConnectionWithoutCert" << std::endl;
#endif
emit connectionWithoutCert();
}
void NotifyQt::handleChatLobbyTimeShift(int /*shift*/)
{
return ; // we say nothing. The help dialog of lobbies explains this already.

View File

@ -52,6 +52,7 @@ class NotifyQt: public QObject, public NotifyClient
virtual void notifyOwnAvatarChanged() ;
virtual void notifyChatLobbyEvent(uint64_t /* lobby id */, uint32_t /* event type */, const RsGxsId & /*nickname*/, const std::string& /* any string */) ;
virtual void notifyChatLobbyTimeShift(int time_shift) ;
void notifyConnectionWithoutCert();
virtual void notifyOwnStatusMessageChanged() ;
virtual void notifyDiskFull(uint32_t loc,uint32_t size_in_mb) ;
@ -143,6 +144,7 @@ class NotifyQt: public QObject, public NotifyClient
void chatLobbyInviteReceived() ;
void deferredSignatureHandlingRequested() ;
void chatLobbyTimeShift(int time_shift) ;
void connectionWithoutCert();
/* Notify from GUI */
void chatFontChanged();

View File

@ -519,6 +519,21 @@ ServerPage QPlainTextEdit#plainTextEdit {
background-color: qlineargradient(x1:0, y1:0, x2:0, y2:1, stop:0 #FFFFD7, stop:1 #FFFFB2);
}
ServerPage QPlainTextEdit#hiddenpageInHelpPlainTextEdit {
border: 1px solid #DCDC41;
border-radius: 6px;
background: #FFFFD7;
background-color: qlineargradient(x1:0, y1:0, x2:0, y2:1, stop:0 #FFFFD7, stop:1 #FFFFB2);
}
ServerPage QPlainTextEdit#pteBobSimple {
border: 1px solid #DCDC41;
border-radius: 6px;
background: #FFFFD7;
background-color: qlineargradient(x1:0, y1:0, x2:0, y2:1, stop:0 #FFFFD7, stop:1 #FFFFB2);
}
/* ProfileManager */
ProfileManager > QFrame#headerFrame {

File diff suppressed because it is too large Load Diff

View File

@ -22,9 +22,8 @@
#ifndef SERVERPAGE_H
#define SERVERPAGE_H
#include <retroshare-gui/configpage.h>
#include "ui_ServerPage.h"
#include "RsAutoUpdatePage.h"
#include <inttypes.h>
/* get OS-specific definitions for:
* struct sockaddr_storage
@ -35,11 +34,18 @@
#include <winsock2.h>
#endif
#include <services/autoproxy/rsautoproxymonitor.h>
#include <services/autoproxy/p3i2pbob.h>
#include <retroshare-gui/configpage.h>
#include <retroshare-gui/RsAutoUpdatePage.h>
class QNetworkReply;
class QNetworkAccessManager;
class BanListPeer;
class ServerPage: public ConfigPage
class ServerPage: public ConfigPage, public autoProxyCallback
{
Q_OBJECT
@ -89,7 +95,40 @@ private slots:
void handleNetworkReply(QNetworkReply *reply);
void updateInProxyIndicator();
// i2p bob
void startBOB();
void restartBOB();
void stopBOB();
void getNewKey();
void loadKey();
void enableBob(bool checked);
void tunnelSettingsChanged(int);
void toggleBobAdvancedSettings(bool checked);
void syncI2PProxyPortNormal(int i);
void syncI2PProxyPortBob(int i);
void syncI2PProxyAddrNormal(QString);
void syncI2PProxyAddrBob(QString);
void connectionWithoutCert();
// autoProxyCallback interface
public:
void taskFinished(taskTicket *&ticket);
private:
void loadCommon();
void saveCommon();
void saveBob();
void updateStatusBob();
void setUpBobElements();
void enableBobElements(bool enable);
void updateInProxyIndicatorResult(bool success);
// ban list
void addPeerToIPTable(QTableWidget *table, int row, const BanListPeer &blp);
bool removeCurrentRowFromBlackList(sockaddr_storage& collected_addr,int& masked_bytes);
@ -105,9 +144,12 @@ private:
Ui::ServerPage ui;
QNetworkAccessManager *manager ;
int mOngoingConnectivityCheck;
bool mIsHiddenNode;
bool mIsHiddenNode;
uint32_t mHiddenType;
bobSettings mBobSettings;
bool mBobAccessible; // keeps track wether bob is accessable or not to en/disable the corresponding buttons
};
#endif // !SERVERPAGE_H

File diff suppressed because it is too large Load Diff