removed lots of signals/slots

This commit is contained in:
csoler 2021-12-05 22:14:19 +01:00
parent bb37e2692b
commit e75d312724
20 changed files with 401 additions and 335 deletions

View file

@ -10,6 +10,21 @@ RsTcpSocket::RsTcpSocket(const std::string& tcp_address,uint16_t tcp_port)
:RsFdBinInterface(0),mState(DISCONNECTED),mConnectAddress(tcp_address),mConnectPort(tcp_port),mSocket(0) :RsFdBinInterface(0),mState(DISCONNECTED),mConnectAddress(tcp_address),mConnectPort(tcp_port),mSocket(0)
{ {
} }
RsTcpSocket::RsTcpSocket()
:RsFdBinInterface(0),mState(DISCONNECTED),mConnectAddress("0.0.0.0"),mConnectPort(0),mSocket(0)
{
}
int RsTcpSocket::connect(const std::string& tcp_address,uint16_t tcp_port)
{
close();
mConnectPort = tcp_port;
mConnectAddress = tcp_address;
return connect();
}
int RsTcpSocket::connect() int RsTcpSocket::connect()
{ {
int CreateSocket = 0; int CreateSocket = 0;
@ -42,6 +57,7 @@ int RsTcpSocket::connect()
int RsTcpSocket::close() int RsTcpSocket::close()
{ {
RsFdBinInterface::close(); RsFdBinInterface::close();
mState = DISCONNECTED;
return !::close(mSocket); return !::close(mSocket);
} }
@ -50,7 +66,9 @@ RsThreadedTcpSocket::RsThreadedTcpSocket(const std::string& tcp_address,uint16_t
: RsTcpSocket(tcp_address,tcp_port) : RsTcpSocket(tcp_address,tcp_port)
{ {
} }
RsThreadedTcpSocket::RsThreadedTcpSocket() : RsTcpSocket()
{
}
void RsThreadedTcpSocket::run() void RsThreadedTcpSocket::run()
{ {
if(!connect()) if(!connect())

View file

@ -6,6 +6,8 @@ class RsTcpSocket: public RsFdBinInterface
{ {
public: public:
RsTcpSocket(const std::string& tcp_address,uint16_t tcp_port); RsTcpSocket(const std::string& tcp_address,uint16_t tcp_port);
RsTcpSocket();
virtual ~RsTcpSocket();
enum State: uint8_t { enum State: uint8_t {
UNKNOWN = 0x00, UNKNOWN = 0x00,
@ -16,6 +18,8 @@ public:
// Return 1 when OK, 0 otherwise. // Return 1 when OK, 0 otherwise.
int connect(); int connect();
int connect(const std::string& tcp_address,uint16_t tcp_port);
// Returns 1 when OK, 0 otherwise. // Returns 1 when OK, 0 otherwise.
int close(); int close();
@ -34,6 +38,7 @@ class RsThreadedTcpSocket: public RsTcpSocket, public RsThread
{ {
public: public:
RsThreadedTcpSocket(const std::string& tcp_address,uint16_t tcp_port); RsThreadedTcpSocket(const std::string& tcp_address,uint16_t tcp_port);
RsThreadedTcpSocket();
virtual ~RsThreadedTcpSocket(); virtual ~RsThreadedTcpSocket();
virtual void run() override; virtual void run() override;

View file

@ -108,9 +108,9 @@ void AddOnionCommand::onFinished(int statusCode)
{ {
TorControlCommand::onFinished(statusCode); TorControlCommand::onFinished(statusCode);
if (isSuccessful()) if (isSuccessful())
emit succeeded(); mSucceeded();
else else
emit failed(statusCode); mFailed(statusCode);
} }

View file

@ -34,9 +34,6 @@
#define ADDONIONCOMMAND_H #define ADDONIONCOMMAND_H
#include "TorControlCommand.h" #include "TorControlCommand.h"
#include <QList>
#include <QPair>
#include <QVariant>
namespace Tor namespace Tor
{ {
@ -45,11 +42,8 @@ class HiddenService;
class AddOnionCommand : public TorControlCommand class AddOnionCommand : public TorControlCommand
{ {
Q_OBJECT // Q_PROPERTY(std::string errorMessage READ errorMessage CONSTANT)
Q_DISABLE_COPY(AddOnionCommand) // Q_PROPERTY(bool successful READ isSuccessful CONSTANT)
Q_PROPERTY(std::string errorMessage READ errorMessage CONSTANT)
Q_PROPERTY(bool successful READ isSuccessful CONSTANT)
public: public:
AddOnionCommand(HiddenService *service); AddOnionCommand(HiddenService *service);
@ -59,14 +53,17 @@ public:
std::string errorMessage() const { return m_errorMessage; } std::string errorMessage() const { return m_errorMessage; }
bool isSuccessful() const; bool isSuccessful() const;
signals: // signals:
void succeeded(); void set_succeeded_callback(const std::function<void(void)>& f) { mSucceeded=f;}
void failed(int code); void set_failed_callback(const std::function<void(int)>& f) { mFailed=f;}
protected: protected:
HiddenService *m_service; HiddenService *m_service;
std::string m_errorMessage; std::string m_errorMessage;
std::function<void(void)> mSucceeded;
std::function<void(int)> mFailed;
virtual void onReply(int statusCode, const ByteArray &data); virtual void onReply(int statusCode, const ByteArray &data);
virtual void onFinished(int statusCode); virtual void onFinished(int statusCode);
}; };

View file

@ -30,8 +30,7 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/ */
#ifndef AUTHENTICATECOMMAND_H #pragma once
#define AUTHENTICATECOMMAND_H
#include "bytearray.h" #include "bytearray.h"
#include "TorControlCommand.h" #include "TorControlCommand.h"
@ -41,8 +40,6 @@ namespace Tor
class AuthenticateCommand : public TorControlCommand class AuthenticateCommand : public TorControlCommand
{ {
Q_OBJECT
public: public:
AuthenticateCommand(); AuthenticateCommand();
@ -60,5 +57,3 @@ private:
}; };
} }
#endif // AUTHENTICATECOMMAND_H

View file

@ -33,19 +33,15 @@
#ifndef GETCONFCOMMAND_H #ifndef GETCONFCOMMAND_H
#define GETCONFCOMMAND_H #define GETCONFCOMMAND_H
#include <map>
#include "TorControlCommand.h" #include "TorControlCommand.h"
#include <QList>
#include <QVariantMap>
namespace Tor namespace Tor
{ {
class GetConfCommand : public TorControlCommand class GetConfCommand : public TorControlCommand
{ {
Q_OBJECT // Q_PROPERTY(QVariantMap results READ results CONSTANT)
Q_DISABLE_COPY(GetConfCommand)
Q_PROPERTY(QVariantMap results READ results CONSTANT)
public: public:
enum Type { enum Type {

View file

@ -30,10 +30,10 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/ */
#ifndef PROTOCOLINFOCOMMAND_H #pragma once
#define PROTOCOLINFOCOMMAND_H
#include "TorControlCommand.h" #include "TorControlCommand.h"
#include "retroshare/rsflags.h"
namespace Tor namespace Tor
{ {
@ -42,23 +42,22 @@ class TorControl;
class ProtocolInfoCommand : public TorControlCommand class ProtocolInfoCommand : public TorControlCommand
{ {
Q_OBJECT
Q_DISABLE_COPY(ProtocolInfoCommand)
public: public:
enum AuthMethod enum
{ {
AuthUnknown = 0, AuthUnknown = 0x0,
AuthNull = 0x1, AuthNull = 0x1,
AuthHashedPassword = 0x2, AuthHashedPassword = 0x2,
AuthCookie = 0x4 AuthCookie = 0x4
}; };
Q_DECLARE_FLAGS(AuthMethods, AuthMethod) typedef uint8_t AuthMethod;
// RS_REGISTER_FLAGS_TYPE(AuthMethod); // not usable here because we're inside a class (and worse, inside a namespace)
ProtocolInfoCommand(TorControl *manager); ProtocolInfoCommand(TorControl *manager);
ByteArray build(); ByteArray build();
AuthMethods authMethods() const { return m_authMethods; } AuthMethod authMethods() const { return m_authMethods; }
std::string torVersion() const { return m_torVersion; } std::string torVersion() const { return m_torVersion; }
std::string cookieFile() const { return m_cookieFile; } std::string cookieFile() const { return m_cookieFile; }
@ -67,11 +66,9 @@ protected:
private: private:
TorControl *manager; TorControl *manager;
AuthMethods m_authMethods; AuthMethod m_authMethods;
std::string m_torVersion; std::string m_torVersion;
std::string m_cookieFile; std::string m_cookieFile;
}; };
} }
#endif // PROTOCOLINFOCOMMAND_H

View file

@ -105,8 +105,8 @@ void SetConfCommand::onFinished(int statusCode)
{ {
TorControlCommand::onFinished(statusCode); TorControlCommand::onFinished(statusCode);
if (isSuccessful()) if (isSuccessful())
emit setConfSucceeded(); mConfSucceeded();
else else
emit setConfFailed(statusCode); mConfFailed(statusCode);
} }

View file

@ -30,24 +30,18 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/ */
#ifndef SETCONFCOMMAND_H #pragma once
#define SETCONFCOMMAND_H
#include <functional>
#include "TorControlCommand.h" #include "TorControlCommand.h"
#include <QList>
#include <QPair>
#include <QVariant>
namespace Tor namespace Tor
{ {
class SetConfCommand : public TorControlCommand class SetConfCommand : public TorControlCommand
{ {
Q_OBJECT //Q_PROPERTY(QString errorMessage READ errorMessage CONSTANT)
Q_DISABLE_COPY(SetConfCommand) //Q_PROPERTY(bool successful READ isSuccessful CONSTANT)
Q_PROPERTY(QString errorMessage READ errorMessage CONSTANT)
Q_PROPERTY(bool successful READ isSuccessful CONSTANT)
public: public:
SetConfCommand(); SetConfCommand();
@ -60,18 +54,19 @@ public:
std::string errorMessage() const { return m_errorMessage; } std::string errorMessage() const { return m_errorMessage; }
bool isSuccessful() const; bool isSuccessful() const;
signals: //signals:
void setConfSucceeded(); void set_ConfSucceeded_callback(const std::function<void(void)>& f) { mConfSucceeded=f; }
void setConfFailed(int code); void set_ConfFailed_callback (const std::function<void(int code)>& f){ mConfFailed=f; }
protected: protected:
std::string m_errorMessage; std::string m_errorMessage;
bool m_resetMode; bool m_resetMode;
std::function<void(void)> mConfSucceeded;
std::function<void(int code)> mConfFailed;
virtual void onReply(int statusCode, const ByteArray &data); virtual void onReply(int statusCode, const ByteArray &data);
virtual void onFinished(int statusCode); virtual void onFinished(int statusCode);
}; };
} }
#endif // SETCONFCOMMAND_H

View file

@ -45,14 +45,6 @@
#include "AddOnionCommand.h" #include "AddOnionCommand.h"
#include "StrUtil.h" #include "StrUtil.h"
#include "PendingOperation.h" #include "PendingOperation.h"
#include <QHostAddress>
#include <QDir>
#include <QNetworkProxy>
//#include <QQmlEngine>
#include <QTimer>
#include <QSaveFile>
#include <QRegularExpression>
#include <QDebug>
Tor::TorControl *torControl = 0; Tor::TorControl *torControl = 0;
@ -75,71 +67,72 @@ using namespace Tor;
namespace Tor { namespace Tor {
class TorControlPrivate : public QObject // class TorControlPrivate : public QObject
{ // {
Q_OBJECT // Q_OBJECT
//
public: // public:
TorControl *q; // TorControl *q;
//
TorControlSocket *socket; // TorControlSocket *socket;
std::string torAddress; // std::string torAddress;
std::string errorMessage; // std::string errorMessage;
std::string torVersion; // std::string torVersion;
ByteArray authPassword; // ByteArray authPassword;
std::string socksAddress; // std::string socksAddress;
QList<HiddenService*> services; // QList<HiddenService*> services;
quint16 controlPort, socksPort; // quint16 controlPort, socksPort;
TorControl::Status status; // TorControl::Status status;
TorControl::TorStatus torStatus; // TorControl::TorStatus torStatus;
std::map<std::string,std::string> bootstrapStatus; // std::map<std::string,std::string> bootstrapStatus;
bool hasOwnership; // bool hasOwnership;
//
TorControlPrivate(TorControl *parent); // TorControlPrivate(TorControl *parent);
//
void setStatus(TorControl::Status status); // void setStatus(TorControl::Status status);
void setTorStatus(TorControl::TorStatus status); // void setTorStatus(TorControl::TorStatus status);
//
void getTorInfo(); // void getTorInfo();
void publishServices(); // void publishServices();
//
public slots: // public slots:
void socketConnected(); // void socketConnected();
void socketDisconnected(); // void socketDisconnected();
void socketError(); // void socketError();
//
void authenticateReply(); // void authenticateReply();
void protocolInfoReply(); // void protocolInfoReply();
void getTorInfoReply(); // void getTorInfoReply();
void setError(const std::string &message); // void setError(const std::string &message);
//
void statusEvent(int code, const ByteArray &data); // void statusEvent(int code, const ByteArray &data);
void updateBootstrap(const std::list<ByteArray> &data); // void updateBootstrap(const std::list<ByteArray> &data);
}; // };
} }
TorControl::TorControl(QObject *parent) TorControl::TorControl()
: QObject(parent), d(new TorControlPrivate(this))
{ {
mSocket = new TorControlSocket(this);
} }
TorControlPrivate::TorControlPrivate(TorControl *parent) // TorControlPrivate::TorControlPrivate(TorControl *parent)
: QObject(parent), q(parent), controlPort(0), socksPort(0), // : QObject(parent), q(parent), controlPort(0), socksPort(0),
status(TorControl::NotConnected), torStatus(TorControl::TorUnknown), // status(TorControl::NotConnected), torStatus(TorControl::TorUnknown),
hasOwnership(false) // hasOwnership(false)
{ // {
socket = new TorControlSocket(this); // socket = new TorControlSocket();
QObject::connect(socket, SIGNAL(connected()), this, SLOT(socketConnected())); //
QObject::connect(socket, SIGNAL(disconnected()), this, SLOT(socketDisconnected())); // // QObject::connect(socket, SIGNAL(connected()), this, SLOT(socketConnected()));
QObject::connect(socket, SIGNAL(error(QAbstractSocket::SocketError)), this, SLOT(socketError())); // // QObject::connect(socket, SIGNAL(disconnected()), this, SLOT(socketDisconnected()));
QObject::connect(socket, SIGNAL(error(QString)), this, SLOT(setError(QString))); // // QObject::connect(socket, SIGNAL(error(QAbstractSocket::SocketError)), this, SLOT(socketError()));
} // // QObject::connect(socket, SIGNAL(error(QString)), this, SLOT(setError(QString)));
// }
QNetworkProxy TorControl::connectionProxy() // QNetworkProxy TorControl::connectionProxy()
{ // {
return QNetworkProxy(QNetworkProxy::Socks5Proxy, d->socksAddress.toString(), d->socksPort); // return QNetworkProxy(QNetworkProxy::Socks5Proxy, d->socksAddress.toString(), d->socksPort);
} // }
static RsTorConnectivityStatus torConnectivityStatus(Tor::TorControl::Status t) static RsTorConnectivityStatus torConnectivityStatus(Tor::TorControl::Status t)
{ {
@ -164,46 +157,46 @@ static RsTorStatus torStatus(Tor::TorControl::TorStatus t)
} }
} }
void TorControlPrivate::setStatus(TorControl::Status n) void TorControl::setStatus(TorControl::Status n)
{ {
if (n == status) if (n == mStatus)
return; return;
TorControl::Status old = status; TorControl::Status old = mStatus;
status = n; mStatus = n;
if (old == TorControl::Error) if (old == TorControl::Error)
errorMessage.clear(); mErrorMessage.clear();
if(rsEvents) if(rsEvents)
{ {
auto ev = std::make_shared<RsTorManagerEvent>(); auto ev = std::make_shared<RsTorManagerEvent>();
ev->mTorManagerEventType = RsTorManagerEventCode::TOR_STATUS_CHANGED; ev->mTorManagerEventType = RsTorManagerEventCode::TOR_STATUS_CHANGED;
ev->mTorConnectivityStatus = torConnectivityStatus(status); ev->mTorConnectivityStatus = torConnectivityStatus(mStatus);
rsEvents->sendEvent(ev); rsEvents->sendEvent(ev);
} }
#ifdef TO_REMOVE #ifdef TO_REMOVE
emit q->statusChanged(status, old); emit statusChanged(status, old);
if (status == TorControl::Connected && old < TorControl::Connected) if (status == TorControl::Connected && old < TorControl::Connected)
emit q->connected(); emit connected();
else if (status < TorControl::Connected && old >= TorControl::Connected) else if (status < TorControl::Connected && old >= TorControl::Connected)
emit q->disconnected(); emit disconnected();
#endif #endif
} }
void TorControlPrivate::setTorStatus(TorControl::TorStatus n) void TorControl::setTorStatus(TorControl::TorStatus n)
{ {
if (n == torStatus) if (n == mTorStatus)
return; return;
TorControl::TorStatus old = torStatus; TorControl::TorStatus old = mTorStatus;
torStatus = n; mTorStatus = n;
#ifdef TO_REMOVE #ifdef TO_REMOVE
emit q->torStatusChanged(torStatus, old); emit torStatusChanged(torStatus, old);
emit q->connectivityChanged(); emit connectivityChanged();
#endif #endif
if(rsEvents) if(rsEvents)
@ -211,75 +204,75 @@ void TorControlPrivate::setTorStatus(TorControl::TorStatus n)
auto ev = std::make_shared<RsTorManagerEvent>(); auto ev = std::make_shared<RsTorManagerEvent>();
ev->mTorManagerEventType = RsTorManagerEventCode::TOR_STATUS_CHANGED; ev->mTorManagerEventType = RsTorManagerEventCode::TOR_STATUS_CHANGED;
ev->mTorStatus = ::torStatus(torStatus); ev->mTorStatus = ::torStatus(mTorStatus);
rsEvents->sendEvent(ev); rsEvents->sendEvent(ev);
} }
if (torStatus == TorControl::TorReady && socksAddress.isNull()) { if (mTorStatus == TorControl::TorReady && mSocksAddress.empty()) {
// Request info again to read the SOCKS port // Request info again to read the SOCKS port
getTorInfo(); getTorInfo();
} }
} }
void TorControlPrivate::setError(const std::string &message) void TorControl::setError(const std::string &message)
{ {
errorMessage = message; mErrorMessage = message;
setStatus(TorControl::Error); setStatus(TorControl::Error);
RsWarn() << "torctrl: Error:" << errorMessage; RsWarn() << "torctrl: Error:" << mErrorMessage;
socket->abort(); mSocket->fullstop();
QTimer::singleShot(15000, q, SLOT(reconnect())); reconnect();
} }
TorControl::Status TorControl::status() const TorControl::Status TorControl::status() const
{ {
return d->status; return mStatus;
} }
TorControl::TorStatus TorControl::torStatus() const TorControl::TorStatus TorControl::torStatus() const
{ {
return d->torStatus; return mTorStatus;
} }
std::string TorControl::torVersion() const std::string TorControl::torVersion() const
{ {
return d->torVersion; return mTorVersion;
} }
std::string TorControl::errorMessage() const std::string TorControl::errorMessage() const
{ {
return d->errorMessage; return mErrorMessage;
} }
bool TorControl::hasConnectivity() const bool TorControl::hasConnectivity() const
{ {
return torStatus() == TorReady && !d->socksAddress.isNull(); return torStatus() == TorReady && !mSocksAddress.empty();
} }
QHostAddress TorControl::socksAddress() const std::string TorControl::socksAddress() const
{ {
return d->socksAddress; return mSocksAddress;
} }
quint16 TorControl::socksPort() const quint16 TorControl::socksPort() const
{ {
return d->socksPort; return mSocksPort;
} }
QList<HiddenService*> TorControl::hiddenServices() const std::list<HiddenService*> TorControl::hiddenServices() const
{ {
return d->services; return mServices;
} }
std::map<std::string,std::string> TorControl::bootstrapStatus() const std::map<std::string,std::string> TorControl::bootstrapStatus() const
{ {
return d->bootstrapStatus; return mBootstrapStatus;
} }
void TorControl::setAuthPassword(const ByteArray &password) void TorControl::setAuthPassword(const ByteArray &password)
{ {
d->authPassword = password; mAuthPassword = password;
} }
void TorControl::connect(const std::string &address, quint16 port) void TorControl::connect(const std::string &address, quint16 port)
@ -290,34 +283,34 @@ void TorControl::connect(const std::string &address, quint16 port)
return; return;
} }
d->torAddress = address; mTorAddress = address;
d->controlPort = port; mControlPort = port;
d->setTorStatus(TorUnknown); setTorStatus(TorUnknown);
//bool b = d->socket->blockSignals(true); //bool b = d->socket->blockSignals(true);
d->socket->fullstop(); mSocket->fullstop();
//d->socket->blockSignals(b); //d->socket->blockSignals(b);
d->setStatus(Connecting); setStatus(Connecting);
d->socket->connectToHost(address, port); mSocket->connectToHost(address, port);
} }
void TorControl::reconnect() void TorControl::reconnect()
{ {
assert(!d->torAddress.empty() && d->controlPort); assert(!mTorAddress.empty() && mControlPort);
if (d->torAddress.empty() || !d->controlPort || status() >= Connecting) if (mTorAddress.empty() || !mControlPort || status() >= Connecting)
return; return;
d->setStatus(Connecting); setStatus(Connecting);
d->socket->connectToHost(d->torAddress, d->controlPort); mSocket->connectToHost(mTorAddress, mControlPort);
} }
void TorControlPrivate::authenticateReply() void TorControl::authenticateReply()
{ {
AuthenticateCommand *command = qobject_cast<AuthenticateCommand*>(sender()); AuthenticateCommand *command = qobject_cast<AuthenticateCommand*>(sender());
Q_ASSERT(command); assert(command);
Q_ASSERT(status == TorControl::Authenticating); assert(mStatus == TorControl::Authenticating);
if (!command) if (!command)
return; return;
@ -332,63 +325,69 @@ void TorControlPrivate::authenticateReply()
setTorStatus(TorControl::TorUnknown); setTorStatus(TorControl::TorUnknown);
TorControlCommand *clientEvents = new TorControlCommand; TorControlCommand *clientEvents = new TorControlCommand;
connect(clientEvents, &TorControlCommand::replyLine, this, &TorControlPrivate::statusEvent); clientEvents->set_replyLine_callback([this](int code, const ByteArray &data)
socket->registerEvent(ByteArray("STATUS_CLIENT"), clientEvents); {
statusEvent(code,data); // no async needed here.
});
mSocket->registerEvent(ByteArray("STATUS_CLIENT"), clientEvents);
getTorInfo(); getTorInfo();
publishServices(); publishServices();
// XXX Fix old configurations that would store unwanted options in torrc. // XXX Fix old configurations that would store unwanted options in torrc.
// This can be removed some suitable amount of time after 1.0.4. // This can be removed some suitable amount of time after 1.0.4.
if (hasOwnership) if (mHasOwnership)
q->saveConfiguration(); saveConfiguration();
} }
void TorControlPrivate::socketConnected() void TorControl::socketConnected()
{ {
Q_ASSERT(status == TorControl::Connecting); assert(mStatus == TorControl::Connecting);
torCtrlDebug() << "torctrl: Connected socket; querying information" << std::endl; torCtrlDebug() << "torctrl: Connected socket; querying information" << std::endl;
setStatus(TorControl::Authenticating); setStatus(TorControl::Authenticating);
ProtocolInfoCommand *command = new ProtocolInfoCommand(q); ProtocolInfoCommand *command = new ProtocolInfoCommand(this);
connect(command, &TorControlCommand::finished, this, &TorControlPrivate::protocolInfoReply);
socket->sendCommand(command, command->build()); command->set_finished_callback( [this](TorControlCommand *sender) { protocolInfoReply(sender); });
//connect(command, &TorControlCommand::finished, this, &protocolInfoReply);
mSocket->sendCommand(command, command->build());
} }
void TorControlPrivate::socketDisconnected() void TorControl::socketDisconnected()
{ {
/* Clear some internal state */ /* Clear some internal state */
torVersion.clear(); mTorVersion.clear();
socksAddress.clear(); mSocksAddress.clear();
socksPort = 0; mSocksPort = 0;
setTorStatus(TorControl::TorUnknown); setTorStatus(TorControl::TorUnknown);
/* This emits the disconnected() signal as well */ /* This emits the disconnected() signal as well */
setStatus(TorControl::NotConnected); setStatus(TorControl::NotConnected);
} }
void TorControlPrivate::socketError() void TorControl::socketError(const std::string& s)
{ {
setError("Connection failed: " + socket->errorString())); setError("Connection failed: " + s);
} }
void TorControlPrivate::protocolInfoReply() void TorControl::protocolInfoReply(TorControlCommand *sender)
{ {
ProtocolInfoCommand *info = qobject_cast<ProtocolInfoCommand*>(sender()); ProtocolInfoCommand *info = dynamic_cast<ProtocolInfoCommand*>(sender);
if (!info) if (!info)
return; return;
torVersion = info->torVersion(); mTorVersion = info->torVersion();
if (status == TorControl::Authenticating) if (mStatus == TorControl::Authenticating)
{ {
AuthenticateCommand *auth = new AuthenticateCommand; AuthenticateCommand *auth = new AuthenticateCommand;
connect(auth, &TorControlCommand::finished, this, &TorControlPrivate::authenticateReply); connect(auth, &TorControlCommand::finished, this, &TorControl::authenticateReply);
ByteArray data; ByteArray data;
ProtocolInfoCommand::AuthMethods methods = info->authMethods(); ProtocolInfoCommand::AuthMethod methods = info->authMethods();
if (methods.testFlag(ProtocolInfoCommand::AuthNull)) if (methods.testFlag(ProtocolInfoCommand::AuthNull))
{ {
@ -426,7 +425,7 @@ void TorControlPrivate::protocolInfoReply()
/* If we know a password and password authentication is allowed, try using that instead. /* If we know a password and password authentication is allowed, try using that instead.
* This is a strange corner case that will likely never happen in a normal configuration, * This is a strange corner case that will likely never happen in a normal configuration,
* but it has happened. */ * but it has happened. */
if (methods.testFlag(ProtocolInfoCommand::AuthHashedPassword) && !authPassword.empty()) if (methods.testFlag(ProtocolInfoCommand::AuthHashedPassword) && !mAuthPassword.empty())
{ {
torCtrlDebug() << "torctrl: Unable to read authentication cookie file:" << cookieError << std::endl; torCtrlDebug() << "torctrl: Unable to read authentication cookie file:" << cookieError << std::endl;
goto usePasswordAuth; goto usePasswordAuth;
@ -437,11 +436,11 @@ void TorControlPrivate::protocolInfoReply()
return; return;
} }
} }
else if (methods.testFlag(ProtocolInfoCommand::AuthHashedPassword) && !authPassword.empty()) else if (methods.testFlag(ProtocolInfoCommand::AuthHashedPassword) && !mAuthPassword.empty())
{ {
usePasswordAuth: usePasswordAuth:
torCtrlDebug() << "torctrl: Using hashed password authentication" << std::endl; torCtrlDebug() << "torctrl: Using hashed password authentication" << std::endl;
data = auth->build(authPassword); data = auth->build(mAuthPassword);
} }
else else
{ {
@ -453,16 +452,16 @@ void TorControlPrivate::protocolInfoReply()
return; return;
} }
socket->sendCommand(auth, data); mSocket->sendCommand(auth, data);
} }
} }
void TorControlPrivate::getTorInfo() void TorControl::getTorInfo()
{ {
Q_ASSERT(q->isConnected()); assert(isConnected());
GetConfCommand *command = new GetConfCommand(GetConfCommand::GetInfo); GetConfCommand *command = new GetConfCommand(GetConfCommand::GetInfo);
connect(command, &TorControlCommand::finished, this, &TorControlPrivate::getTorInfoReply); connect(command, &TorControlCommand::finished, this, &TorControl::getTorInfoReply);
std::list<std::string> keys{ "status/circuit-established","status/bootstrap-phase" }; std::list<std::string> keys{ "status/circuit-established","status/bootstrap-phase" };
@ -489,13 +488,13 @@ void TorControlPrivate::getTorInfo()
#endif #endif
keys .push_back("net/listeners/socks"); keys .push_back("net/listeners/socks");
socket->sendCommand(command, command->build(keys)); mSocket->sendCommand(command, command->build(keys));
} }
void TorControlPrivate::getTorInfoReply() void TorControl::getTorInfoReply()
{ {
GetConfCommand *command = qobject_cast<GetConfCommand*>(sender()); GetConfCommand *command = qobject_cast<GetConfCommand*>(sender());
if (!command || !q->isConnected()) if (!command || !isConnected())
return; return;
std::list<ByteArray> listenAddresses = splitQuotedStrings(command->get("net/listeners/socks").front(), ' '); std::list<ByteArray> listenAddresses = splitQuotedStrings(command->get("net/listeners/socks").front(), ' ');
@ -509,10 +508,10 @@ void TorControlPrivate::getTorInfoReply()
/* Use the first address that matches the one used for this control connection. If none do, /* Use the first address that matches the one used for this control connection. If none do,
* just use the first address and rely on the user to reconfigure if necessary (not a problem; * just use the first address and rely on the user to reconfigure if necessary (not a problem;
* their setup is already very customized) */ * their setup is already very customized) */
if (socksAddress.empty() || address == socket->peerAddress()) { if (mSocksAddress.empty() || address == mSocket->peerAddress()) {
socksAddress = address; mSocksAddress = address;
socksPort = port; mSocksPort = port;
if (address == socket->peerAddress()) if (address == mSocket->peerAddress())
break; break;
} }
} }
@ -520,8 +519,8 @@ void TorControlPrivate::getTorInfoReply()
/* It is not immediately an error to have no SOCKS address; when DisableNetwork is set there won't be a /* It is not immediately an error to have no SOCKS address; when DisableNetwork is set there won't be a
* listener yet. To handle that situation, we'll try to read the socks address again when TorReady state * listener yet. To handle that situation, we'll try to read the socks address again when TorReady state
* is reached. */ * is reached. */
if (!socksAddress.empty()) { if (!mSocksAddress.empty()) {
torCtrlDebug() << "torctrl: SOCKS address is " << socksAddress << ":" << socksPort << std::endl; torCtrlDebug() << "torctrl: SOCKS address is " << mSocksAddress << ":" << mSocksPort << std::endl;
if(rsEvents) if(rsEvents)
{ {
@ -532,12 +531,13 @@ void TorControlPrivate::getTorInfoReply()
} }
} }
if (command->get("status/circuit-established").toInt() == 1) { if (ByteArray(command->get("status/circuit-established").front()).toInt() == 1)
{
torCtrlDebug() << "torctrl: Tor indicates that circuits have been established; state is TorReady" << std::endl; torCtrlDebug() << "torctrl: Tor indicates that circuits have been established; state is TorReady" << std::endl;
setTorStatus(TorControl::TorReady); setTorStatus(TorControl::TorReady);
} else {
setTorStatus(TorControl::TorOffline);
} }
else
setTorStatus(TorControl::TorOffline);
auto bootstrap = command->get("status/bootstrap-phase"); auto bootstrap = command->get("status/bootstrap-phase");
if (!bootstrap.empty()) if (!bootstrap.empty())
@ -546,18 +546,18 @@ void TorControlPrivate::getTorInfoReply()
void TorControl::addHiddenService(HiddenService *service) void TorControl::addHiddenService(HiddenService *service)
{ {
if (d->services.contains(service)) if (std::find(mServices.begin(),mServices.end(),service) != mServices.end())
return; return;
d->services.append(service); mServices.push_back(service);
} }
void TorControlPrivate::publishServices() void TorControl::publishServices()
{ {
torCtrlDebug() << "Publish Services... " ; torCtrlDebug() << "Publish Services... " ;
Q_ASSERT(q->isConnected()); assert(isConnected());
if (services.isEmpty()) if (mServices.empty())
{ {
std::cerr << "No service regstered!" << std::endl; std::cerr << "No service regstered!" << std::endl;
return; return;
@ -578,22 +578,23 @@ void TorControlPrivate::publishServices()
} }
#endif #endif
if (q->torVersionAsNewAs("0.2.7")) { if (torVersionAsNewAs("0.2.7")) {
foreach (HiddenService *service, services) { for(HiddenService *service: mServices)
{
if (service->hostname().empty()) if (service->hostname().empty())
torCtrlDebug() << "torctrl: Creating a new hidden service" << std::endl; torCtrlDebug() << "torctrl: Creating a new hidden service" << std::endl;
else else
torCtrlDebug() << "torctrl: Publishing hidden service: " << service->hostname() << std::endl; torCtrlDebug() << "torctrl: Publishing hidden service: " << service->hostname() << std::endl;
AddOnionCommand *onionCommand = new AddOnionCommand(service); AddOnionCommand *onionCommand = new AddOnionCommand(service);
QObject::connect(onionCommand, &AddOnionCommand::succeeded, service, &HiddenService::servicePublished); QObject::connect(onionCommand, &AddOnionCommand::succeeded, service, &HiddenService::servicePublished);
socket->sendCommand(onionCommand, onionCommand->build()); mSocket->sendCommand(onionCommand, onionCommand->build());
} }
} else { } else {
torCtrlDebug() << "torctrl: Using legacy SETCONF hidden service configuration for tor" << torVersion.toStdString() << std::endl; torCtrlDebug() << "torctrl: Using legacy SETCONF hidden service configuration for tor" << mTorVersion << std::endl;
SetConfCommand *command = new SetConfCommand; SetConfCommand *command = new SetConfCommand;
std::list<std::pair<std::string,std::string> > torConfig; std::list<std::pair<std::string,std::string> > torConfig;
foreach (HiddenService *service, services) for(HiddenService *service: mServices)
{ {
if (service->dataPath().empty()) if (service->dataPath().empty())
continue; continue;
@ -621,35 +622,35 @@ void TorControlPrivate::publishServices()
} }
if (!torConfig.empty()) if (!torConfig.empty())
socket->sendCommand(command, command->build(torConfig)); mSocket->sendCommand(command, command->build(torConfig));
} }
} }
void TorControl::shutdown() void TorControl::shutdown()
{ {
if (!hasOwnership()) { if (!hasOwnership()) {
qWarning() << "torctrl: Ignoring shutdown command for a tor instance I don't own"; RsWarn() << "torctrl: Ignoring shutdown command for a tor instance I don't own";
return; return;
} }
d->socket->sendCommand(ByteArray("SIGNAL SHUTDOWN\r\n")); mSocket->sendCommand(ByteArray("SIGNAL SHUTDOWN\r\n"));
} }
void TorControl::shutdownSync() void TorControl::shutdownSync()
{ {
if (!hasOwnership()) { if (!hasOwnership()) {
qWarning() << "torctrl: Ignoring shutdown command for a tor instance I don't own"; RsWarn() << "torctrl: Ignoring shutdown command for a tor instance I don't own";
return; return;
} }
shutdown(); shutdown();
while (d->socket->moretowrite()) while (mSocket->moretowrite(0))
std::this_thread::sleep_for(std::chrono::milliseconds(100)); std::this_thread::sleep_for(std::chrono::milliseconds(100));
d->socket->close(); mSocket->close();
} }
void TorControlPrivate::statusEvent(int code, const ByteArray &data) void TorControl::statusEvent(int code, const ByteArray &data)
{ {
Q_UNUSED(code); Q_UNUSED(code);
@ -670,7 +671,7 @@ void TorControlPrivate::statusEvent(int code, const ByteArray &data)
} }
} }
void TorControlPrivate::updateBootstrap(const std::list<ByteArray> &data) void TorControl::updateBootstrap(const std::list<ByteArray> &data)
{ {
bootstrapStatus.clear(); bootstrapStatus.clear();
// WARN or NOTICE // WARN or NOTICE
@ -704,7 +705,7 @@ void TorControlPrivate::updateBootstrap(const std::list<ByteArray> &data)
QObject *TorControl::getConfiguration(const std::string& options) QObject *TorControl::getConfiguration(const std::string& options)
{ {
GetConfCommand *command = new GetConfCommand(GetConfCommand::GetConf); GetConfCommand *command = new GetConfCommand(GetConfCommand::GetConf);
d->socket->sendCommand(command, command->build(options)); mSocket->sendCommand(command, command->build(options));
//QQmlEngine::setObjectOwnership(command, QQmlEngine::CppOwnership); //QQmlEngine::setObjectOwnership(command, QQmlEngine::CppOwnership);
return command; return command;
@ -714,7 +715,7 @@ QObject *TorControl::setConfiguration(const std::list<std::pair<std::string,std:
{ {
SetConfCommand *command = new SetConfCommand; SetConfCommand *command = new SetConfCommand;
command->setResetMode(true); command->setResetMode(true);
d->socket->sendCommand(command, command->build(options)); mSocket->sendCommand(command, command->build(options));
//QQmlEngine::setObjectOwnership(command, QQmlEngine::CppOwnership); //QQmlEngine::setObjectOwnership(command, QQmlEngine::CppOwnership);
return command; return command;
@ -818,13 +819,13 @@ private:
PendingOperation *TorControl::saveConfiguration() PendingOperation *TorControl::saveConfiguration()
{ {
if (!hasOwnership()) { if (!hasOwnership()) {
qWarning() << "torctrl: Ignoring save configuration command for a tor instance I don't own"; RsWarn() << "torctrl: Ignoring save configuration command for a tor instance I don't own";
return 0; return 0;
} }
SaveConfigOperation *operation = new SaveConfigOperation(this); SaveConfigOperation *operation = new SaveConfigOperation(this);
QObject::connect(operation, &PendingOperation::finished, operation, &QObject::deleteLater); QObject::connect(operation, &PendingOperation::finished, operation, &QObject::deleteLater);
operation->start(d->socket); operation->start(mSocket);
//QQmlEngine::setObjectOwnership(operation, QQmlEngine::CppOwnership); //QQmlEngine::setObjectOwnership(operation, QQmlEngine::CppOwnership);
return operation; return operation;
@ -832,13 +833,13 @@ PendingOperation *TorControl::saveConfiguration()
bool TorControl::hasOwnership() const bool TorControl::hasOwnership() const
{ {
return d->hasOwnership; return mHasOwnership;
} }
void TorControl::takeOwnership() void TorControl::takeOwnership()
{ {
d->hasOwnership = true; mHasOwnership = true;
d->socket->sendCommand(ByteArray("TAKEOWNERSHIP\r\n")); mSocket->sendCommand(ByteArray("TAKEOWNERSHIP\r\n"));
// Reset PID-based polling // Reset PID-based polling
std::list<std::pair<std::string,std::string> > options; std::list<std::pair<std::string,std::string> > options;
@ -848,22 +849,29 @@ void TorControl::takeOwnership()
bool TorControl::torVersionAsNewAs(const std::string& match) const bool TorControl::torVersionAsNewAs(const std::string& match) const
{ {
QRegularExpression r(QStringLiteral("[.-]")); auto split = ByteArray(torVersion()).split(ByteArray(".-"));
QStringList split = torVersion().split(r); auto matchSplit = ByteArray(match).split(ByteArray(".-"));
QStringList matchSplit = match.split(r);
for (int i = 0; i < matchSplit.size(); i++) { int split_size = split.size();
if (i >= split.size()) int i=0;
const auto& b_split(split.begin());
for(const auto& b_matchsplit:matchSplit)
{
if (i >= split_size)
return false; return false;
bool ok1 = false, ok2 = false; int currentVal,matchVal;
int currentVal = split[i].toInt(&ok1); bool ok1 = RsUtil::StringToInt((*b_split).toString(),currentVal);
int matchVal = matchSplit[i].toInt(&ok2); bool ok2 = RsUtil::StringToInt(b_matchsplit.toString(),matchVal);
if (!ok1 || !ok2) if (!ok1 || !ok2)
return false; return false;
if (currentVal > matchVal) if (currentVal > matchVal)
return true; return true;
if (currentVal < matchVal) if (currentVal < matchVal)
return false; return false;
++i;
} }
// Versions are equal, up to the length of match // Versions are equal, up to the length of match

View file

@ -35,10 +35,9 @@
#include <iostream> #include <iostream>
#include <QObject>
#include <QHostAddress>
#include "PendingOperation.h" #include "PendingOperation.h"
#include "bytearray.h" #include "bytearray.h"
#include "TorControlSocket.h"
class QNetworkProxy; class QNetworkProxy;
@ -46,23 +45,23 @@ namespace Tor
{ {
class HiddenService; class HiddenService;
class TorControlPrivate; class TorControlSocket;
class TorControlCommand;
class TorControl : public QObject class TorControl : public TorControlSocketClient
{ {
Q_OBJECT // Q_ENUMS(Status TorStatus)
Q_ENUMS(Status TorStatus) //
// // Status of the control connection
// Status of the control connection // Q_PROPERTY(Status status READ status NOTIFY statusChanged)
Q_PROPERTY(Status status READ status NOTIFY statusChanged) // // Status of Tor (and whether it believes it can connect)
// Status of Tor (and whether it believes it can connect) // Q_PROPERTY(TorStatus torStatus READ torStatus NOTIFY torStatusChanged)
Q_PROPERTY(TorStatus torStatus READ torStatus NOTIFY torStatusChanged) // // Whether it's possible to make a SOCKS connection and connect
// Whether it's possible to make a SOCKS connection and connect // Q_PROPERTY(bool hasConnectivity READ hasConnectivity NOTIFY connectivityChanged)
Q_PROPERTY(bool hasConnectivity READ hasConnectivity NOTIFY connectivityChanged) // Q_PROPERTY(QString torVersion READ torVersion NOTIFY connected)
Q_PROPERTY(QString torVersion READ torVersion NOTIFY connected) // Q_PROPERTY(QString errorMessage READ errorMessage NOTIFY statusChanged)
Q_PROPERTY(QString errorMessage READ errorMessage NOTIFY statusChanged) // Q_PROPERTY(QVariantMap bootstrapStatus READ bootstrapStatus NOTIFY bootstrapStatusChanged)
Q_PROPERTY(QVariantMap bootstrapStatus READ bootstrapStatus NOTIFY bootstrapStatusChanged) // Q_PROPERTY(bool hasOwnership READ hasOwnership NOTIFY hasOwnershipChanged)
Q_PROPERTY(bool hasOwnership READ hasOwnership NOTIFY hasOwnershipChanged)
public: public:
enum Status enum Status
@ -81,8 +80,7 @@ public:
TorReady = 0x02 TorReady = 0x02
}; };
explicit TorControl();
explicit TorControl(QObject *parent = 0);
/* Information */ /* Information */
Status status() const; Status status() const;
@ -92,7 +90,7 @@ public:
std::string errorMessage() const; std::string errorMessage() const;
bool hasConnectivity() const; bool hasConnectivity() const;
QHostAddress socksAddress() const; std::string socksAddress() const;
quint16 socksPort() const; quint16 socksPort() const;
QNetworkProxy connectionProxy(); QNetworkProxy connectionProxy();
@ -109,24 +107,26 @@ public:
void takeOwnership(); void takeOwnership();
/* Hidden Services */ /* Hidden Services */
QList<HiddenService*> hiddenServices() const; std::list<HiddenService*> hiddenServices() const;
void addHiddenService(HiddenService *service); void addHiddenService(HiddenService *service);
std::map<std::string, std::string> bootstrapStatus() const; std::map<std::string, std::string> bootstrapStatus() const;
Q_INVOKABLE QObject *getConfiguration(const std::string &options); /*Q_INVOKABLE*/ QObject *getConfiguration(const std::string &options);
Q_INVOKABLE QObject *setConfiguration(const std::list<std::pair<std::string, std::string> > &options); /*Q_INVOKABLE*/ QObject *setConfiguration(const std::list<std::pair<std::string, std::string> > &options);
Q_INVOKABLE PendingOperation *saveConfiguration(); /*Q_INVOKABLE*/ PendingOperation *saveConfiguration();
signals: //signals:
void statusChanged(int newStatus, int oldStatus); // void statusChanged(int newStatus, int oldStatus);
void torStatusChanged(int newStatus, int oldStatus); // void torStatusChanged(int newStatus, int oldStatus);
void connected(); // void connected();
void disconnected(); // void disconnected();
void connectivityChanged(); // void connectivityChanged();
void bootstrapStatusChanged(); // void bootstrapStatusChanged();
void hasOwnershipChanged(); // void hasOwnershipChanged();
public slots: virtual void socketError(const std::string &s) override;
//public slots:
/* Instruct Tor to shutdown */ /* Instruct Tor to shutdown */
void shutdown(); void shutdown();
/* Call shutdown(), and wait synchronously for the command to be written */ /* Call shutdown(), and wait synchronously for the command to be written */
@ -135,7 +135,31 @@ public slots:
void reconnect(); void reconnect();
private: private:
TorControlPrivate *d; TorControlSocket *mSocket;
std::string mTorAddress;
std::string mErrorMessage;
std::string mTorVersion;
ByteArray mAuthPassword;
std::string mSocksAddress;
std::list<HiddenService*> mServices;
quint16 mControlPort, mSocksPort;
TorControl::Status mStatus;
TorControl::TorStatus mTorStatus;
std::map<std::string,std::string> mBootstrapStatus;
bool mHasOwnership;
void getTorInfo();
void getTorInfoReply();
void setStatus(TorControl::Status n);
void statusEvent(int code, const ByteArray &data);
void setTorStatus(TorControl::TorStatus n);
void updateBootstrap(const std::list<ByteArray>& data);
void setError(const std::string& message);
void publishServices();
void protocolInfoReply(TorControlCommand *sender);
void socketDisconnected();
void socketConnected();
void authenticateReply();
}; };
} }

View file

@ -31,7 +31,6 @@
*/ */
#include "TorControlCommand.h" #include "TorControlCommand.h"
#include <QDebug>
using namespace Tor; using namespace Tor;
@ -42,22 +41,23 @@ TorControlCommand::TorControlCommand()
void TorControlCommand::onReply(int statusCode, const ByteArray &data) void TorControlCommand::onReply(int statusCode, const ByteArray &data)
{ {
emit replyLine(statusCode, data); //emit replyLine(statusCode, data);
mReplyLine(statusCode, data);
} }
void TorControlCommand::onFinished(int statusCode) void TorControlCommand::onFinished(int statusCode)
{ {
m_finalStatus = statusCode; m_finalStatus = statusCode;
emit finished(); //emit finished();
mFinished(this);
} }
void TorControlCommand::onDataLine(const ByteArray &data) void TorControlCommand::onDataLine(const ByteArray &data)
{ {
Q_UNUSED(data);
} }
void TorControlCommand::onDataFinished() void TorControlCommand::onDataFinished()
{ {
qWarning() << "torctrl: Unexpected data response for command"; RsWarn() << "torctrl: Unexpected data response for command";
} }

View file

@ -30,33 +30,31 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/ */
#ifndef TORCONTROLCOMMAND_H #pragma once
#define TORCONTROLCOMMAND_H
#include <QObject>
#include <functional>
#include "bytearray.h" #include "bytearray.h"
namespace Tor namespace Tor
{ {
class TorControlCommand : public QObject class ProtocolInfoCommand;
{
Q_OBJECT
Q_DISABLE_COPY(TorControlCommand)
class TorControlCommand
{
friend class TorControlSocket; friend class TorControlSocket;
public: public:
TorControlCommand(); TorControlCommand();
virtual ~TorControlCommand()=default;
int statusCode() const { return m_finalStatus; } int statusCode() const { return m_finalStatus; }
signals: //signals:
void replyLine(int statusCode, const ByteArray &data); void set_replyLine_callback( const std::function<void(int statusCode, const ByteArray &data)>& f) { mReplyLine=f ; }
void finished(); void set_finished_callback( const std::function<void(TorControlCommand *sender)>& f) { mFinished=f; };
protected: public:
virtual void onReply(int statusCode, const ByteArray &data); virtual void onReply(int statusCode, const ByteArray &data);
virtual void onFinished(int statusCode); virtual void onFinished(int statusCode);
virtual void onDataLine(const ByteArray &data); virtual void onDataLine(const ByteArray &data);
@ -64,8 +62,13 @@ protected:
private: private:
int m_finalStatus; int m_finalStatus;
// Disable copy
TorControlCommand(const TorControlCommand&){}
TorControlCommand& operator=(const TorControlCommand&){ return *this; }
std::function<void(int statusCode, const ByteArray &data)> mReplyLine;
std::function<void(TorControlCommand *sender)> mFinished;
}; };
} }
#endif // TORCONTROLCOMMAND_H

View file

@ -37,8 +37,8 @@
using namespace Tor; using namespace Tor;
TorControlSocket::TorControlSocket(const std::string& tcp_address,uint16_t tcp_port) TorControlSocket::TorControlSocket(TorControlSocketClient *client)
: RsThreadedTcpSocket(tcp_address,tcp_port),currentCommand(0), inDataReply(false) : RsThreadedTcpSocket(),currentCommand(0), inDataReply(false),mClient(client)
{ {
//connect(this, SIGNAL(readyRead()), this, SLOT(process())); //connect(this, SIGNAL(readyRead()), this, SLOT(process()));
//connect(this, SIGNAL(disconnected()), this, SLOT(clear())); //connect(this, SIGNAL(disconnected()), this, SLOT(clear()));
@ -98,7 +98,7 @@ void TorControlSocket::clear()
void TorControlSocket::setError(const std::string &message) void TorControlSocket::setError(const std::string &message)
{ {
m_errorMessage = message; m_errorMessage = message;
emit error(message); mClient->socketError(message);
abort(); abort();
} }
@ -202,7 +202,7 @@ void TorControlSocket::process()
commandQueue.pop_front(); commandQueue.pop_front();
if (command) { if (command) {
command->onFinished(statusCode); command->onFinished(statusCode);
command->deleteLater(); delete command; // should we "delete later" ?
} }
} }
} }

View file

@ -40,12 +40,20 @@ namespace Tor
class TorControlCommand; class TorControlCommand;
class TorControlSocketClient
{
public:
virtual void socketError(const std::string& s) = 0;
};
class TorControlSocket : public RsThreadedTcpSocket class TorControlSocket : public RsThreadedTcpSocket
{ {
public: public:
explicit TorControlSocket(const std::string& tcp_address,uint16_t tcp_port); explicit TorControlSocket(TorControlSocketClient *client);
virtual ~TorControlSocket(); virtual ~TorControlSocket();
void connect(const std::string& tcp_address,uint16_t tcp_port);
std::string errorMessage() const { return m_errorMessage; } std::string errorMessage() const { return m_errorMessage; }
void connectToHost(const std::string& tcp_address,uint16_t tcp_port); void connectToHost(const std::string& tcp_address,uint16_t tcp_port);
@ -62,7 +70,9 @@ public:
std::string peerAddress() const; std::string peerAddress() const;
//signals: //signals:
void error(const std::string& message); // void error(const std::string& message);
const std::string& errorString() const { return m_errorMessage ;}
//private slots: //private slots:
void process(); void process();
@ -74,6 +84,7 @@ private:
std::string m_errorMessage; std::string m_errorMessage;
TorControlCommand *currentCommand; TorControlCommand *currentCommand;
bool inDataReply; bool inDataReply;
TorControlSocketClient *mClient;
void setError(const std::string& message); void setError(const std::string& message);
}; };

View file

@ -211,23 +211,22 @@ bool TorManager::setupHiddenService()
// 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 = QHostAddress::LocalHost; // we only listen from localhost std::string address = "127.0.0.1"; // we only listen from localhost
unsigned short port = 7934;//(quint16)m_settings->read("localListenPort").toInt();
quint16 port = 7934;//(quint16)m_settings->read("localListenPort").toInt(); std::cerr << "Testing host address: " << address << ":" << port ;
std::cerr << "Testing host address: " << address.toString().toStdString() << ":" << port ; // if (!QTcpServer().listen(address, port))
// {
if (!QTcpServer().listen(address, port)) // // XXX error case
{ // std::cerr << " Failed to open incoming socket" << std::endl;
// XXX error case // return false;
std::cerr << " Failed to open incoming socket" << std::endl; // }
return false;
}
std::cerr << " OK - Adding hidden service to TorControl." << std::endl; std::cerr << " OK - Adding hidden service to TorControl." << std::endl;
//d->hiddenService->addTarget(9878, mIncomingServer->serverAddress(), mIncomingServer->serverPort()); //d->hiddenService->addTarget(9878, mIncomingServer->serverAddress(), mIncomingServer->serverPort());
d->hiddenService->addTarget(9878, QHostAddress::LocalHost,7934); d->hiddenService->addTarget(9878, "127.0.0.1",7934);
control()->addHiddenService(d->hiddenService); control()->addHiddenService(d->hiddenService);
return true ; return true ;
@ -408,7 +407,7 @@ bool TorManager::start()
return true ; return true ;
} }
bool TorManager::getProxyServerInfo(QHostAddress& proxy_server_adress,uint16_t& proxy_server_port) bool TorManager::getProxyServerInfo(std::string& proxy_server_adress,uint16_t& proxy_server_port)
{ {
proxy_server_adress = control()->socksAddress(); proxy_server_adress = control()->socksAddress();
proxy_server_port = control()->socksPort(); proxy_server_port = control()->socksPort();
@ -416,7 +415,7 @@ bool TorManager::getProxyServerInfo(QHostAddress& proxy_server_adress,uint16_t&
return proxy_server_port > 1023 ; return proxy_server_port > 1023 ;
} }
bool TorManager::getHiddenServiceInfo(std::string& service_id,std::string& service_onion_address,uint16_t& service_port, QHostAddress& service_target_address,uint16_t& target_port) bool TorManager::getHiddenServiceInfo(std::string& service_id,std::string& service_onion_address,uint16_t& service_port, std::string& service_target_address,uint16_t& target_port)
{ {
QList<Tor::HiddenService*> hidden_services = control()->hiddenServices(); QList<Tor::HiddenService*> hidden_services = control()->hiddenServices();
@ -444,7 +443,7 @@ bool TorManager::getHiddenServiceInfo(std::string& service_id,std::string& servi
void TorManagerPrivate::processStateChanged(int state) void TorManagerPrivate::processStateChanged(int state)
{ {
RsInfo() << "state: " << state << " passwd=\"" << process->controlPassword().toString() << "\" " << process->controlHost().toString().toStdString() RsInfo() << "state: " << state << " passwd=\"" << process->controlPassword().toString() << "\" " << process->controlHost()
<< ":" << process->controlPort() << std::endl; << ":" << process->controlPort() << std::endl;
if (state == TorProcess::Ready) { if (state == TorProcess::Ready) {
@ -605,14 +604,14 @@ bool RsTor::getHiddenServiceInfo(std::string& service_id,
{ {
std::string sid; std::string sid;
std::string soa; std::string soa;
QHostAddress sta; std::string sta;
if(!instance()->getHiddenServiceInfo(sid,soa,service_port,sta,target_port)) if(!instance()->getHiddenServiceInfo(sid,soa,service_port,sta,target_port))
return false; return false;
service_id = sid; service_id = sid;
service_onion_address = soa; service_onion_address = soa;
service_target_address = sta.toString().toStdString(); service_target_address = sta;
return true; return true;
} }
@ -624,7 +623,7 @@ std::list<std::string> RsTor::logMessages()
std::string RsTor::socksAddress() std::string RsTor::socksAddress()
{ {
return instance()->control()->socksAddress().toString().toStdString(); return instance()->control()->socksAddress();
} }
uint16_t RsTor::socksPort() uint16_t RsTor::socksPort()
{ {
@ -700,10 +699,10 @@ std::string RsTor::errorMessage()
void RsTor::getProxyServerInfo(std::string& server_address, uint16_t& server_port) void RsTor::getProxyServerInfo(std::string& server_address, uint16_t& server_port)
{ {
QHostAddress qserver_address; std::string qserver_address;
instance()->getProxyServerInfo(qserver_address,server_port); instance()->getProxyServerInfo(qserver_address,server_port);
server_address = qserver_address.toString().toStdString(); server_address = qserver_address;
} }
bool RsTor::start() bool RsTor::start()

View file

@ -38,8 +38,6 @@
#include "retroshare/rstor.h" #include "retroshare/rstor.h"
#include "HiddenService.h" #include "HiddenService.h"
#include <QHostAddress>
namespace Tor namespace Tor
{ {
@ -86,8 +84,8 @@ public:
bool hasError() const; bool hasError() const;
std::string errorMessage() const; std::string errorMessage() const;
bool getHiddenServiceInfo(std::string& service_id,std::string& service_onion_address,uint16_t& service_port, QHostAddress& service_target_address,uint16_t& target_port); bool getHiddenServiceInfo(std::string& service_id,std::string& service_onion_address,uint16_t& service_port, std::string& service_target_address,uint16_t& target_port);
bool getProxyServerInfo(QHostAddress& proxy_server_adress,uint16_t& proxy_server_port); bool getProxyServerInfo(std::string &proxy_server_adress, uint16_t& proxy_server_port);
//public slots: //public slots:
bool start(); bool start();

View file

@ -333,12 +333,12 @@ ByteArray TorProcess::controlPassword()
return mControlPassword; return mControlPassword;
} }
QHostAddress TorProcess::controlHost() std::string TorProcess::controlHost()
{ {
return mControlHost; return mControlHost;
} }
quint16 TorProcess::controlPort() unsigned short TorProcess::controlPort()
{ {
return mControlPort; return mControlPort;
} }

View file

@ -33,8 +33,6 @@
#ifndef TORPROCESS_H #ifndef TORPROCESS_H
#define TORPROCESS_H #define TORPROCESS_H
#include <QHostAddress>
#include "bytearray.h" #include "bytearray.h"
#include "util/rsthreads.h" #include "util/rsthreads.h"
@ -89,8 +87,8 @@ public:
State state() const; State state() const;
std::string errorMessage() const; std::string errorMessage() const;
QHostAddress controlHost(); std::string controlHost();
quint16 controlPort(); unsigned short controlPort();
ByteArray controlPassword(); ByteArray controlPassword();
//signals: //signals:
@ -116,8 +114,8 @@ private:
std::list<std::string> mExtraSettings; std::list<std::string> mExtraSettings;
TorProcess::State mState; TorProcess::State mState;
std::string mErrorMessage; std::string mErrorMessage;
QHostAddress mControlHost; std::string mControlHost;
quint16 mControlPort; unsigned short mControlPort;
ByteArray mControlPassword; ByteArray mControlPassword;
int controlPortAttempts; int controlPortAttempts;
@ -127,7 +125,7 @@ private:
bool ensureFilesExist(); bool ensureFilesExist();
pid_t mTorProcessId; pid_t mTorProcessId;
public slots: //public slots:
void processStarted(); void processStarted();
void processFinished(); void processFinished();
void processError(std::string error); void processError(std::string error);

View file

@ -4,6 +4,7 @@
#include <string.h> #include <string.h>
#include <string> #include <string>
#include <algorithm>
#include <vector> #include <vector>
#include <list> #include <list>
@ -42,7 +43,7 @@ public:
{ {
std::istringstream is(toString().c_str()); std::istringstream is(toString().c_str());
int res = 0; int res = -1;
is >> res ; is >> res ;
return res; return res;
@ -103,6 +104,8 @@ public:
return res; return res;
} }
// Splits the byte array using sep as separator.
std::list<ByteArray> split(unsigned char sep) std::list<ByteArray> split(unsigned char sep)
{ {
std::list<ByteArray> res; std::list<ByteArray> res;
@ -120,6 +123,25 @@ public:
return res; return res;
} }
// Splits the byte array using any of the characters in sep as separators.
std::list<ByteArray> split(const ByteArray& sep)
{
std::list<ByteArray> res;
ByteArray current_block;
for(uint32_t i=0;i<size();++i)
if(std::find(sep.begin(),sep.end(),operator[](i)) != sep.end())
{
res.push_back(current_block);
current_block.clear();
}
else
current_block += operator[](i);
return res;
}
// Removes the following characters from the beginning and from the end of the array: // Removes the following characters from the beginning and from the end of the array:
// '\t', '\n', '\v', '\f', '\r', and ' '. // '\t', '\n', '\v', '\f', '\r', and ' '.