fixed some bugs in TorControl

This commit is contained in:
csoler 2021-12-17 16:54:44 +01:00
parent d9368507a9
commit af4c948024
17 changed files with 128 additions and 63 deletions

View File

@ -97,8 +97,8 @@ int RsFdBinInterface::read_pending()
if(readbytes > 0)
{
RsDbg() << "Received the following bytes: " << RsUtil::BinToHex( reinterpret_cast<unsigned char*>(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<unsigned char*>(inBuffer),readbytes,50) << std::endl;
RsDbg() << "Received the following bytes: " << std::string(inBuffer,readbytes) << std::endl;
void *ptr = malloc(readbytes);

View File

@ -75,12 +75,6 @@ RsThreadedTcpSocket::RsThreadedTcpSocket() : RsTcpSocket()
}
void RsThreadedTcpSocket::run()
{
if(!connect())
{
RsErr() << "Cannot connect socket to " << connectAddress() << ":" << connectPort() ;
return ;
}
while(connectionState() == CONNECTED)
{
tick();

View File

@ -57,7 +57,9 @@ enum class RsTorConnectivityStatus: uint8_t {
NOT_CONNECTED = 0x01,
CONNECTING = 0x02,
AUTHENTICATING = 0x03,
CONNECTED = 0x04
AUTHENTICATED = 0x04,
HIDDEN_SERVICE_READY = 0x05,
UNKNOWN = 0x06
};
// Status of the Tor service with which RS is talking.

View File

@ -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<const void*>(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();
}

View File

@ -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();
}
}

View File

@ -74,14 +74,14 @@ public:
void finishWithError(const std::string &errorMessage);
void finishWithSuccess();
void set_finished_callback(const std::function<void(void)>& f) { finished_callback = f; }
void set_finished_callback(const std::function<void(void)>& f) { mFinishedCallback = f; }
private:
bool m_finished;
std::string m_errorMessage;
std::function<void(void)> finished_callback;
std::function<void(void)> success_callback;
std::function<void(const std::string&)> error_callback;
std::function<void(void)> mFinishedCallback;
std::function<void(void)> mSuccessCallback;
std::function<void(const std::string&)> mErrorCallback;
};

View File

@ -36,7 +36,7 @@
using namespace Tor;
SetConfCommand::SetConfCommand()
: m_resetMode(false)
: m_resetMode(false), mConfSucceeded([](){}), mConfFailed([](int){})
{
}

View File

@ -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<RsTorManagerEvent>();
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<RsTorManagerEvent>();
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<RsTorManagerEvent>();
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<ByteArray> &data)
auto ev = std::make_shared<RsTorManagerEvent>();
ev->mTorManagerEventType = RsTorManagerEventCode::BOOTSTRAP_STATUS_CHANGED;
ev->mTorConnectivityStatus = torConnectivityStatus(mStatus);
ev->mTorStatus = ::torStatus(mTorStatus);
rsEvents->sendEvent(ev);
}
}

View File

@ -67,9 +67,10 @@ public:
Error = -1,
NotConnected = 0x00,
Connecting = 0x01,
SocketConnected= 0x02,
SocketConnected = 0x02,
Authenticating = 0x03,
Connected = 0x04
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<std::string,std::string> 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);

View File

@ -35,7 +35,9 @@
using namespace Tor;
TorControlCommand::TorControlCommand()
: m_finalStatus(0)
: m_finalStatus(0),
mReplyLine ( std::function<void(int, const ByteArray &)>([](int, const ByteArray &){})),
mFinished ( std::function<void(TorControlCommand*)>([](TorControlCommand*){}))
{
}

View File

@ -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
{

View File

@ -419,6 +419,8 @@ bool TorManager::startTorManager()
{
auto ev = std::make_shared<RsTorManagerEvent>();
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");
@ -742,7 +761,8 @@ RsTorConnectivityStatus RsTor::torConnectivityStatus()
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::Authenticated : return RsTorConnectivityStatus::AUTHENTICATED;
case Tor::TorControl::HiddenServiceReady : return RsTorConnectivityStatus::HIDDEN_SERVICE_READY;
}
}

View File

@ -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);
}
}
}

View File

@ -15,8 +15,8 @@ class ByteArray: public std::vector<unsigned char>
{
public:
ByteArray() =default;
ByteArray(int n) : std::vector<unsigned char>(n) {}
ByteArray(const unsigned char *d,int n) : std::vector<unsigned char>(n) { memcpy(data(),d,n); }
explicit ByteArray(int n) : std::vector<unsigned char>(n) {}
explicit ByteArray(const unsigned char *d,int n) : std::vector<unsigned char>(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<class T> 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;
}

View File

@ -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. " ;

View File

@ -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)

View File

@ -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())
{