added Tor control window

This commit is contained in:
csoler 2017-12-21 15:32:42 +01:00
parent 5ca2d5e27b
commit e87b25794f
5 changed files with 283 additions and 11 deletions

View File

@ -0,0 +1,176 @@
#include <QTimer>
#include <QFile>
#include <iostream>
#include "TorControlWindow.h"
#include "TorControl.h"
#include "HiddenService.h"
TorControlDialog::TorControlDialog(Tor::TorManager *tm,QWidget *parent)
: mTorManager(tm)
{
setupUi(this) ;
QObject::connect(tm,SIGNAL(errorChanged()),this,SLOT(showLog())) ;
QObject::connect(tm->control(),SIGNAL(statusChanged(int,int)),this,SLOT(statusChanged())) ;
QObject::connect(tm->control(),SIGNAL(connected()),this,SLOT(statusChanged()));
QObject::connect(tm->control(),SIGNAL(disconnected()),this,SLOT(statusChanged()));
QObject::connect(tm->control(),SIGNAL(bootstrapStatusChanged()),this,SLOT(statusChanged()));
QObject::connect(tm->control(),SIGNAL(connectivityChanged()),this,SLOT(statusChanged()));
QTimer::singleShot(2000,this,SLOT(checkForHiddenService())) ;
//void configurationNeededChanged();
}
void TorControlDialog::setupHiddenService()
{
QString keyData = m_settings->read("serviceKey").toString();
QString legacyDir = m_settings->read("dataDirectory").toString();
if (!keyData.isEmpty())
{
CryptoKey key;
if (!key.loadFromData(QByteArray::fromBase64(keyData.toLatin1()), CryptoKey::PrivateKey, CryptoKey::DER)) {
qWarning() << "Cannot load service key from configuration";
return;
}
m_hiddenService = new Tor::HiddenService(key, legacyDir, this);
}
else if (!legacyDir.isEmpty() && QFile::exists(legacyDir + QLatin1String("/private_key")))
{
qDebug() << "Attempting to load key from legacy filesystem format in" << legacyDir;
CryptoKey key;
if (!key.loadFromFile(legacyDir + QLatin1String("/private_key"), CryptoKey::PrivateKey)) {
qWarning() << "Cannot load legacy format key from" << legacyDir << "for conversion";
return;
} else {
keyData = QString::fromLatin1(key.encodedPrivateKey(CryptoKey::DER).toBase64());
m_settings->write("serviceKey", keyData);
m_hiddenService = new Tor::HiddenService(key, legacyDir, this);
}
}
else if (!m_settings->read("initializing").toBool())
{
qWarning() << "Missing private key for initialized identity";
return;
}
else
{
m_hiddenService = new Tor::HiddenService(legacyDir, this);
connect(m_hiddenService, &Tor::HiddenService::privateKeyChanged, this, [&]()
{
QString key = QString::fromLatin1(m_hiddenService->privateKey().encodedPrivateKey(CryptoKey::DER).toBase64());
m_settings->write("serviceKey", key);
}
);
}
Q_ASSERT(m_hiddenService);
connect(m_hiddenService, SIGNAL(statusChanged(int,int)), SLOT(onStatusChanged(int,int)));
// Generally, these are not used, and we bind to localhost and port 0
// for an automatic (and portable) selection.
QHostAddress address(m_settings->read("localListenAddress").toString());
if (address.isNull())
address = QHostAddress::LocalHost;
quint16 port = (quint16)m_settings->read("localListenPort").toInt();
m_incomingServer = new QTcpServer(this);
if (!m_incomingServer->listen(address, port)) {
// XXX error case
qWarning() << "Failed to open incoming socket:" << m_incomingServer->errorString();
return;
}
connect(m_incomingServer, &QTcpServer::newConnection, this, &UserIdentity::onIncomingConnection);
m_hiddenService->addTarget(9878, m_incomingServer->serverAddress(), m_incomingServer->serverPort());
torControl->addHiddenService(m_hiddenService);
}
void TorControlDialog::checkForHiddenService()
{
QList<Tor::HiddenService*> hidden_services = mTorManager->control()->hiddenServices();
std::cerr << "Checking for hidden services:" << std::endl;
if(hidden_services.empty())
{
setupHiddenService();
QTimer::singleShot(2000,this,SLOT(checkForHiddenService())) ;
}
}
void TorControlDialog::statusChanged()
{
int status = mTorManager->control()->status();
int torstatus = mTorManager->control()->torStatus();
QString status_str,torstatus_str ;
switch(status)
{
default:
case Tor::TorControl::Error : status_str = "Error" ; break ;
case Tor::TorControl::NotConnected: status_str = "Not connected" ; break ;
case Tor::TorControl::Connecting: status_str = "Connecting" ; break ;
case Tor::TorControl::Authenticating: status_str = "Authenticating" ; break ;
case Tor::TorControl::Connected: status_str = "Connected" ; break ;
}
switch(torstatus)
{
default:
case Tor::TorControl::TorUnknown: torstatus_str = "Unknown" ; break ;
case Tor::TorControl::TorOffline: torstatus_str = "Tor offline" ; break ;
case Tor::TorControl::TorReady: torstatus_str = "Tor ready" ; break ;
}
torStatus_LB->setText(torstatus_str + "(" + status_str + ")") ;
QVariantMap qvm = mTorManager->control()->bootstrapStatus();
QString bootstrapstatus_str ;
for(auto it(qvm.begin());it!=qvm.end();++it)
bootstrapstatus_str += it.key() + ":" + it.value().toString();
torBootstrapStatus_LB->setText(bootstrapstatus_str) ;
QList<Tor::HiddenService*> hidden_services = mTorManager->control()->hiddenServices();
if(hidden_services.empty())
hiddenService_LB->setText(QString("None")) ;
else
{
QString hiddenservices_str ;
for(auto it(hidden_services.begin());it!=hidden_services.end();++it)
{
hiddenservices_str += (*it)->hostname();
for(auto it2((*it)->targets().begin());it2!=(*it)->targets().end();++it2)
hiddenservices_str += QString::number((*it2).servicePort) + ":" + (*it2).targetAddress.toString() + ":" + QString::number((*it2).targetPort) + " " ;
}
hiddenService_LB->setText(hiddenservices_str) ;
}
showLog();
}
void TorControlDialog::showLog()
{
QString s ;
QStringList logmsgs = mTorManager->logMessages() ;
for(QStringList::const_iterator it(logmsgs.begin());it!=logmsgs.end();++it)
s += *it + "\n" ;
torLog_TB->setText(s) ;
QCoreApplication::processEvents() ;
}

View File

@ -0,0 +1,20 @@
#include "ui_TorControlWindow.h"
#include "TorManager.h"
class TorControlDialog: public QDialog, public Ui::TorControlDialog
{
Q_OBJECT
public:
TorControlDialog(Tor::TorManager *tm,QWidget *parent =NULL);
protected slots:
void showLog();
void statusChanged();
void checkForHiddenService();
private:
void setupHiddenService();
Tor::TorManager *mTorManager ;
};

View File

@ -0,0 +1,70 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>TorControlDialog</class>
<widget class="QDialog" name="TorControlDialog">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>739</width>
<height>489</height>
</rect>
</property>
<property name="windowTitle">
<string>Dialog</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<layout class="QGridLayout" name="gridLayout">
<item row="2" column="1">
<widget class="QLabel" name="hiddenService_LB">
<property name="text">
<string>TextLabel</string>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="label_2">
<property name="text">
<string>Tor bootstrap status:</string>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QLabel" name="torBootstrapStatus_LB">
<property name="text">
<string>TextLabel</string>
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QLabel" name="label_3">
<property name="text">
<string>Hidden service:</string>
</property>
</widget>
</item>
<item row="0" column="0">
<widget class="QLabel" name="label">
<property name="text">
<string>Tor status:</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QLabel" name="torStatus_LB">
<property name="text">
<string>TextLabel</string>
</property>
</widget>
</item>
</layout>
</item>
<item>
<widget class="QTextBrowser" name="torLog_TB"/>
</item>
</layout>
</widget>
<resources/>
<connections/>
</ui>

View File

@ -48,6 +48,7 @@
#ifdef RETROTOR
#include "TorControl/TorManager.h"
#include "TorControl/TorControlWindow.h"
#endif
#include "retroshare/rsidentity.h"
@ -284,19 +285,20 @@ feenableexcept(FE_INVALID | FE_DIVBYZERO);
// Start the Tor engine, and make sure it provides a viable hidden service
/* Tor control manager */
Tor::TorManager *torManager = Tor::TorManager::instance();
torManager->setDataDirectory(Rshare::dataDirectory() + QString("/tor/"));
//torManager->setDataDirectory(QString("./tor"));//settings->filePath()).path() + QString("/tor/"));
Tor::TorManager *torManager = Tor::TorManager::instance();
torManager->setDataDirectory(Rshare::dataDirectory() + QString("/tor/"));
//torManager->setDataDirectory(QString("./tor"));//settings->filePath()).path() + QString("/tor/"));
Tor::TorControl *torControl = torManager->control();
torManager->start();
torManager->start();
while(torManager->configurationNeeded())
{
usleep(1000*1000) ;
// we should display some configuration window here!
}
TorControlDialog tcd(torManager) ;
tcd.exec();
// tcd.show() ;
//
// while(true)
// {
// QCoreApplication::processEvents();
// }
#endif
/* Start RetroShare */

View File

@ -22,6 +22,10 @@ profiling {
retrotor {
DEFINES *= RETROTOR
FORMS += TorControl/TorControlWindow.ui
SOURCES += TorControl/TorControlWindow.cpp
HEADERS += TorControl/TorControlWindow.h
}
#QMAKE_CFLAGS += -fmudflap