Changes for Tor API

This commit is contained in:
defnax 2026-08-16 19:58:06 +02:00
parent 145f716794
commit 6499ffbae6
3 changed files with 101 additions and 46 deletions

View File

@ -128,6 +128,21 @@ public:
*/
static RsTorConnectivityStatus torConnectivityStatus() ;
/**
* Configure TorManager to attach to an already running Tor instance.
* This must be called before start(). The external process is never
* stopped or taken over by RetroShare.
*
* This endpoint is available before account login because the Tor
* connection must be configured before hidden-node initialization starts.
*
* @jsonapi{development,unauthenticated}
*/
static bool setExternalTorConnection(
const std::string& controlAddress, uint16_t controlPort,
const std::string& controlPassword,
const std::string& socksAddress, uint16_t socksPort );
static void setTorDataDirectory(const std::string& dir);
static void setHiddenServiceDirectory(const std::string& dir);

View File

@ -74,6 +74,12 @@ public:
bool configNeeded;
bool mVerbose;
std::string userProvidedTorExecutablePath;
bool useExternalTor;
std::string externalControlAddress;
uint16_t externalControlPort;
ByteArray externalControlPassword;
std::string externalSocksAddress;
uint16_t externalSocksPort;
HiddenService *hiddenService ;
@ -123,6 +129,9 @@ TorManagerPrivate::TorManagerPrivate(TorManager *parent)
, control(new TorControl())
, configNeeded(false)
, mVerbose(false)
, useExternalTor(false)
, externalControlPort(0)
, externalSocksPort(0)
, hiddenService(NULL)
{
control->set_statusChanged_callback([this](int new_status,int /*old_status*/) { controlStatusChanged(new_status); });
@ -371,6 +380,32 @@ std::string TorManager::torExecutablePath() const
return (d==nullptr)?(std::string()):(d->torExecutablePath());
}
bool TorManager::setExternalTorConnection(
const std::string& controlAddress, uint16_t controlPort,
const std::string& controlPassword,
const std::string& socksAddress, uint16_t socksPort )
{
if(isRunning())
{
d->setError("Cannot change Tor connection while TorManager is running.");
return false;
}
if(controlAddress.empty() || controlPort == 0 ||
socksAddress.empty() || socksPort == 0)
{
d->setError("External Tor control and SOCKS endpoints must be valid.");
return false;
}
d->useExternalTor = true;
d->externalControlAddress = controlAddress;
d->externalControlPort = controlPort;
d->externalControlPassword = ByteArray(controlPassword);
d->externalSocksAddress = socksAddress;
d->externalSocksPort = socksPort;
return true;
}
const std::list<std::string>& TorManager::logMessages() const
{
return d->logMessages;
@ -394,43 +429,14 @@ bool TorManager::startTorManager()
//emit errorChanged(); // not needed because there's no error to handle
}
#ifdef TODO
SettingsObject settings("tor");
// If a control port is defined by config or environment, skip launching tor
if (!settings.read("controlPort").isUndefined() ||
!qEnvironmentVariableIsEmpty("TOR_CONTROL_PORT"))
if(d->useExternalTor)
{
QHostAddress address(settings.read("controlAddress").toString());
quint16 port = (quint16)settings.read("controlPort").toInt();
QByteArray password = settings.read("controlPassword").toString().toLatin1();
if (!qEnvironmentVariableIsEmpty("TOR_CONTROL_HOST"))
address = QHostAddress(qgetenv("TOR_CONTROL_HOST"));
if (!qEnvironmentVariableIsEmpty("TOR_CONTROL_PORT")) {
bool ok = false;
port = qgetenv("TOR_CONTROL_PORT").toUShort(&ok);
if (!ok)
port = 0;
}
if (!qEnvironmentVariableIsEmpty("TOR_CONTROL_PASSWD"))
password = qgetenv("TOR_CONTROL_PASSWD");
if (!port) {
d->setError("Invalid control port settings from environment or configuration");
return false;
}
if (address.isNull())
address = QHostAddress::LocalHost;
d->control->setAuthPassword(password);
d->control->connect(address, port);
RsInfo() << "Connecting to external Tor control port at "
<< d->externalControlAddress << ":" << d->externalControlPort;
d->control->setAuthPassword(d->externalControlPassword);
d->control->connect(d->externalControlAddress, d->externalControlPort);
}
else
#endif
{
// Launch a bundled Tor instance
std::string executable = d->torExecutablePath();
@ -503,7 +509,8 @@ bool TorManager::startTorManager()
void TorManager::run()
{
d->process->start();
if(d->process)
d->process->start();
while(!shouldStop())
{
@ -512,7 +519,8 @@ void TorManager::run()
}
d->control->shutdownSync();
d->process->stop();
if(d->process)
d->process->stop();
if(rsEvents)
{
@ -526,10 +534,12 @@ void TorManager::threadTick()
{
static bool authenticated_msg_already_given = false;
d->process->tick();
if(d->process->state() != TorProcess::Ready)
return;
if(d->process)
{
d->process->tick();
if(d->process->state() != TorProcess::Ready)
return;
}
switch(d->control->status())
{
@ -538,8 +548,10 @@ void TorManager::threadTick()
break;
case TorControl::NotConnected:
RsInfo() << "Connecting to tor process at " << d->process->controlHost() << ":" << d->process->controlPort() << "..." ;
d->control->connect(d->process->controlHost(),d->process->controlPort());
if(d->useExternalTor)
d->control->connect(d->externalControlAddress,d->externalControlPort);
else
d->control->connect(d->process->controlHost(),d->process->controlPort());
break;
case TorControl::SocketConnected:
@ -551,7 +563,8 @@ void TorManager::threadTick()
setupHiddenService();
}
d->control->setAuthPassword(d->process->controlPassword());
d->control->setAuthPassword(d->useExternalTor
? d->externalControlPassword : d->process->controlPassword());
d->control->authenticate();
RsInfo() << "Authenticating..." ;
break;
@ -588,6 +601,12 @@ bool TorManager::getProxyServerInfo(std::string& proxy_server_adress,uint16_t& p
proxy_server_adress = control()->socksAddress();
proxy_server_port = control()->socksPort();
if(d->useExternalTor && (proxy_server_adress.empty() || proxy_server_port == 0))
{
proxy_server_adress = d->externalSocksAddress;
proxy_server_port = d->externalSocksPort;
}
return proxy_server_port > 1023 ;
}
@ -796,7 +815,17 @@ void TorManagerPrivate::setError(const std::string &message)
bool RsTor::isTorAvailable()
{
return !instance()->d->torExecutablePath().empty();
return instance()->d->useExternalTor || !instance()->d->torExecutablePath().empty();
}
bool RsTor::setExternalTorConnection(
const std::string& controlAddress, uint16_t controlPort,
const std::string& controlPassword,
const std::string& socksAddress, uint16_t socksPort )
{
return instance()->setExternalTorConnection(
controlAddress, controlPort, controlPassword,
socksAddress, socksPort );
}
bool RsTor::getHiddenServiceInfo(std::string& service_id,
@ -840,11 +869,17 @@ void RsTor::setTorExecutablePath(const std::string& e)
std::string RsTor::socksAddress()
{
return instance()->control()->socksAddress();
std::string address;
uint16_t port = 0;
instance()->getProxyServerInfo(address, port);
return address;
}
uint16_t RsTor::socksPort()
{
return instance()->control()->socksPort();
std::string address;
uint16_t port = 0;
instance()->getProxyServerInfo(address, port);
return port;
}
static RsTorStatus torStatus(Tor::TorControl::TorStatus t)

View File

@ -62,6 +62,11 @@ public:
std::string torExecutablePath() const;
void setTorExecutablePath(const std::string& tor_exe_full_path) ;
bool setExternalTorConnection(
const std::string& controlAddress, uint16_t controlPort,
const std::string& controlPassword,
const std::string& socksAddress, uint16_t socksPort );
std::string hiddenServiceDirectory() const;
void setHiddenServiceDirectory(const std::string &path);