mirror of
https://github.com/RetroShare/RetroShare.git
synced 2025-07-26 16:05:48 -04:00
split tor control into two parts
This commit is contained in:
parent
e87b25794f
commit
5b5a2bef81
4 changed files with 151 additions and 49 deletions
|
@ -1,8 +1,13 @@
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
#include <QTimer>
|
#include <QTimer>
|
||||||
#include <QFile>
|
#include <QFile>
|
||||||
|
#include <QTcpServer>
|
||||||
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
|
||||||
#include "TorControlWindow.h"
|
#include "TorControlWindow.h"
|
||||||
|
#include "TorManager.h"
|
||||||
#include "TorControl.h"
|
#include "TorControl.h"
|
||||||
#include "HiddenService.h"
|
#include "HiddenService.h"
|
||||||
|
|
||||||
|
@ -19,37 +24,51 @@ TorControlDialog::TorControlDialog(Tor::TorManager *tm,QWidget *parent)
|
||||||
QObject::connect(tm->control(),SIGNAL(bootstrapStatusChanged()),this,SLOT(statusChanged()));
|
QObject::connect(tm->control(),SIGNAL(bootstrapStatusChanged()),this,SLOT(statusChanged()));
|
||||||
QObject::connect(tm->control(),SIGNAL(connectivityChanged()),this,SLOT(statusChanged()));
|
QObject::connect(tm->control(),SIGNAL(connectivityChanged()),this,SLOT(statusChanged()));
|
||||||
|
|
||||||
QTimer::singleShot(2000,this,SLOT(checkForHiddenService())) ;
|
//QTimer::singleShot(2000,this,SLOT(checkForHiddenService())) ;
|
||||||
//void configurationNeededChanged();
|
|
||||||
|
mIncomingServer = new QTcpServer(this) ;
|
||||||
|
mHiddenService = NULL ;
|
||||||
|
|
||||||
|
connect(mIncomingServer, SIGNAL(QTcpServer::newConnection()), this, SLOT(onIncomingConnection()));
|
||||||
|
}
|
||||||
|
|
||||||
|
void TorControlDialog::onIncomingConnection()
|
||||||
|
{
|
||||||
|
std::cerr << "Incoming connection !!" << std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
void TorControlDialog::setupHiddenService()
|
void TorControlDialog::setupHiddenService()
|
||||||
{
|
{
|
||||||
|
/*
|
||||||
QString keyData = m_settings->read("serviceKey").toString();
|
QString keyData = m_settings->read("serviceKey").toString();
|
||||||
QString legacyDir = m_settings->read("dataDirectory").toString();
|
QString legacyDir = m_settings->read("dataDirectory").toString();
|
||||||
|
|
||||||
if (!keyData.isEmpty())
|
if (!keyData.isEmpty())
|
||||||
{
|
{
|
||||||
CryptoKey key;
|
CryptoKey key;
|
||||||
if (!key.loadFromData(QByteArray::fromBase64(keyData.toLatin1()), CryptoKey::PrivateKey, CryptoKey::DER)) {
|
if (!key.loadFromData(QByteArray::fromBase64(keyData.toLatin1()), CryptoKey::PrivateKey, CryptoKey::DER))
|
||||||
|
{
|
||||||
qWarning() << "Cannot load service key from configuration";
|
qWarning() << "Cannot load service key from configuration";
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
m_hiddenService = new Tor::HiddenService(key, legacyDir, this);
|
mHiddenService = new Tor::HiddenService(key, legacyDir, this);
|
||||||
}
|
}
|
||||||
else if (!legacyDir.isEmpty() && QFile::exists(legacyDir + QLatin1String("/private_key")))
|
else if (!legacyDir.isEmpty() && QFile::exists(legacyDir + QLatin1String("/private_key")))
|
||||||
{
|
{
|
||||||
qDebug() << "Attempting to load key from legacy filesystem format in" << legacyDir;
|
qDebug() << "Attempting to load key from legacy filesystem format in" << legacyDir;
|
||||||
|
|
||||||
CryptoKey key;
|
CryptoKey key;
|
||||||
if (!key.loadFromFile(legacyDir + QLatin1String("/private_key"), CryptoKey::PrivateKey)) {
|
if (!key.loadFromFile(legacyDir + QLatin1String("/private_key"), CryptoKey::PrivateKey))
|
||||||
|
{
|
||||||
qWarning() << "Cannot load legacy format key from" << legacyDir << "for conversion";
|
qWarning() << "Cannot load legacy format key from" << legacyDir << "for conversion";
|
||||||
return;
|
return;
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
keyData = QString::fromLatin1(key.encodedPrivateKey(CryptoKey::DER).toBase64());
|
keyData = QString::fromLatin1(key.encodedPrivateKey(CryptoKey::DER).toBase64());
|
||||||
m_settings->write("serviceKey", keyData);
|
m_settings->write("serviceKey", keyData);
|
||||||
m_hiddenService = new Tor::HiddenService(key, legacyDir, this);
|
mHiddenService = new Tor::HiddenService(key, legacyDir, this);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (!m_settings->read("initializing").toBool())
|
else if (!m_settings->read("initializing").toBool())
|
||||||
|
@ -59,52 +78,54 @@ void TorControlDialog::setupHiddenService()
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
m_hiddenService = new Tor::HiddenService(legacyDir, this);
|
mHiddenService = new Tor::HiddenService(legacyDir, this);
|
||||||
|
|
||||||
connect(m_hiddenService, &Tor::HiddenService::privateKeyChanged, this, [&]()
|
connect(mHiddenService, &Tor::HiddenService::privateKeyChanged, this, [&]()
|
||||||
{
|
{
|
||||||
QString key = QString::fromLatin1(m_hiddenService->privateKey().encodedPrivateKey(CryptoKey::DER).toBase64());
|
QString key = QString::fromLatin1(mHiddenService->privateKey().encodedPrivateKey(CryptoKey::DER).toBase64());
|
||||||
m_settings->write("serviceKey", key);
|
m_settings->write("serviceKey", key);
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
Q_ASSERT(m_hiddenService);
|
Q_ASSERT(mHiddenService);
|
||||||
connect(m_hiddenService, SIGNAL(statusChanged(int,int)), SLOT(onStatusChanged(int,int)));
|
connect(mHiddenService, SIGNAL(statusChanged(int,int)), SLOT(onStatusChanged(int,int)));
|
||||||
|
|
||||||
// Generally, these are not used, and we bind to localhost and port 0
|
// Generally, these are not used, and we bind to localhost and port 0
|
||||||
// for an automatic (and portable) selection.
|
// for an automatic (and portable) selection.
|
||||||
|
|
||||||
QHostAddress address(m_settings->read("localListenAddress").toString());
|
QHostAddress address(m_settings->read("localListenAddress").toString());
|
||||||
|
|
||||||
if (address.isNull())
|
if (address.isNull())
|
||||||
address = QHostAddress::LocalHost;
|
address = QHostAddress::LocalHost;
|
||||||
|
|
||||||
quint16 port = (quint16)m_settings->read("localListenPort").toInt();
|
quint16 port = (quint16)m_settings->read("localListenPort").toInt();
|
||||||
|
|
||||||
m_incomingServer = new QTcpServer(this);
|
if (!mIncomingServer->listen(address, port))
|
||||||
if (!m_incomingServer->listen(address, port)) {
|
{
|
||||||
// XXX error case
|
// XXX error case
|
||||||
qWarning() << "Failed to open incoming socket:" << m_incomingServer->errorString();
|
qWarning() << "Failed to open incoming socket:" << mIncomingServer->errorString();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
connect(m_incomingServer, &QTcpServer::newConnection, this, &UserIdentity::onIncomingConnection);
|
mHiddenService->addTarget(9878, mIncomingServer->serverAddress(), mIncomingServer->serverPort());
|
||||||
|
torControl->addHiddenService(mHiddenService);
|
||||||
m_hiddenService->addTarget(9878, m_incomingServer->serverAddress(), m_incomingServer->serverPort());
|
*/
|
||||||
torControl->addHiddenService(m_hiddenService);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void TorControlDialog::checkForHiddenService()
|
// void TorControlDialog::checkForHiddenService()
|
||||||
{
|
// {
|
||||||
QList<Tor::HiddenService*> hidden_services = mTorManager->control()->hiddenServices();
|
// QList<Tor::HiddenService*> hidden_services = mTorManager->control()->hiddenServices();
|
||||||
|
//
|
||||||
std::cerr << "Checking for hidden services:" << std::endl;
|
// std::cerr << "Checking for hidden services:" << std::endl;
|
||||||
|
//
|
||||||
if(hidden_services.empty())
|
// if(hidden_services.empty())
|
||||||
{
|
// {
|
||||||
setupHiddenService();
|
// setupHiddenService();
|
||||||
|
//
|
||||||
QTimer::singleShot(2000,this,SLOT(checkForHiddenService())) ;
|
// QTimer::singleShot(2000,this,SLOT(checkForHiddenService())) ;
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
|
||||||
void TorControlDialog::statusChanged()
|
void TorControlDialog::statusChanged()
|
||||||
{
|
{
|
||||||
|
@ -174,3 +195,24 @@ void TorControlDialog::showLog()
|
||||||
torLog_TB->setText(s) ;
|
torLog_TB->setText(s) ;
|
||||||
QCoreApplication::processEvents() ;
|
QCoreApplication::processEvents() ;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TorControlDialog::TorStatus TorControlDialog::checkForTor()
|
||||||
|
{
|
||||||
|
switch(mTorManager->control()->status())
|
||||||
|
{
|
||||||
|
case Tor::TorControl::Connected: usleep(2*1000*1000);return TOR_STATUS_OK ;
|
||||||
|
case Tor::TorControl::Error: return TOR_STATUS_FAIL ;
|
||||||
|
|
||||||
|
default:
|
||||||
|
return TOR_STATUS_UNKNOWN ;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
TorControlDialog::HiddenServiceStatus TorControlDialog::checkForHiddenService()
|
||||||
|
{
|
||||||
|
return HIDDEN_SERVICE_STATUS_UNKNOWN ;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,11 @@
|
||||||
#include "ui_TorControlWindow.h"
|
#include "ui_TorControlWindow.h"
|
||||||
#include "TorManager.h"
|
|
||||||
|
class QTcpServer ;
|
||||||
|
|
||||||
|
namespace Tor {
|
||||||
|
class HiddenService ;
|
||||||
|
class TorManager ;
|
||||||
|
}
|
||||||
|
|
||||||
class TorControlDialog: public QDialog, public Ui::TorControlDialog
|
class TorControlDialog: public QDialog, public Ui::TorControlDialog
|
||||||
{
|
{
|
||||||
|
@ -8,13 +14,34 @@ class TorControlDialog: public QDialog, public Ui::TorControlDialog
|
||||||
public:
|
public:
|
||||||
TorControlDialog(Tor::TorManager *tm,QWidget *parent =NULL);
|
TorControlDialog(Tor::TorManager *tm,QWidget *parent =NULL);
|
||||||
|
|
||||||
|
enum TorStatus {
|
||||||
|
TOR_STATUS_UNKNOWN = 0x00,
|
||||||
|
TOR_STATUS_OK = 0x01,
|
||||||
|
TOR_STATUS_FAIL = 0x02
|
||||||
|
};
|
||||||
|
|
||||||
|
enum HiddenServiceStatus {
|
||||||
|
HIDDEN_SERVICE_STATUS_UNKNOWN = 0x00,
|
||||||
|
HIDDEN_SERVICE_STATUS_OK = 0x01,
|
||||||
|
HIDDEN_SERVICE_STATUS_FAIL = 0x02
|
||||||
|
};
|
||||||
|
|
||||||
|
// Should be called multiple times in a loop until it returns something else than *_UNKNOWN
|
||||||
|
|
||||||
|
TorStatus checkForTor() ;
|
||||||
|
HiddenServiceStatus checkForHiddenService() ;
|
||||||
|
|
||||||
protected slots:
|
protected slots:
|
||||||
void showLog();
|
void showLog();
|
||||||
void statusChanged();
|
void statusChanged();
|
||||||
void checkForHiddenService();
|
// void checkForHiddenService();
|
||||||
|
void onIncomingConnection();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void setupHiddenService();
|
void setupHiddenService();
|
||||||
|
|
||||||
Tor::TorManager *mTorManager ;
|
Tor::TorManager *mTorManager ;
|
||||||
|
Tor::HiddenService *mHiddenService ;
|
||||||
|
|
||||||
|
QTcpServer *mIncomingServer ;
|
||||||
};
|
};
|
||||||
|
|
|
@ -187,6 +187,10 @@ public:
|
||||||
/** Sets whether the bandwidth graph is always on top. */
|
/** Sets whether the bandwidth graph is always on top. */
|
||||||
void setBWGraphAlwaysOnTop(bool alwaysOnTop);
|
void setBWGraphAlwaysOnTop(bool alwaysOnTop);
|
||||||
|
|
||||||
|
#ifdef RETROTOR
|
||||||
|
void setHiddenServiceKey() ;
|
||||||
|
#endif
|
||||||
|
|
||||||
uint getNewsFeedFlags();
|
uint getNewsFeedFlags();
|
||||||
void setNewsFeedFlags(uint flags);
|
void setNewsFeedFlags(uint flags);
|
||||||
|
|
||||||
|
|
|
@ -282,23 +282,29 @@ feenableexcept(FE_INVALID | FE_DIVBYZERO);
|
||||||
Rshare rshare(args, argc, argv, QString::fromUtf8(RsAccounts::ConfigDirectory().c_str()));
|
Rshare rshare(args, argc, argv, QString::fromUtf8(RsAccounts::ConfigDirectory().c_str()));
|
||||||
|
|
||||||
#ifdef RETROTOR
|
#ifdef RETROTOR
|
||||||
// Start the Tor engine, and make sure it provides a viable hidden service
|
// First check that we can start the Tor engine, if not, quit.
|
||||||
|
|
||||||
/* Tor control manager */
|
/* Tor control manager */
|
||||||
Tor::TorManager *torManager = Tor::TorManager::instance();
|
Tor::TorManager *torManager = Tor::TorManager::instance();
|
||||||
torManager->setDataDirectory(Rshare::dataDirectory() + QString("/tor/"));
|
torManager->setDataDirectory(Rshare::dataDirectory() + QString("/tor/"));
|
||||||
//torManager->setDataDirectory(QString("./tor"));//settings->filePath()).path() + QString("/tor/"));
|
|
||||||
|
|
||||||
torManager->start();
|
torManager->start();
|
||||||
|
|
||||||
TorControlDialog tcd(torManager) ;
|
TorControlDialog tcd(torManager) ;
|
||||||
tcd.exec();
|
tcd.show();
|
||||||
// tcd.show() ;
|
|
||||||
//
|
while(tcd.checkForTor() == TorControlDialog::TOR_STATUS_UNKNOWN) // runs until some status is reached: either tor works, or it fails.
|
||||||
// while(true)
|
{
|
||||||
// {
|
QCoreApplication::processEvents();
|
||||||
// QCoreApplication::processEvents();
|
usleep(1000) ;
|
||||||
// }
|
}
|
||||||
|
|
||||||
|
tcd.hide();
|
||||||
|
|
||||||
|
if(tcd.checkForTor() != TorControlDialog::TOR_STATUS_OK)
|
||||||
|
{
|
||||||
|
QMessageBox::critical(NULL,QObject::tr("Tor not found!"),QObject::tr("Tor wasn't found on your system. Please install it and re-start Retroshare.")) ;
|
||||||
|
return 1 ;
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Start RetroShare */
|
/* Start RetroShare */
|
||||||
|
@ -330,9 +336,10 @@ feenableexcept(FE_INVALID | FE_DIVBYZERO);
|
||||||
if (genCert)
|
if (genCert)
|
||||||
{
|
{
|
||||||
GenCertDialog gd(false);
|
GenCertDialog gd(false);
|
||||||
if (gd.exec () == QDialog::Rejected) {
|
|
||||||
|
if (gd.exec () == QDialog::Rejected)
|
||||||
return 1;
|
return 1;
|
||||||
}
|
|
||||||
sDefaultGXSIdToCreate = gd.getGXSNickname();
|
sDefaultGXSIdToCreate = gd.getGXSNickname();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -364,6 +371,28 @@ feenableexcept(FE_INVALID | FE_DIVBYZERO);
|
||||||
|
|
||||||
SoundManager::create();
|
SoundManager::create();
|
||||||
|
|
||||||
|
#ifdef RETROTOR
|
||||||
|
// Now that we know the Tor service running, and we know the SSL id, we can make sure it provides a viable hidden service
|
||||||
|
|
||||||
|
/* Tor control manager */
|
||||||
|
|
||||||
|
tcd.show();
|
||||||
|
|
||||||
|
while(tcd.checkForHiddenService() == TorControlDialog::HIDDEN_SERVICE_STATUS_UNKNOWN) // runs until some status is reached: either tor works, or it fails.
|
||||||
|
{
|
||||||
|
QCoreApplication::processEvents();
|
||||||
|
usleep(1000) ;
|
||||||
|
}
|
||||||
|
|
||||||
|
tcd.hide();
|
||||||
|
|
||||||
|
if(tcd.checkForHiddenService() != TorControlDialog::HIDDEN_SERVICE_STATUS_OK)
|
||||||
|
{
|
||||||
|
QMessageBox::critical(NULL,QObject::tr("Cannot start a hidden tor service!"),QObject::tr("It was not possible to start a hidden service.")) ;
|
||||||
|
return 1 ;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
splashScreen.showMessage(rshare.translate("SplashScreen", "Load configuration"), Qt::AlignHCenter | Qt::AlignBottom);
|
splashScreen.showMessage(rshare.translate("SplashScreen", "Load configuration"), Qt::AlignHCenter | Qt::AlignBottom);
|
||||||
|
|
||||||
/* stop Retroshare if startup fails */
|
/* stop Retroshare if startup fails */
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue