added basic hidden service creation. Untested.

This commit is contained in:
csoler 2017-12-25 22:59:42 +01:00
parent f5ce711ad6
commit 659367ca96
6 changed files with 145 additions and 100 deletions

View File

@ -78,6 +78,7 @@ public:
TorReady TorReady
}; };
explicit TorControl(QObject *parent = 0); explicit TorControl(QObject *parent = 0);
/* Information */ /* Information */

View File

@ -37,96 +37,6 @@ void TorControlDialog::onIncomingConnection()
std::cerr << "Incoming connection !!" << std::endl; std::cerr << "Incoming connection !!" << std::endl;
} }
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;
}
mHiddenService = 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);
mHiddenService = new Tor::HiddenService(key, legacyDir, this);
}
}
else if (!m_settings->read("initializing").toBool())
{
qWarning() << "Missing private key for initialized identity";
return;
}
else
{
mHiddenService = new Tor::HiddenService(legacyDir, this);
connect(mHiddenService, &Tor::HiddenService::privateKeyChanged, this, [&]()
{
QString key = QString::fromLatin1(mHiddenService->privateKey().encodedPrivateKey(CryptoKey::DER).toBase64());
m_settings->write("serviceKey", key);
}
);
}
Q_ASSERT(mHiddenService);
connect(mHiddenService, 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();
if (!mIncomingServer->listen(address, port))
{
// XXX error case
qWarning() << "Failed to open incoming socket:" << mIncomingServer->errorString();
return;
}
mHiddenService->addTarget(9878, mIncomingServer->serverAddress(), mIncomingServer->serverPort());
torControl->addHiddenService(mHiddenService);
*/
}
// 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() void TorControlDialog::statusChanged()
{ {
int status = mTorManager->control()->status(); int status = mTorManager->control()->status();
@ -210,9 +120,32 @@ TorControlDialog::TorStatus TorControlDialog::checkForTor()
TorControlDialog::HiddenServiceStatus TorControlDialog::checkForHiddenService() TorControlDialog::HiddenServiceStatus TorControlDialog::checkForHiddenService()
{ {
return HIDDEN_SERVICE_STATUS_UNKNOWN ; std::cerr << "Checking for hidden services:" << std::endl;
switch(mHiddenServiceStatus)
{
case HIDDEN_SERVICE_STATUS_UNKNOWN: {
if(!mTorManager->setupHiddenService())
{
mHiddenServiceStatus = HIDDEN_SERVICE_STATUS_FAIL ;
return mHiddenServiceStatus ;
}
mHiddenServiceStatus = HIDDEN_SERVICE_STATUS_REQUESTED ;
break ;
}
case HIDDEN_SERVICE_STATUS_REQUESTED: {
QList<Tor::HiddenService*> hidden_services = mTorManager->control()->hiddenServices();
if(mHiddenService == NULL)
mHiddenService = *(hidden_services.begin()) ;
}
case HIDDEN_SERVICE_STATUS_OK : break;
default: break ;
}
return mHiddenServiceStatus ;
} }

View File

@ -21,9 +21,10 @@ public:
}; };
enum HiddenServiceStatus { enum HiddenServiceStatus {
HIDDEN_SERVICE_STATUS_UNKNOWN = 0x00, HIDDEN_SERVICE_STATUS_UNKNOWN = 0x00, // no information known.
HIDDEN_SERVICE_STATUS_OK = 0x01, HIDDEN_SERVICE_STATUS_FAIL = 0x01, // some error occurred
HIDDEN_SERVICE_STATUS_FAIL = 0x02 HIDDEN_SERVICE_STATUS_REQUESTED = 0x02, // one service at least has been requested. Still being tested.
HIDDEN_SERVICE_STATUS_OK = 0x03 // one service responds and has been tested
}; };
// Should be called multiple times in a loop until it returns something else than *_UNKNOWN // Should be called multiple times in a loop until it returns something else than *_UNKNOWN
@ -34,11 +35,10 @@ public:
protected slots: protected slots:
void showLog(); void showLog();
void statusChanged(); void statusChanged();
// void checkForHiddenService();
void onIncomingConnection(); void onIncomingConnection();
private: private:
void setupHiddenService(); HiddenServiceStatus mHiddenServiceStatus ;
Tor::TorManager *mTorManager ; Tor::TorManager *mTorManager ;
Tor::HiddenService *mHiddenService ; Tor::HiddenService *mHiddenService ;

View File

@ -35,11 +35,15 @@
#include "TorManager.h" #include "TorManager.h"
#include "TorProcess.h" #include "TorProcess.h"
#include "TorControl.h" #include "TorControl.h"
#include "CryptoKey.h"
#include "HiddenService.h"
#include "GetConfCommand.h" #include "GetConfCommand.h"
#include "Settings.h" #include "Settings.h"
#include <QFile> #include <QFile>
#include <QDir> #include <QDir>
#include <QCoreApplication> #include <QCoreApplication>
#include <QTcpServer>
#include <QTextStream>
using namespace Tor; using namespace Tor;
@ -55,10 +59,13 @@ public:
TorProcess *process; TorProcess *process;
TorControl *control; TorControl *control;
QString dataDir; QString dataDir;
QString hiddenServiceDir;
QStringList logMessages; QStringList logMessages;
QString errorMessage; QString errorMessage;
bool configNeeded; bool configNeeded;
HiddenService *hiddenService ;
explicit TorManagerPrivate(TorManager *parent = 0); explicit TorManagerPrivate(TorManager *parent = 0);
QString torExecutablePath() const; QString torExecutablePath() const;
@ -123,6 +130,100 @@ void TorManager::setDataDirectory(const QString &path)
d->dataDir.append(QLatin1Char('/')); d->dataDir.append(QLatin1Char('/'));
} }
QString TorManager::hiddenServiceDirectory() const
{
return d->hiddenServiceDir;
}
void TorManager::setHiddenServiceDirectory(const QString &path)
{
d->hiddenServiceDir = QDir::fromNativeSeparators(path);
if (!d->hiddenServiceDir.isEmpty() && !d->hiddenServiceDir.endsWith(QLatin1Char('/')))
d->hiddenServiceDir.append(QLatin1Char('/'));
}
bool TorManager::setupHiddenService()
{
QString keyData ;//= m_settings->read("serviceKey").toString();
QString legacyDir = d->hiddenServiceDir;
// if (!keyData.isEmpty())
// {
// CryptoKey key;
// if (!key.loadFromData(QByteArray::fromBase64(keyData.toLatin1()), CryptoKey::PrivateKey, CryptoKey::DER))
// {
// qWarning() << "Cannot load service key from configuration";
// return;
// }
//
// mHiddenService = 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 false;
}
else
{
keyData = QString::fromLatin1(key.encodedPrivateKey(CryptoKey::DER).toBase64());
d->hiddenService = new Tor::HiddenService(key, legacyDir, this);
}
}
// else if (!m_settings->read("initializing").toBool())
// {
// qWarning() << "Missing private key for initialized identity";
// return;
// }
else
{
d->hiddenService = new Tor::HiddenService(legacyDir, this);
connect(d->hiddenService, SIGNAL(Tor::HiddenService::privateKeyChanged), this, SLOT(hiddenServicePrivateKeyChanged())) ;
}
Q_ASSERT(d->hiddenService);
connect(d->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 = QHostAddress::LocalHost; // we only listen from localhost
quint16 port = 7934;//(quint16)m_settings->read("localListenPort").toInt();
if (!QTcpServer().listen(address, port))
{
// XXX error case
qWarning() << "Failed to open incoming socket on port :" << port;
return false;
}
//d->hiddenService->addTarget(9878, mIncomingServer->serverAddress(), mIncomingServer->serverPort());
d->hiddenService->addTarget(9878, QHostAddress::LocalHost,7934);
torControl->addHiddenService(d->hiddenService);
return true ;
}
void TorManager::hiddenServicePrivateKeyChanged()
{
QString key = QString::fromLatin1(d->hiddenService->privateKey().encodedPrivateKey(CryptoKey::DER).toBase64());
QFile outfile(d->hiddenServiceDir + QLatin1String("/private_key")) ;
outfile.open( QIODevice::WriteOnly | QIODevice::Text );
QTextStream s(&outfile);
s << key ;
outfile.close();
}
bool TorManager::configurationNeeded() const bool TorManager::configurationNeeded() const
{ {
return d->configNeeded; return d->configNeeded;

View File

@ -60,6 +60,7 @@ class TorManager : public QObject
Q_PROPERTY(QString dataDirectory READ dataDirectory WRITE setDataDirectory) Q_PROPERTY(QString dataDirectory READ dataDirectory WRITE setDataDirectory)
public: public:
explicit TorManager(QObject *parent = 0); explicit TorManager(QObject *parent = 0);
static TorManager *instance(); static TorManager *instance();
@ -69,6 +70,12 @@ public:
QString dataDirectory() const; QString dataDirectory() const;
void setDataDirectory(const QString &path); void setDataDirectory(const QString &path);
QString hiddenServiceDirectory() const;
void setHiddenServiceDirectory(const QString &path);
// Starts a hidden service, loading it from the config directory that has been set earlier.
bool setupHiddenService() ;
// True on first run or when the Tor configuration wizard needs to be shown // True on first run or when the Tor configuration wizard needs to be shown
bool configurationNeeded() const; bool configurationNeeded() const;
@ -80,6 +87,9 @@ public:
public slots: public slots:
void start(); void start();
private slots:
void hiddenServicePrivateKeyChanged();
signals: signals:
void configurationNeededChanged(); void configurationNeededChanged();
void errorChanged(); void errorChanged();

View File

@ -379,7 +379,7 @@ feenableexcept(FE_INVALID | FE_DIVBYZERO);
// Now that we know the Tor service running, and we know the SSL id, we can make sure it provides a viable hidden service // Now that we know the Tor service running, and we know the SSL id, we can make sure it provides a viable hidden service
{ {
torManager->setDataDirectory(Rshare::dataDirectory() + QString("/tor/")); // re-set it, because now it's changed to the specific location that is run torManager->setDataDirectory(Rshare::dataDirectory() + QString("/hidden_service/")); // re-set it, because now it's changed to the specific location that is run
TorControlDialog tcd(torManager) ; TorControlDialog tcd(torManager) ;
tcd.show(); tcd.show();