diff --git a/libretroshare/src/pqi/pqifdbin.cc b/libretroshare/src/pqi/pqifdbin.cc index a982d670c..9a3d7ca2e 100644 --- a/libretroshare/src/pqi/pqifdbin.cc +++ b/libretroshare/src/pqi/pqifdbin.cc @@ -97,8 +97,8 @@ int RsFdBinInterface::read_pending() if(readbytes > 0) { - RsDbg() << "Received the following bytes: " << RsUtil::BinToHex( reinterpret_cast(inBuffer),readbytes,50) << std::endl; - //RsDbg() << "Received the following bytes: " << std::string(inBuffer,readbytes) << std::endl; + //RsDbg() << "Received the following bytes: " << RsUtil::BinToHex( reinterpret_cast(inBuffer),readbytes,50) << std::endl; + RsDbg() << "Received the following bytes: " << std::string(inBuffer,readbytes) << std::endl; void *ptr = malloc(readbytes); diff --git a/libretroshare/src/pqi/rstcpsocket.cc b/libretroshare/src/pqi/rstcpsocket.cc index e104da46e..1c8848941 100644 --- a/libretroshare/src/pqi/rstcpsocket.cc +++ b/libretroshare/src/pqi/rstcpsocket.cc @@ -75,12 +75,6 @@ RsThreadedTcpSocket::RsThreadedTcpSocket() : RsTcpSocket() } void RsThreadedTcpSocket::run() { - if(!connect()) - { - RsErr() << "Cannot connect socket to " << connectAddress() << ":" << connectPort() ; - return ; - } - while(connectionState() == CONNECTED) { tick(); diff --git a/libretroshare/src/retroshare/rstor.h b/libretroshare/src/retroshare/rstor.h index 347d8b1c7..0ae966a7e 100644 --- a/libretroshare/src/retroshare/rstor.h +++ b/libretroshare/src/retroshare/rstor.h @@ -53,11 +53,13 @@ enum class RsTorHiddenServiceStatus: uint8_t { // Status of the connection/authentication between RS and the Tor service enum class RsTorConnectivityStatus: uint8_t { - ERROR = 0x00, - NOT_CONNECTED = 0x01, - CONNECTING = 0x02, - AUTHENTICATING = 0x03, - CONNECTED = 0x04 + ERROR = 0x00, + NOT_CONNECTED = 0x01, + CONNECTING = 0x02, + AUTHENTICATING = 0x03, + AUTHENTICATED = 0x04, + HIDDEN_SERVICE_READY = 0x05, + UNKNOWN = 0x06 }; // Status of the Tor service with which RS is talking. diff --git a/libretroshare/src/tor/CryptoKey.cpp b/libretroshare/src/tor/CryptoKey.cpp index 641c1e4dc..95fdab016 100644 --- a/libretroshare/src/tor/CryptoKey.cpp +++ b/libretroshare/src/tor/CryptoKey.cpp @@ -135,8 +135,20 @@ ByteArray torControlHashedPassword(const ByteArray &password) uint32_t count = ((uint32_t)16 + (96 & 15)) << ((96 >> 4) + 6); - Sha1CheckSum md = RsDirUtil::sha1sum((salt+password).data(),count); + SHA_CTX hash; + SHA1_Init(&hash); + + ByteArray tmp = salt + password; + while (count) + { + int c = std::min((size_t)count, tmp.size()); + SHA1_Update(&hash, reinterpret_cast(tmp.data()), c); + count -= c; + } + + unsigned char md[20]; + SHA1_Final(md, &hash); /* 60 is the hex-encoded value of 96, which is a constant used by Tor's algorithm. */ - return ByteArray("16:") + salt.toHex().toUpper() + ByteArray("60") + ByteArray(md.toByteArray(), md.SIZE_IN_BYTES).toHex().toUpper(); + return ByteArray("16:") + salt.toHex().toUpper() + ByteArray("60") + ByteArray(md, 20).toHex().toUpper(); } diff --git a/libretroshare/src/tor/PendingOperation.cpp b/libretroshare/src/tor/PendingOperation.cpp index e22f63852..cbfb8897c 100644 --- a/libretroshare/src/tor/PendingOperation.cpp +++ b/libretroshare/src/tor/PendingOperation.cpp @@ -34,7 +34,7 @@ #include "PendingOperation.h" PendingOperation::PendingOperation() - : m_finished(false) + : m_finished(false),mFinishedCallback([](){}), mSuccessCallback([](){}),mErrorCallback([](const std::string&){}) { } @@ -67,8 +67,8 @@ void PendingOperation::finishWithError(const std::string &message) if (!m_finished) { m_finished = true; - finished_callback(); - error_callback(m_errorMessage); + mFinishedCallback(); + mErrorCallback(m_errorMessage); } } @@ -78,9 +78,9 @@ void PendingOperation::finishWithSuccess() if (!m_finished) { m_finished = true; - finished_callback(); + mFinishedCallback(); if (isSuccess()) - success_callback(); + mSuccessCallback(); } } diff --git a/libretroshare/src/tor/PendingOperation.h b/libretroshare/src/tor/PendingOperation.h index 5965bfd26..4a75b1c9e 100644 --- a/libretroshare/src/tor/PendingOperation.h +++ b/libretroshare/src/tor/PendingOperation.h @@ -74,14 +74,14 @@ public: void finishWithError(const std::string &errorMessage); void finishWithSuccess(); - void set_finished_callback(const std::function& f) { finished_callback = f; } + void set_finished_callback(const std::function& f) { mFinishedCallback = f; } private: bool m_finished; std::string m_errorMessage; - std::function finished_callback; - std::function success_callback; - std::function error_callback; + std::function mFinishedCallback; + std::function mSuccessCallback; + std::function mErrorCallback; }; diff --git a/libretroshare/src/tor/SetConfCommand.cpp b/libretroshare/src/tor/SetConfCommand.cpp index f4660d2c5..0285c8c8b 100644 --- a/libretroshare/src/tor/SetConfCommand.cpp +++ b/libretroshare/src/tor/SetConfCommand.cpp @@ -36,7 +36,7 @@ using namespace Tor; SetConfCommand::SetConfCommand() - : m_resetMode(false) + : m_resetMode(false), mConfSucceeded([](){}), mConfFailed([](int){}) { } diff --git a/libretroshare/src/tor/TorControl.cpp b/libretroshare/src/tor/TorControl.cpp index ac13ddcab..579077bad 100644 --- a/libretroshare/src/tor/TorControl.cpp +++ b/libretroshare/src/tor/TorControl.cpp @@ -143,7 +143,7 @@ static RsTorConnectivityStatus torConnectivityStatus(Tor::TorControl::Status t) case TorControl::NotConnected: return RsTorConnectivityStatus::NOT_CONNECTED; case TorControl::Connecting: return RsTorConnectivityStatus::CONNECTING; case TorControl::Authenticating: return RsTorConnectivityStatus::AUTHENTICATING; - case TorControl::Connected: return RsTorConnectivityStatus::CONNECTED; + case TorControl::Authenticated: return RsTorConnectivityStatus::AUTHENTICATED; } } static RsTorStatus torStatus(Tor::TorControl::TorStatus t) @@ -173,6 +173,7 @@ void TorControl::setStatus(TorControl::Status n) auto ev = std::make_shared(); ev->mTorManagerEventType = RsTorManagerEventCode::TOR_STATUS_CHANGED; + ev->mTorStatus = ::torStatus(mTorStatus); ev->mTorConnectivityStatus = torConnectivityStatus(mStatus); rsEvents->sendEvent(ev); @@ -198,13 +199,10 @@ void TorControl::setTorStatus(TorControl::TorStatus n) auto ev = std::make_shared(); ev->mTorManagerEventType = RsTorManagerEventCode::TOR_STATUS_CHANGED; + ev->mTorConnectivityStatus = torConnectivityStatus(mStatus); ev->mTorStatus = ::torStatus(mTorStatus); rsEvents->sendEvent(ev); } - if (mTorStatus == TorControl::TorReady && mSocksAddress.empty()) { - // Request info again to read the SOCKS port - getTorInfo(); - } } void TorControl::setError(const std::string &message) @@ -213,10 +211,6 @@ void TorControl::setError(const std::string &message) setStatus(TorControl::Error); RsWarn() << "torctrl: Error:" << mErrorMessage; - - mSocket->fullstop(); - - reconnect(); } TorControl::Status TorControl::status() const @@ -317,7 +311,7 @@ void TorControl::authenticateReply(TorControlCommand *sender) } torCtrlDebug() << "torctrl: Authentication successful" << std::endl; - setStatus(TorControl::Connected); + setStatus(TorControl::Authenticated); setTorStatus(TorControl::TorUnknown); @@ -343,8 +337,8 @@ void TorControl::authenticate() { assert(mStatus == TorControl::SocketConnected); - torCtrlDebug() << "torctrl: Connected socket; querying information" << std::endl; setStatus(TorControl::Authenticating); + torCtrlDebug() << "torctrl: Connected socket; querying information for authentication" << std::endl; ProtocolInfoCommand *command = new ProtocolInfoCommand(this); @@ -437,7 +431,7 @@ void TorControl::protocolInfoReply(TorControlCommand *sender) else if ((methods & ProtocolInfoCommand::AuthHashedPassword) && !mAuthPassword.empty()) { usePasswordAuth: - torCtrlDebug() << "torctrl: Using hashed password authentication" << std::endl; + torCtrlDebug() << "torctrl: Using hashed password authentication with AuthPasswd=\"" << mAuthPassword.toString() << "\"" << std::endl; data = auth->build(mAuthPassword); } else @@ -526,6 +520,8 @@ void TorControl::getTorInfoReply(TorControlCommand *sender) auto ev = std::make_shared(); ev->mTorManagerEventType = RsTorManagerEventCode::TOR_CONNECTIVITY_CHANGED; + ev->mTorConnectivityStatus = torConnectivityStatus(mStatus); + ev->mTorStatus = ::torStatus(mTorStatus); rsEvents->sendEvent(ev); } } @@ -586,7 +582,7 @@ void TorControl::publishServices() torCtrlDebug() << "torctrl: Publishing hidden service: " << service->hostname() << std::endl; AddOnionCommand *onionCommand = new AddOnionCommand(service); //protocolInfoReplyQObject::connect(onionCommand, &AddOnionCommand::succeeded, service, &HiddenService::servicePublished); - onionCommand->set_succeeded_callback( [service]() { service->servicePublished(); }); + onionCommand->set_succeeded_callback( [this,service]() { checkHiddenService(service) ; }); mSocket->sendCommand(onionCommand, onionCommand->build()); } } else { @@ -618,7 +614,7 @@ void TorControl::publishServices() torConfig.push_back(std::make_pair("HiddenServicePort", target)); } - command->set_ConfSucceeded_callback( [service]() { service->servicePublished(); }); + command->set_ConfSucceeded_callback( [this,service]() { checkHiddenService(service); }); //QObject::connect(command, &SetConfCommand::setConfSucceeded, service, &HiddenService::servicePublished); } @@ -627,6 +623,18 @@ void TorControl::publishServices() } } +void TorControl::checkHiddenService(HiddenService *service) +{ + service->servicePublished(); + + if(service->status() == HiddenService::Online) + { + RsDbg() << "Hidden service published and ready!" ; + + setStatus(TorControl::HiddenServiceReady); + } +} + void TorControl::shutdown() { if (!hasOwnership()) { @@ -697,6 +705,8 @@ void TorControl::updateBootstrap(const std::list &data) auto ev = std::make_shared(); ev->mTorManagerEventType = RsTorManagerEventCode::BOOTSTRAP_STATUS_CHANGED; + ev->mTorConnectivityStatus = torConnectivityStatus(mStatus); + ev->mTorStatus = ::torStatus(mTorStatus); rsEvents->sendEvent(ev); } } diff --git a/libretroshare/src/tor/TorControl.h b/libretroshare/src/tor/TorControl.h index 13aad5c9e..6936e6653 100644 --- a/libretroshare/src/tor/TorControl.h +++ b/libretroshare/src/tor/TorControl.h @@ -65,11 +65,12 @@ public: enum Status { Error = -1, - NotConnected = 0x00, - Connecting = 0x01, - SocketConnected= 0x02, - Authenticating = 0x03, - Connected = 0x04 + NotConnected = 0x00, + Connecting = 0x01, + SocketConnected = 0x02, + Authenticating = 0x03, + Authenticated = 0x04, + HiddenServiceReady = 0x05, }; enum TorStatus @@ -96,7 +97,7 @@ public: void setAuthPassword(const ByteArray& password); /* Connection */ - bool isConnected() const { return status() == Connected; } + bool isConnected() const { return status() == Authenticated; } void connect(const std::string &address, uint16_t port); void authenticate(); @@ -137,6 +138,7 @@ public: void reconnect(); + void getTorInfo(); private: TorControlSocket *mSocket; std::string mTorAddress; @@ -151,7 +153,7 @@ private: std::map mBootstrapStatus; bool mHasOwnership; - void getTorInfo(); + void checkHiddenService(HiddenService *service); void getTorInfoReply(TorControlCommand *sender); void setStatus(TorControl::Status n); void statusEvent(int code, const ByteArray &data); diff --git a/libretroshare/src/tor/TorControlCommand.cpp b/libretroshare/src/tor/TorControlCommand.cpp index 67e02169a..2bfc17a71 100644 --- a/libretroshare/src/tor/TorControlCommand.cpp +++ b/libretroshare/src/tor/TorControlCommand.cpp @@ -35,7 +35,9 @@ using namespace Tor; TorControlCommand::TorControlCommand() - : m_finalStatus(0) + : m_finalStatus(0), + mReplyLine ( std::function([](int, const ByteArray &){})), + mFinished ( std::function([](TorControlCommand*){})) { } diff --git a/libretroshare/src/tor/TorControlSocket.cpp b/libretroshare/src/tor/TorControlSocket.cpp index 40beb95ee..5d69dc7de 100644 --- a/libretroshare/src/tor/TorControlSocket.cpp +++ b/libretroshare/src/tor/TorControlSocket.cpp @@ -51,7 +51,14 @@ TorControlSocket::~TorControlSocket() bool TorControlSocket::connectToHost(const std::string& tcp_address,uint16_t tcp_port) { - return RsTcpSocket::connect(tcp_address,tcp_port); + if(RsTcpSocket::connect(tcp_address,tcp_port)) + { + start(); + return true; + } + else + return false; + } std::string TorControlSocket::peerAddress() const { diff --git a/libretroshare/src/tor/TorManager.cpp b/libretroshare/src/tor/TorManager.cpp index c63b38e11..338db478a 100644 --- a/libretroshare/src/tor/TorManager.cpp +++ b/libretroshare/src/tor/TorManager.cpp @@ -419,6 +419,8 @@ bool TorManager::startTorManager() { auto ev = std::make_shared(); ev->mTorManagerEventType = RsTorManagerEventCode::CONFIGURATION_NEEDED; + ev->mTorConnectivityStatus = RsTorConnectivityStatus::UNKNOWN; + ev->mTorStatus = RsTorStatus::UNKNOWN; rsEvents->sendEvent(ev); } //emit configurationNeededChanged(); @@ -469,6 +471,9 @@ void TorManager::threadTick() switch(d->control->status()) { + case TorControl::Connecting: + break; + case TorControl::NotConnected: RsDbg() << "Connecting to tor process at " << d->process->controlHost() << ":" << d->process->controlPort() << "..." ; d->control->connect(d->process->controlHost(),d->process->controlPort()); @@ -476,6 +481,7 @@ void TorManager::threadTick() case TorControl::SocketConnected: RsDbg() << "Connection established." ; + d->control->setAuthPassword(d->process->controlPassword()); d->control->authenticate(); break; @@ -483,7 +489,20 @@ void TorManager::threadTick() RsDbg() << "Authenticating..." ; break; - case TorControl::Connected:; + case TorControl::Authenticated:; + + RsDbg() << "Authenticated. Looking for hidden services."; + + for(auto service:d->control->hiddenServices()) + if(service->status() == HiddenService::Online) + { + + } + break; + + case TorControl::Error: + d->control->shutdown(); + d->control->reconnect(); break; } } @@ -549,7 +568,7 @@ void TorManagerPrivate::processLogMessage(const std::string &message) void TorManagerPrivate::controlStatusChanged(int status) { - if (status == TorControl::Connected) { + if (status == TorControl::Authenticated) { if (!configNeeded) { // If DisableNetwork is 1, trigger configurationNeeded auto cmd = control->getConfiguration("DisableNetwork"); @@ -738,11 +757,12 @@ RsTorConnectivityStatus RsTor::torConnectivityStatus() switch(ts) { default: - case Tor::TorControl::Error : return RsTorConnectivityStatus::ERROR; - case Tor::TorControl::NotConnected : return RsTorConnectivityStatus::NOT_CONNECTED; - case Tor::TorControl::Authenticating: return RsTorConnectivityStatus::AUTHENTICATING; - case Tor::TorControl::Connecting: return RsTorConnectivityStatus::CONNECTING; - case Tor::TorControl::Connected : return RsTorConnectivityStatus::CONNECTED; + case Tor::TorControl::Error : return RsTorConnectivityStatus::ERROR; + case Tor::TorControl::NotConnected : return RsTorConnectivityStatus::NOT_CONNECTED; + case Tor::TorControl::Authenticating: return RsTorConnectivityStatus::AUTHENTICATING; + case Tor::TorControl::Connecting: return RsTorConnectivityStatus::CONNECTING; + case Tor::TorControl::Authenticated : return RsTorConnectivityStatus::AUTHENTICATED; + case Tor::TorControl::HiddenServiceReady : return RsTorConnectivityStatus::HIDDEN_SERVICE_READY; } } diff --git a/libretroshare/src/tor/TorProcess.cpp b/libretroshare/src/tor/TorProcess.cpp index 3142e9488..c33fbb876 100644 --- a/libretroshare/src/tor/TorProcess.cpp +++ b/libretroshare/src/tor/TorProcess.cpp @@ -205,6 +205,8 @@ void TorProcess::start() if(m_client) m_client->processErrorChanged(mErrorMessage);// emit errorMessageChanged(d->errorMessage); if(m_client) m_client->processStateChanged(mState); // emit stateChanged(d->state); } + else + RsDbg() << "Using ControlPasswd=\"" << password.toString() << "\", hashed version=\"" << hashedPassword.toString() << "\"" ; mState = Starting; @@ -235,7 +237,7 @@ void TorProcess::start() args.push_back(mDataDir); args.push_back("HashedControlPassword") ; - args.push_back(torControlHashedPassword(mControlPassword).toString()); + args.push_back(hashedPassword.toString()); args.push_back("ControlPort") ; args.push_back("auto"); @@ -303,12 +305,14 @@ void TorProcess::tick() if(tryReadControlPort()) { mState = Ready; - // stateChanged(mState); + m_client->processStateChanged(mState);// stateChanged(mState); } else if(mControlPortReadNbTries > 10) { //errorMessageChanged(errorMessage); //stateChanged(state); + mState = Failed; + m_client->processStateChanged(mState);// stateChanged(mState); } } } diff --git a/libretroshare/src/tor/bytearray.h b/libretroshare/src/tor/bytearray.h index 6d8897ae9..f2c1903cf 100644 --- a/libretroshare/src/tor/bytearray.h +++ b/libretroshare/src/tor/bytearray.h @@ -15,8 +15,8 @@ class ByteArray: public std::vector { public: ByteArray() =default; - ByteArray(int n) : std::vector(n) {} - ByteArray(const unsigned char *d,int n) : std::vector(n) { memcpy(data(),d,n); } + explicit ByteArray(int n) : std::vector(n) {} + explicit ByteArray(const unsigned char *d,int n) : std::vector(n) { memcpy(data(),d,n); } virtual ~ByteArray() =default; ByteArray(const std::string& c) { resize(c.size()); memcpy(data(),c.c_str(),c.size()); } @@ -34,6 +34,7 @@ public: template void append(const T) = delete;// Prevents any implicit when calling the preceding functions which actually causes real bugs. + ByteArray& operator+=(char b) { push_back(b); return *this; } ByteArray& operator+=(const ByteArray& b) { for(auto c:b) push_back(c); return *this; } ByteArray& operator+=(const char *b) { for(uint32_t n=0;b[n]!=0;++n) push_back(b[n]); return *this;} @@ -51,6 +52,7 @@ public: return res; } bool endsWith(const ByteArray& b) const { return size() >= b.size() && !memcmp(&data()[size()-b.size()],b.data(),b.size()); } + bool endsWith(char b) const { return size() > 0 && back()==b; } bool startsWith(const ByteArray& b) const { return b.size() <= size() && !strncmp((char*)b.data(),(char*)data(),std::min(size(),b.size())); } bool startsWith(const char *b) const { @@ -121,7 +123,10 @@ public: current_block.clear(); } else - current_block += operator[](i); + current_block += (*this)[i]; + + if(!current_block.empty()) + res.push_back(current_block); return res; } @@ -142,6 +147,9 @@ public: else current_block += operator[](i); + if(!current_block.empty()) + res.push_back(current_block); + return res; } diff --git a/retroshare-gui/src/TorControl/TorControlWindow.cpp b/retroshare-gui/src/TorControl/TorControlWindow.cpp index b38d02038..7ec6f0392 100644 --- a/retroshare-gui/src/TorControl/TorControlWindow.cpp +++ b/retroshare-gui/src/TorControl/TorControlWindow.cpp @@ -90,7 +90,7 @@ void TorControlDialog::statusChanged(RsTorStatus torstatus, RsTorConnectivitySta case RsTorConnectivityStatus::NOT_CONNECTED: tor_control_status_str = tr("Not connected") ; break ; case RsTorConnectivityStatus::CONNECTING: tor_control_status_str = tr("Connecting") ; break ; case RsTorConnectivityStatus::AUTHENTICATING: tor_control_status_str = tr("Authenticating") ; break ; - case RsTorConnectivityStatus::CONNECTED: tor_control_status_str = tr("Connected") ; break ; + case RsTorConnectivityStatus::AUTHENTICATED: tor_control_status_str = tr("Authenticated") ; break ; } switch(torstatus) @@ -195,6 +195,10 @@ TorControlDialog::HiddenServiceStatus TorControlDialog::checkForHiddenService() switch(mHiddenServiceStatus) { default: + case HIDDEN_SERVICE_STATUS_FAIL: { + std::cerr << " Hidden service setup failed. Something's wrong." << std::endl; + return mHiddenServiceStatus; + } case HIDDEN_SERVICE_STATUS_UNKNOWN: { std::cerr << " trying to setup. " ; diff --git a/retroshare-gui/src/gui/statusbar/torstatus.cpp b/retroshare-gui/src/gui/statusbar/torstatus.cpp index 319d8da3d..44de873ae 100644 --- a/retroshare-gui/src/gui/statusbar/torstatus.cpp +++ b/retroshare-gui/src/gui/statusbar/torstatus.cpp @@ -104,7 +104,7 @@ void TorStatus::getTorStatus() case RsTorConnectivityStatus::NOT_CONNECTED: tor_control_ok = false ; tor_control_status_str = "Not connected" ; break ; case RsTorConnectivityStatus::CONNECTING: tor_control_ok = false ; tor_control_status_str = "Connecting" ; break ; case RsTorConnectivityStatus::AUTHENTICATING: tor_control_ok = false ; tor_control_status_str = "Authenticating" ; break ; - case RsTorConnectivityStatus::CONNECTED: tor_control_ok = true ; tor_control_status_str = "Connected" ; break ; + case RsTorConnectivityStatus::AUTHENTICATED: tor_control_ok = true ; tor_control_status_str = "Connected" ; break ; } switch(torstatus) diff --git a/retroshare-gui/src/main.cpp b/retroshare-gui/src/main.cpp index 104f525a8..56495d592 100644 --- a/retroshare-gui/src/main.cpp +++ b/retroshare-gui/src/main.cpp @@ -406,7 +406,7 @@ feenableexcept(FE_INVALID | FE_DIVBYZERO); RsDirUtil::checkCreateDirectory(std::string(tor_hidden_service_dir)) ; - RsTor::setupHiddenService(); + //RsTor::setupHiddenService(); if(! RsTor::start() || RsTor::hasError()) {