From d7fb3d8bf4622be397462a18631828278f177385 Mon Sep 17 00:00:00 2001 From: csoler Date: Sat, 19 Jun 2021 15:34:46 +0200 Subject: [PATCH 01/65] moved TorControl files into libretroshare. Not compiling yet. --- libretroshare/src/libretroshare.pro | 40 +++++++ .../src/tor}/AddOnionCommand.cpp | 0 .../src/tor}/AddOnionCommand.h | 17 ++- .../src/tor}/AuthenticateCommand.cpp | 0 .../src/tor}/AuthenticateCommand.h | 0 .../src/tor}/CryptoKey.cpp | 46 +++---- .../src/tor}/CryptoKey.h | 15 ++- .../src/tor}/GetConfCommand.cpp | 25 ++-- .../src/tor}/GetConfCommand.h | 16 ++- .../src/tor}/HiddenService.cpp | 2 +- .../src/tor}/HiddenService.h | 47 ++++---- .../src/tor}/PendingOperation.cpp | 0 .../src/tor}/PendingOperation.h | 0 .../src/tor}/ProtocolInfoCommand.cpp | 0 .../src/tor}/ProtocolInfoCommand.h | 31 +++-- .../src/tor}/SecureRNG.cpp | 31 +++-- .../src/tor}/SecureRNG.h | 10 +- .../src/tor}/SetConfCommand.cpp | 0 .../src/tor}/SetConfCommand.h | 0 .../src/tor}/Settings.cpp | 0 .../src/tor}/Settings.h | 0 .../src/tor}/StrUtil.cpp | 12 +- .../src/tor}/StrUtil.h | 6 +- .../src/tor}/TorControl.cpp | 0 .../src/tor}/TorControl.h | 0 .../src/tor}/TorControlCommand.cpp | 0 .../src/tor}/TorControlCommand.h | 19 ++- .../src/tor}/TorControlSocket.cpp | 0 .../src/tor}/TorControlSocket.h | 0 .../src/tor}/TorManager.cpp | 0 .../src/tor}/TorManager.h | 0 .../src/tor}/TorProcess.cpp | 0 .../src/tor}/TorProcess.h | 0 .../src/tor}/TorProcess_p.h | 0 .../src/tor}/TorSocket.cpp | 0 .../src/tor}/TorSocket.h | 0 libretroshare/src/tor/TorTypes.h | 112 ++++++++++++++++++ .../src/tor}/Useful.h | 0 .../{ => gui}/TorControl/TorControlWindow.cpp | 0 .../{ => gui}/TorControl/TorControlWindow.h | 0 .../{ => gui}/TorControl/TorControlWindow.ui | 0 retroshare-gui/src/retroshare-gui.pro | 40 ------- 42 files changed, 294 insertions(+), 175 deletions(-) rename {retroshare-gui/src/TorControl => libretroshare/src/tor}/AddOnionCommand.cpp (100%) rename {retroshare-gui/src/TorControl => libretroshare/src/tor}/AddOnionCommand.h (89%) rename {retroshare-gui/src/TorControl => libretroshare/src/tor}/AuthenticateCommand.cpp (100%) rename {retroshare-gui/src/TorControl => libretroshare/src/tor}/AuthenticateCommand.h (100%) rename {retroshare-gui/src/TorControl => libretroshare/src/tor}/CryptoKey.cpp (93%) rename {retroshare-gui/src/TorControl => libretroshare/src/tor}/CryptoKey.h (90%) rename {retroshare-gui/src/TorControl => libretroshare/src/tor}/GetConfCommand.cpp (87%) rename {retroshare-gui/src/TorControl => libretroshare/src/tor}/GetConfCommand.h (89%) rename {retroshare-gui/src/TorControl => libretroshare/src/tor}/HiddenService.cpp (98%) rename {retroshare-gui/src/TorControl => libretroshare/src/tor}/HiddenService.h (72%) rename {retroshare-gui/src/TorControl => libretroshare/src/tor}/PendingOperation.cpp (100%) rename {retroshare-gui/src/TorControl => libretroshare/src/tor}/PendingOperation.h (100%) rename {retroshare-gui/src/TorControl => libretroshare/src/tor}/ProtocolInfoCommand.cpp (100%) rename {retroshare-gui/src/TorControl => libretroshare/src/tor}/ProtocolInfoCommand.h (83%) rename {retroshare-gui/src/TorControl => libretroshare/src/tor}/SecureRNG.cpp (84%) rename {retroshare-gui/src/TorControl => libretroshare/src/tor}/SecureRNG.h (88%) rename {retroshare-gui/src/TorControl => libretroshare/src/tor}/SetConfCommand.cpp (100%) rename {retroshare-gui/src/TorControl => libretroshare/src/tor}/SetConfCommand.h (100%) rename {retroshare-gui/src/TorControl => libretroshare/src/tor}/Settings.cpp (100%) rename {retroshare-gui/src/TorControl => libretroshare/src/tor}/Settings.h (100%) rename {retroshare-gui/src/TorControl => libretroshare/src/tor}/StrUtil.cpp (91%) rename {retroshare-gui/src/TorControl => libretroshare/src/tor}/StrUtil.h (94%) rename {retroshare-gui/src/TorControl => libretroshare/src/tor}/TorControl.cpp (100%) rename {retroshare-gui/src/TorControl => libretroshare/src/tor}/TorControl.h (100%) rename {retroshare-gui/src/TorControl => libretroshare/src/tor}/TorControlCommand.cpp (100%) rename {retroshare-gui/src/TorControl => libretroshare/src/tor}/TorControlCommand.h (85%) rename {retroshare-gui/src/TorControl => libretroshare/src/tor}/TorControlSocket.cpp (100%) rename {retroshare-gui/src/TorControl => libretroshare/src/tor}/TorControlSocket.h (100%) rename {retroshare-gui/src/TorControl => libretroshare/src/tor}/TorManager.cpp (100%) rename {retroshare-gui/src/TorControl => libretroshare/src/tor}/TorManager.h (100%) rename {retroshare-gui/src/TorControl => libretroshare/src/tor}/TorProcess.cpp (100%) rename {retroshare-gui/src/TorControl => libretroshare/src/tor}/TorProcess.h (100%) rename {retroshare-gui/src/TorControl => libretroshare/src/tor}/TorProcess_p.h (100%) rename {retroshare-gui/src/TorControl => libretroshare/src/tor}/TorSocket.cpp (100%) rename {retroshare-gui/src/TorControl => libretroshare/src/tor}/TorSocket.h (100%) create mode 100644 libretroshare/src/tor/TorTypes.h rename {retroshare-gui/src/TorControl => libretroshare/src/tor}/Useful.h (100%) rename retroshare-gui/src/{ => gui}/TorControl/TorControlWindow.cpp (100%) rename retroshare-gui/src/{ => gui}/TorControl/TorControlWindow.h (100%) rename retroshare-gui/src/{ => gui}/TorControl/TorControlWindow.ui (100%) diff --git a/libretroshare/src/libretroshare.pro b/libretroshare/src/libretroshare.pro index 84d18944e..5276bda9b 100644 --- a/libretroshare/src/libretroshare.pro +++ b/libretroshare/src/libretroshare.pro @@ -719,6 +719,46 @@ SOURCES += rsitems/rsnxsitems.cc \ gxs/rsgxsutil.cc \ gxs/rsgxsrequesttypes.cc +# Tor +HEADERS += tor/AddOnionCommand.h \ + tor/AuthenticateCommand.h \ + tor/CryptoKey.h \ + tor/GetConfCommand.h \ + tor/HiddenService.h \ + tor/PendingOperation.h \ + tor/ProtocolInfoCommand.h \ + tor/SecureRNG.h \ + tor/TorTypes.h \ + tor/SetConfCommand.h \ + tor/Settings.h \ + tor/StrUtil.h \ + tor/TorControl.h \ + tor/TorControlCommand.h \ + tor/TorControlSocket.h \ + tor/TorManager.h \ + tor/TorProcess.h \ + tor/TorProcess_p.h \ + tor/TorSocket.h \ + tor/Useful.h + +SOURCES += tor/AddOnionCommand.cpp \ + tor/AuthenticateCommand.cpp \ + tor/GetConfCommand.cpp \ + tor/HiddenService.cpp \ + tor/ProtocolInfoCommand.cpp \ + tor/SetConfCommand.cpp \ + tor/TorControlCommand.cpp \ + tor/TorControl.cpp \ + tor/TorControlSocket.cpp \ + tor/TorManager.cpp \ + tor/TorProcess.cpp \ + tor/TorSocket.cpp \ + tor/CryptoKey.cpp \ + tor/PendingOperation.cpp \ + tor/SecureRNG.cpp \ + tor/Settings.cpp \ + tor/StrUtil.cpp + # gxs tunnels HEADERS += gxstunnel/p3gxstunnel.h \ gxstunnel/rsgxstunnelitems.h \ diff --git a/retroshare-gui/src/TorControl/AddOnionCommand.cpp b/libretroshare/src/tor/AddOnionCommand.cpp similarity index 100% rename from retroshare-gui/src/TorControl/AddOnionCommand.cpp rename to libretroshare/src/tor/AddOnionCommand.cpp diff --git a/retroshare-gui/src/TorControl/AddOnionCommand.h b/libretroshare/src/tor/AddOnionCommand.h similarity index 89% rename from retroshare-gui/src/TorControl/AddOnionCommand.h rename to libretroshare/src/tor/AddOnionCommand.h index 7c0afaf5e..a51888b2f 100644 --- a/retroshare-gui/src/TorControl/AddOnionCommand.h +++ b/libretroshare/src/tor/AddOnionCommand.h @@ -34,9 +34,7 @@ #define ADDONIONCOMMAND_H #include "TorControlCommand.h" -#include -#include -#include +#include namespace Tor { @@ -45,27 +43,28 @@ class HiddenService; class AddOnionCommand : public TorControlCommand { - Q_OBJECT - Q_DISABLE_COPY(AddOnionCommand) - - Q_PROPERTY(QString errorMessage READ errorMessage CONSTANT) +#ifdef NO_TOR_CONTROL_PROPERTIES + Q_PROPERTY(std::string errorMessage READ errorMessage CONSTANT) Q_PROPERTY(bool successful READ isSuccessful CONSTANT) +#endif public: AddOnionCommand(HiddenService *service); QByteArray build(); - QString errorMessage() const { return m_errorMessage; } + std::string errorMessage() const { return m_errorMessage; } bool isSuccessful() const; +#ifdef NO_TOR_CONTROL_SIGNALS signals: void succeeded(); void failed(int code); +#endif protected: HiddenService *m_service; - QString m_errorMessage; + std::string m_errorMessage; virtual void onReply(int statusCode, const QByteArray &data); virtual void onFinished(int statusCode); diff --git a/retroshare-gui/src/TorControl/AuthenticateCommand.cpp b/libretroshare/src/tor/AuthenticateCommand.cpp similarity index 100% rename from retroshare-gui/src/TorControl/AuthenticateCommand.cpp rename to libretroshare/src/tor/AuthenticateCommand.cpp diff --git a/retroshare-gui/src/TorControl/AuthenticateCommand.h b/libretroshare/src/tor/AuthenticateCommand.h similarity index 100% rename from retroshare-gui/src/TorControl/AuthenticateCommand.h rename to libretroshare/src/tor/AuthenticateCommand.h diff --git a/retroshare-gui/src/TorControl/CryptoKey.cpp b/libretroshare/src/tor/CryptoKey.cpp similarity index 93% rename from retroshare-gui/src/TorControl/CryptoKey.cpp rename to libretroshare/src/tor/CryptoKey.cpp index 9be9a6699..d5b66c988 100644 --- a/retroshare-gui/src/TorControl/CryptoKey.cpp +++ b/libretroshare/src/tor/CryptoKey.cpp @@ -31,13 +31,13 @@ */ #include +#include #include "CryptoKey.h" #include "SecureRNG.h" #include "Useful.h" -#include -#include -#include +#include "TorTypes.h" + #include #include #include @@ -120,17 +120,23 @@ bool CryptoKey::loadFromData(const QByteArray &data, KeyType type, KeyFormat for } #endif -bool CryptoKey::loadFromFile(const QString& path) +bool CryptoKey::loadFromFile(const std::string &path) { - QFile file(path); - if (!file.open(QIODevice::ReadOnly)) + FILE *f = fopen(path.c_str(),"r"); + + if(!f) { - qWarning() << "Failed to open Tor key file " << path << ": " << file.errorString(); + std::cerr << "Failed to open Tor key file " << path << std::endl; return false; } - QByteArray data = file.readAll(); - file.close(); + Tor::TorByteArray data ; + int c; + + while( EOF != (c=fgetc(f))) + data += (unsigned char)c; + + fclose(f); if(data.contains("-----BEGIN RSA PRIVATE KEY-----")) { @@ -146,14 +152,14 @@ bool CryptoKey::loadFromFile(const QString& path) } std::cerr << "Have read the following key: " << std::endl; - std::cerr << QString(data).toStdString() << std::endl; + std::cerr << data.toStdString() << std::endl; key_data = data; return true; } -bool CryptoKey::loadFromTorMessage(const QByteArray& b) +bool CryptoKey::loadFromTorMessage(const Tor::TorByteArray& b) { // note: We should probably check the structure a bit more, for security. @@ -163,7 +169,7 @@ bool CryptoKey::loadFromTorMessage(const QByteArray& b) std::cerr << " type: RSA-1024 (Tor v2)" << std::endl; else if(b.startsWith("ED25519-V3")) std::cerr << " type: ED25519-V3 (Tor v3)" << std::endl; - else if(b.indexOf(':')) + else if(b.indexOf(':') >= 0) { std::cerr << " unknown type, or bad syntax in key: \"" << b.left(b.indexOf(':')).toStdString() << "\". Not accepted." << std::endl; return false; @@ -174,22 +180,22 @@ bool CryptoKey::loadFromTorMessage(const QByteArray& b) } /* Cryptographic hash of a password as expected by Tor's HashedControlPassword */ -QByteArray torControlHashedPassword(const QByteArray &password) +Tor::TorByteArray torControlHashedPassword(const Tor::TorByteArray& password) { - QByteArray salt = SecureRNG::random(8); + Tor::TorByteArray salt = SecureRNG::random(8); if (salt.isNull()) - return QByteArray(); + return Tor::TorByteArray(); int count = ((quint32)16 + (96 & 15)) << ((96 >> 4) + 6); SHA_CTX hash; SHA1_Init(&hash); - QByteArray tmp = salt + password; + Tor::TorByteArray tmp = salt + password; while (count) { - int c = qMin(count, tmp.size()); - SHA1_Update(&hash, reinterpret_cast(tmp.constData()), c); + int c = std::min(count, tmp.size()); + SHA1_Update(&hash, reinterpret_cast(tmp.data()), c); count -= c; } @@ -197,8 +203,8 @@ QByteArray torControlHashedPassword(const QByteArray &password) SHA1_Final(md, &hash); /* 60 is the hex-encoded value of 96, which is a constant used by Tor's algorithm. */ - return QByteArray("16:") + salt.toHex().toUpper() + QByteArray("60") + - QByteArray::fromRawData(reinterpret_cast(md), 20).toHex().toUpper(); + return Tor::TorByteArray("16:") + salt.toHex().toUpper() + Tor::TorByteArray("60") + + Tor::TorByteArray::fromRawData(reinterpret_cast(md), 20).toHex().toUpper(); } diff --git a/retroshare-gui/src/TorControl/CryptoKey.h b/libretroshare/src/tor/CryptoKey.h similarity index 90% rename from retroshare-gui/src/TorControl/CryptoKey.h rename to libretroshare/src/tor/CryptoKey.h index c99703444..57c22476f 100644 --- a/retroshare-gui/src/TorControl/CryptoKey.h +++ b/libretroshare/src/tor/CryptoKey.h @@ -33,9 +33,7 @@ #ifndef CRYPTOKEY_H #define CRYPTOKEY_H -#include -#include -#include +#include "tor/TorTypes.h" class CryptoKey { @@ -57,12 +55,13 @@ public: bool loadFromData(const QByteArray &data, KeyType type, KeyFormat format = PEM); bool loadFromFile(const QString &path, KeyType type, KeyFormat format = PEM); #endif - bool loadFromFile(const QString &path); + bool loadFromFile(const std::string& path); void clear(); - const QByteArray bytes() const { return key_data; } - bool loadFromTorMessage(const QByteArray& b); - bool isLoaded() const { return !key_data.isNull(); } + const Tor::TorByteArray& bytes() const { return key_data; } + bool loadFromTorMessage(const Tor::TorByteArray& b); + bool isLoaded() const { return !key_data.empty(); } + #ifdef TO_REMOVE bool isPrivate() const; @@ -101,6 +100,6 @@ private: #endif }; -QByteArray torControlHashedPassword(const QByteArray &password); +Tor::TorByteArray torControlHashedPassword(const Tor::TorByteArray& password); #endif // CRYPTOKEY_H diff --git a/retroshare-gui/src/TorControl/GetConfCommand.cpp b/libretroshare/src/tor/GetConfCommand.cpp similarity index 87% rename from retroshare-gui/src/TorControl/GetConfCommand.cpp rename to libretroshare/src/tor/GetConfCommand.cpp index 933def562..7da0a46cc 100644 --- a/retroshare-gui/src/TorControl/GetConfCommand.cpp +++ b/libretroshare/src/tor/GetConfCommand.cpp @@ -30,9 +30,11 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ +#include + +#include "TorTypes.h" #include "GetConfCommand.h" #include "StrUtil.h" -#include using namespace Tor; @@ -43,27 +45,28 @@ GetConfCommand::GetConfCommand(Type t) QByteArray GetConfCommand::build(const QByteArray &key) { - return build(QList() << key); + return build(std::list{key}); } -QByteArray GetConfCommand::build(const QList &keys) +QByteArray GetConfCommand::build(const std::list &keys) { QByteArray out; if (type == GetConf) { - out = "GETCONF"; + out = QByteArray("GETCONF"); } else if (type == GetInfo) { - out = "GETINFO"; + out = QByteArray("GETINFO"); } else { - Q_ASSERT(false); + throw std::runtime_error("Unsupported build type in GetConfCommand"); return out; } - foreach (const QByteArray &key, keys) { - out.append(' '); - out.append(key); + for(const QByteArray& key: keys) + { + out += (' '); + out += key; } - out.append("\r\n"); + out += std::string("\r\n"); return out; } @@ -74,7 +77,7 @@ void GetConfCommand::onReply(int statusCode, const QByteArray &data) return; int kep = data.indexOf('='); - QString key = QString::fromLatin1(data.mid(0, kep)); + std::string key = QString::fromLatin1(data.mid(0, kep)); QVariant value; if (kep >= 0) value = QString::fromLatin1(unquotedString(data.mid(kep + 1))); diff --git a/retroshare-gui/src/TorControl/GetConfCommand.h b/libretroshare/src/tor/GetConfCommand.h similarity index 89% rename from retroshare-gui/src/TorControl/GetConfCommand.h rename to libretroshare/src/tor/GetConfCommand.h index 0de97d1b7..0289d5e40 100644 --- a/retroshare-gui/src/TorControl/GetConfCommand.h +++ b/libretroshare/src/tor/GetConfCommand.h @@ -34,18 +34,16 @@ #define GETCONFCOMMAND_H #include "TorControlCommand.h" -#include -#include +#include namespace Tor { class GetConfCommand : public TorControlCommand { - Q_OBJECT - Q_DISABLE_COPY(GetConfCommand) - +#ifdef NO_TOR_CONTROL_PROPERTIES Q_PROPERTY(QVariantMap results READ results CONSTANT) +#endif public: enum Type { @@ -57,10 +55,10 @@ public: GetConfCommand(Type type); QByteArray build(const QByteArray &key); - QByteArray build(const QList &keys); + QByteArray build(const std::list &keys); - const QVariantMap &results() const { return m_results; } - QVariant get(const QByteArray &key) const; + const QVariantMap& results() const { return m_results; } + QVariant get(const QByteArray& key) const; protected: virtual void onReply(int statusCode, const QByteArray &data); @@ -69,7 +67,7 @@ protected: private: QVariantMap m_results; - QString m_lastKey; + std::string m_lastKey; }; } diff --git a/retroshare-gui/src/TorControl/HiddenService.cpp b/libretroshare/src/tor/HiddenService.cpp similarity index 98% rename from retroshare-gui/src/TorControl/HiddenService.cpp rename to libretroshare/src/tor/HiddenService.cpp index b2b58626a..6b28ebd6f 100644 --- a/retroshare-gui/src/TorControl/HiddenService.cpp +++ b/libretroshare/src/tor/HiddenService.cpp @@ -90,7 +90,7 @@ void HiddenService::addTarget(quint16 servicePort, QHostAddress targetAddress, q m_targets.append(t); } -void HiddenService::setServiceId(const QByteArray& sid) +void HiddenService::setServiceId(const TorByteArray &sid) { m_service_id = sid; m_hostname = sid + ".onion"; diff --git a/retroshare-gui/src/TorControl/HiddenService.h b/libretroshare/src/tor/HiddenService.h similarity index 72% rename from retroshare-gui/src/TorControl/HiddenService.h rename to libretroshare/src/tor/HiddenService.h index 20fa1d851..19f1e561d 100644 --- a/retroshare-gui/src/TorControl/HiddenService.h +++ b/libretroshare/src/tor/HiddenService.h @@ -33,28 +33,25 @@ #ifndef HIDDENSERVICE_H #define HIDDENSERVICE_H -#include -#include -#include -#include "CryptoKey.h" +#include +#include + +#include "tor/CryptoKey.h" +#include "tor/TorTypes.h" namespace Tor { - class TorSocket; -class HiddenService : public QObject +class HiddenService : public NonCopiable { - Q_OBJECT - Q_DISABLE_COPY(HiddenService) - friend class TorControlPrivate; public: struct Target { - QHostAddress targetAddress; - quint16 servicePort, targetPort; + TorHostAddress targetAddress; + unsigned short servicePort, targetPort; }; enum Status @@ -64,24 +61,25 @@ public: Online /* Published */ }; - HiddenService(QObject *parent = 0); - HiddenService(const QString &dataPath, QObject *parent = 0); - HiddenService(const CryptoKey &privateKey, const QString &dataPath = QString(), QObject *parent = 0); + HiddenService(); + HiddenService(const std::string& dataPath); + HiddenService(const CryptoKey& privateKey, const std::string& dataPath = std::string()); Status status() const { return m_status; } - const QString& hostname() const { return m_hostname; } - const QString serviceId() const { return QString(m_service_id); } - const QString& dataPath() const { return m_dataPath; } + const std::string& hostname() const { return m_hostname; } + const std::string serviceId() const { return std::string(m_service_id.data()); } + const std::string& dataPath() const { return m_dataPath; } CryptoKey privateKey() { return m_privateKey; } void setPrivateKey(const CryptoKey &privateKey); - void setServiceId(const QByteArray& sid); + void setServiceId(const TorByteArray& sid); - const QList &targets() const { return m_targets; } + const std::list& targets() const { return m_targets; } void addTarget(const Target &target); - void addTarget(quint16 servicePort, QHostAddress targetAddress, quint16 targetPort); + void addTarget(unsigned short servicePort, TorHostAddress targetAddress, unsigned short targetPort); +#ifdef NO_TOR_CONTROL_SIGNALS signals: void statusChanged(int newStatus, int oldStatus); void serviceOnline(); @@ -90,14 +88,15 @@ signals: private slots: void servicePublished(); +#endif private: - QString m_dataPath; - QList m_targets; - QString m_hostname; + std::string m_dataPath; + std::list m_targets; + std::string m_hostname; Status m_status; CryptoKey m_privateKey; - QByteArray m_service_id; + TorByteArray m_service_id; void loadPrivateKey(); void setStatus(Status newStatus); diff --git a/retroshare-gui/src/TorControl/PendingOperation.cpp b/libretroshare/src/tor/PendingOperation.cpp similarity index 100% rename from retroshare-gui/src/TorControl/PendingOperation.cpp rename to libretroshare/src/tor/PendingOperation.cpp diff --git a/retroshare-gui/src/TorControl/PendingOperation.h b/libretroshare/src/tor/PendingOperation.h similarity index 100% rename from retroshare-gui/src/TorControl/PendingOperation.h rename to libretroshare/src/tor/PendingOperation.h diff --git a/retroshare-gui/src/TorControl/ProtocolInfoCommand.cpp b/libretroshare/src/tor/ProtocolInfoCommand.cpp similarity index 100% rename from retroshare-gui/src/TorControl/ProtocolInfoCommand.cpp rename to libretroshare/src/tor/ProtocolInfoCommand.cpp diff --git a/retroshare-gui/src/TorControl/ProtocolInfoCommand.h b/libretroshare/src/tor/ProtocolInfoCommand.h similarity index 83% rename from retroshare-gui/src/TorControl/ProtocolInfoCommand.h rename to libretroshare/src/tor/ProtocolInfoCommand.h index 7789cfefd..1ead20d29 100644 --- a/retroshare-gui/src/TorControl/ProtocolInfoCommand.h +++ b/libretroshare/src/tor/ProtocolInfoCommand.h @@ -33,8 +33,17 @@ #ifndef PROTOCOLINFOCOMMAND_H #define PROTOCOLINFOCOMMAND_H +#include #include "TorControlCommand.h" -#include + +enum class AuthMethods: uint8_t +{ + AuthUnknown = 0x0, + AuthNull = 0x1, + AuthHashedPassword = 0x2, + AuthCookie = 0x4 +}; +RS_REGISTER_ENUM_FLAGS_TYPE(AuthMethods) namespace Tor { @@ -43,25 +52,13 @@ class TorControl; class ProtocolInfoCommand : public TorControlCommand { - Q_OBJECT - Q_DISABLE_COPY(ProtocolInfoCommand) - public: - enum AuthMethod - { - AuthUnknown = 0, - AuthNull = 0x1, - AuthHashedPassword = 0x2, - AuthCookie = 0x4 - }; - Q_DECLARE_FLAGS(AuthMethods, AuthMethod) - ProtocolInfoCommand(TorControl *manager); QByteArray build(); AuthMethods authMethods() const { return m_authMethods; } - QString torVersion() const { return m_torVersion; } - QString cookieFile() const { return m_cookieFile; } + std::string torVersion() const { return m_torVersion; } + std::string cookieFile() const { return m_cookieFile; } protected: virtual void onReply(int statusCode, const QByteArray &data); @@ -69,8 +66,8 @@ protected: private: TorControl *manager; AuthMethods m_authMethods; - QString m_torVersion; - QString m_cookieFile; + std::string m_torVersion; + std::string m_cookieFile; }; } diff --git a/retroshare-gui/src/TorControl/SecureRNG.cpp b/libretroshare/src/tor/SecureRNG.cpp similarity index 84% rename from retroshare-gui/src/TorControl/SecureRNG.cpp rename to libretroshare/src/tor/SecureRNG.cpp index 60cf3c048..e07ef8e72 100644 --- a/retroshare-gui/src/TorControl/SecureRNG.cpp +++ b/libretroshare/src/tor/SecureRNG.cpp @@ -31,10 +31,12 @@ */ #include "SecureRNG.h" -#include + #include #include #include +#include +#include #ifdef Q_OS_WIN #include @@ -82,7 +84,7 @@ bool SecureRNG::seed() #else if (!RAND_poll()) { - qWarning() << "OpenSSL RNG seed failed:" << ERR_get_error(); + std::cerr << "OpenSSL RNG seed failed:" << ERR_get_error(); return false; } #endif @@ -94,11 +96,16 @@ bool SecureRNG::seed() return true; } -void SecureRNG::random(char *buf, int size) +void SecureRNG::random(unsigned char *buf, int size) { - int r = RAND_bytes(reinterpret_cast(buf), size); + int r = RAND_bytes(buf, size); + if (r <= 0) - qFatal("RNG failed: %lu", ERR_get_error()); + { + std::ostringstream s; + s << "RNG failed: " << ERR_get_error() ; + throw std::runtime_error(s.str()); + } } QByteArray SecureRNG::random(int size) @@ -111,7 +118,7 @@ QByteArray SecureRNG::random(int size) QByteArray SecureRNG::randomPrintable(int length) { QByteArray re(length, 0); - for (int i = 0; i < re.size(); i++) + for (uint32_t i = 0; i < re.size(); i++) re[i] = randomInt(95) + 32; return re; } @@ -123,24 +130,24 @@ unsigned SecureRNG::randomInt(unsigned max) for (;;) { - random(reinterpret_cast(&value), sizeof(value)); + random(reinterpret_cast(&value), sizeof(value)); if (value < cutoff) return value % max; } } #ifndef UINT64_MAX -#define UINT64_MAX ((quint64)-1) +#define UINT64_MAX ((uint64_t)-1) #endif -quint64 SecureRNG::randomInt64(quint64 max) +uint64_t SecureRNG::randomInt64(uint64_t max) { - quint64 cutoff = UINT64_MAX - (UINT64_MAX % max); - quint64 value = 0; + uint64_t cutoff = UINT64_MAX - (UINT64_MAX % max); + uint64_t value = 0; for (;;) { - random(reinterpret_cast(value), sizeof(value)); + random(reinterpret_cast(value), sizeof(value)); if (value < cutoff) return value % max; } diff --git a/retroshare-gui/src/TorControl/SecureRNG.h b/libretroshare/src/tor/SecureRNG.h similarity index 88% rename from retroshare-gui/src/TorControl/SecureRNG.h rename to libretroshare/src/tor/SecureRNG.h index f3b2a4b64..cce43cec5 100644 --- a/retroshare-gui/src/TorControl/SecureRNG.h +++ b/libretroshare/src/tor/SecureRNG.h @@ -33,19 +33,19 @@ #ifndef SECURERNG_H #define SECURERNG_H -#include +#include "TorTypes.h" class SecureRNG { public: static bool seed(); - static void random(char *buf, int size); - static QByteArray random(int size); + static void random(unsigned char *buf, int size); + static Tor::TorByteArray random(int size); - static QByteArray randomPrintable(int length); + static Tor::TorByteArray randomPrintable(int length); static unsigned randomInt(unsigned max); - static quint64 randomInt64(quint64 max); + static uint64_t randomInt64(uint64_t max); }; #endif // SECURERNG_H diff --git a/retroshare-gui/src/TorControl/SetConfCommand.cpp b/libretroshare/src/tor/SetConfCommand.cpp similarity index 100% rename from retroshare-gui/src/TorControl/SetConfCommand.cpp rename to libretroshare/src/tor/SetConfCommand.cpp diff --git a/retroshare-gui/src/TorControl/SetConfCommand.h b/libretroshare/src/tor/SetConfCommand.h similarity index 100% rename from retroshare-gui/src/TorControl/SetConfCommand.h rename to libretroshare/src/tor/SetConfCommand.h diff --git a/retroshare-gui/src/TorControl/Settings.cpp b/libretroshare/src/tor/Settings.cpp similarity index 100% rename from retroshare-gui/src/TorControl/Settings.cpp rename to libretroshare/src/tor/Settings.cpp diff --git a/retroshare-gui/src/TorControl/Settings.h b/libretroshare/src/tor/Settings.h similarity index 100% rename from retroshare-gui/src/TorControl/Settings.h rename to libretroshare/src/tor/Settings.h diff --git a/retroshare-gui/src/TorControl/StrUtil.cpp b/libretroshare/src/tor/StrUtil.cpp similarity index 91% rename from retroshare-gui/src/TorControl/StrUtil.cpp rename to libretroshare/src/tor/StrUtil.cpp index 81de151b0..b78b50ae5 100644 --- a/retroshare-gui/src/TorControl/StrUtil.cpp +++ b/libretroshare/src/tor/StrUtil.cpp @@ -32,14 +32,14 @@ #include "StrUtil.h" -QByteArray quotedString(const QByteArray &string) +QByteArray quotedString(const QByteArray& string) { QByteArray out; out.reserve(string.size() * 2); - out.append('"'); + out += '"'; - for (int i = 0; i < string.size(); ++i) + for (uint32_t i = 0; i < string.size(); ++i) { switch (string[i]) { @@ -67,7 +67,7 @@ QByteArray unquotedString(const QByteArray &string) QByteArray out; out.reserve(string.size() - 2); - for (int i = 1; i < string.size(); ++i) + for (uint32_t i = 1; i < string.size(); ++i) { switch (string[i]) { @@ -85,9 +85,9 @@ QByteArray unquotedString(const QByteArray &string) return out; } -QList splitQuotedStrings(const QByteArray &input, char separator) +std::list splitQuotedStrings(const QByteArray &input, char separator) { - QList out; + std::list out; bool inquote = false; int start = 0; diff --git a/retroshare-gui/src/TorControl/StrUtil.h b/libretroshare/src/tor/StrUtil.h similarity index 94% rename from retroshare-gui/src/TorControl/StrUtil.h rename to libretroshare/src/tor/StrUtil.h index c86d2c6ec..ba9b5ac3a 100644 --- a/retroshare-gui/src/TorControl/StrUtil.h +++ b/libretroshare/src/tor/StrUtil.h @@ -33,14 +33,14 @@ #ifndef STRINGUTIL_H #define STRINGUTIL_H -#include -#include +#include "TorTypes.h" +#include QByteArray quotedString(const QByteArray &string); /* Return the unquoted contents of a string, either until an end quote or an unescaped separator character. */ QByteArray unquotedString(const QByteArray &string); -QList splitQuotedStrings(const QByteArray &input, char separator); +std::list splitQuotedStrings(const QByteArray &input, char separator); #endif // STRINGUTIL_H diff --git a/retroshare-gui/src/TorControl/TorControl.cpp b/libretroshare/src/tor/TorControl.cpp similarity index 100% rename from retroshare-gui/src/TorControl/TorControl.cpp rename to libretroshare/src/tor/TorControl.cpp diff --git a/retroshare-gui/src/TorControl/TorControl.h b/libretroshare/src/tor/TorControl.h similarity index 100% rename from retroshare-gui/src/TorControl/TorControl.h rename to libretroshare/src/tor/TorControl.h diff --git a/retroshare-gui/src/TorControl/TorControlCommand.cpp b/libretroshare/src/tor/TorControlCommand.cpp similarity index 100% rename from retroshare-gui/src/TorControl/TorControlCommand.cpp rename to libretroshare/src/tor/TorControlCommand.cpp diff --git a/retroshare-gui/src/TorControl/TorControlCommand.h b/libretroshare/src/tor/TorControlCommand.h similarity index 85% rename from retroshare-gui/src/TorControl/TorControlCommand.h rename to libretroshare/src/tor/TorControlCommand.h index 894381054..6c8693682 100644 --- a/retroshare-gui/src/TorControl/TorControlCommand.h +++ b/libretroshare/src/tor/TorControlCommand.h @@ -33,32 +33,31 @@ #ifndef TORCONTROLCOMMAND_H #define TORCONTROLCOMMAND_H -#include -#include +#include +#include "tor/TorTypes.h" namespace Tor { - -class TorControlCommand : public QObject +class TorControlCommand : public NonCopiable { - Q_OBJECT - Q_DISABLE_COPY(TorControlCommand) - friend class TorControlSocket; public: TorControlCommand(); + virtual ~TorControlCommand() {} int statusCode() const { return m_finalStatus; } +#ifdef NO_TOR_CONTROL_SIGNALS signals: - void replyLine(int statusCode, const QByteArray &data); + void replyLine(int statusCode, const TorByteArray& data); void finished(); +#endif protected: - virtual void onReply(int statusCode, const QByteArray &data); + virtual void onReply(int statusCode, const TorByteArray& data); virtual void onFinished(int statusCode); - virtual void onDataLine(const QByteArray &data); + virtual void onDataLine(const TorByteArray& data); virtual void onDataFinished(); private: diff --git a/retroshare-gui/src/TorControl/TorControlSocket.cpp b/libretroshare/src/tor/TorControlSocket.cpp similarity index 100% rename from retroshare-gui/src/TorControl/TorControlSocket.cpp rename to libretroshare/src/tor/TorControlSocket.cpp diff --git a/retroshare-gui/src/TorControl/TorControlSocket.h b/libretroshare/src/tor/TorControlSocket.h similarity index 100% rename from retroshare-gui/src/TorControl/TorControlSocket.h rename to libretroshare/src/tor/TorControlSocket.h diff --git a/retroshare-gui/src/TorControl/TorManager.cpp b/libretroshare/src/tor/TorManager.cpp similarity index 100% rename from retroshare-gui/src/TorControl/TorManager.cpp rename to libretroshare/src/tor/TorManager.cpp diff --git a/retroshare-gui/src/TorControl/TorManager.h b/libretroshare/src/tor/TorManager.h similarity index 100% rename from retroshare-gui/src/TorControl/TorManager.h rename to libretroshare/src/tor/TorManager.h diff --git a/retroshare-gui/src/TorControl/TorProcess.cpp b/libretroshare/src/tor/TorProcess.cpp similarity index 100% rename from retroshare-gui/src/TorControl/TorProcess.cpp rename to libretroshare/src/tor/TorProcess.cpp diff --git a/retroshare-gui/src/TorControl/TorProcess.h b/libretroshare/src/tor/TorProcess.h similarity index 100% rename from retroshare-gui/src/TorControl/TorProcess.h rename to libretroshare/src/tor/TorProcess.h diff --git a/retroshare-gui/src/TorControl/TorProcess_p.h b/libretroshare/src/tor/TorProcess_p.h similarity index 100% rename from retroshare-gui/src/TorControl/TorProcess_p.h rename to libretroshare/src/tor/TorProcess_p.h diff --git a/retroshare-gui/src/TorControl/TorSocket.cpp b/libretroshare/src/tor/TorSocket.cpp similarity index 100% rename from retroshare-gui/src/TorControl/TorSocket.cpp rename to libretroshare/src/tor/TorSocket.cpp diff --git a/retroshare-gui/src/TorControl/TorSocket.h b/libretroshare/src/tor/TorSocket.h similarity index 100% rename from retroshare-gui/src/TorControl/TorSocket.h rename to libretroshare/src/tor/TorSocket.h diff --git a/libretroshare/src/tor/TorTypes.h b/libretroshare/src/tor/TorTypes.h new file mode 100644 index 000000000..a3ebb523a --- /dev/null +++ b/libretroshare/src/tor/TorTypes.h @@ -0,0 +1,112 @@ +#pragma once + +#include +#include + +namespace Tor +{ + +class NonCopiable { +public: + NonCopiable(){} + virtual ~NonCopiable()=default; +private: + NonCopiable(const NonCopiable& nc) {} + virtual NonCopiable& operator=(const NonCopiable& nc) { return *this ; } +}; + +class TorByteArray: public std::vector +{ +public: + TorByteArray(const std::string& s = std::string()) + { + clear(); + for(uint32_t i=0;i size()) + return false; + + for(uint32_t i=0;i size()) + return false; + + for(uint32_t i=0;i Date: Fri, 25 Jun 2021 21:46:00 +0200 Subject: [PATCH 02/65] keeping Qt internally for a while and making RsTor Qt-free --- libretroshare/src/libretroshare.pro | 9 ++- libretroshare/src/retroshare/rsevents.h | 5 +- libretroshare/src/tor/AddOnionCommand.h | 17 ++--- libretroshare/src/tor/CryptoKey.cpp | 46 ++++++------ libretroshare/src/tor/CryptoKey.h | 15 ++-- libretroshare/src/tor/GetConfCommand.cpp | 25 +++---- libretroshare/src/tor/GetConfCommand.h | 16 +++-- libretroshare/src/tor/HiddenService.cpp | 2 +- libretroshare/src/tor/HiddenService.h | 47 ++++++------ libretroshare/src/tor/ProtocolInfoCommand.h | 31 ++++---- libretroshare/src/tor/SecureRNG.cpp | 31 ++++---- libretroshare/src/tor/SecureRNG.h | 10 +-- libretroshare/src/tor/StrUtil.cpp | 12 ++-- libretroshare/src/tor/StrUtil.h | 6 +- libretroshare/src/tor/TorControlCommand.h | 19 ++--- libretroshare/src/tor/TorManager.cpp | 49 +++++++++++-- libretroshare/src/tor/TorManager.h | 7 +- libretroshare/src/tor/TorTypes.h | 80 ++++++++++++++------- retroshare-gui/src/gui/GenCertDialog.cpp | 12 ++-- retroshare-gui/src/main.cpp | 2 +- 20 files changed, 258 insertions(+), 183 deletions(-) diff --git a/libretroshare/src/libretroshare.pro b/libretroshare/src/libretroshare.pro index 5276bda9b..0d3889708 100644 --- a/libretroshare/src/libretroshare.pro +++ b/libretroshare/src/libretroshare.pro @@ -9,13 +9,18 @@ libretroshare_shared { } else { CONFIG += staticlib } -CONFIG -= qt +CONFIG += qt + +QT += network + TARGET = retroshare TARGET_PRL = libretroshare DESTDIR = lib !include("use_libretroshare.pri"):error("Including") +QMAKE_CXXFLAGS += -fPIC + # treat warnings as error for better removing #QMAKE_CFLAGS += -Werror #QMAKE_CXXFLAGS += -Werror @@ -720,6 +725,8 @@ SOURCES += rsitems/rsnxsitems.cc \ gxs/rsgxsrequesttypes.cc # Tor +HEADERS += retroshare/rstor.h + HEADERS += tor/AddOnionCommand.h \ tor/AuthenticateCommand.h \ tor/CryptoKey.h \ diff --git a/libretroshare/src/retroshare/rsevents.h b/libretroshare/src/retroshare/rsevents.h index ec2e7b97f..a1ea3b399 100644 --- a/libretroshare/src/retroshare/rsevents.h +++ b/libretroshare/src/retroshare/rsevents.h @@ -103,7 +103,10 @@ enum class RsEventType : uint32_t /// @see rspeers.h NETWORK = 16, - __MAX /// Used internally, keep last + /// @see rspeers.h + TOR_MANAGER = 17, + + __MAX /// Used internally, keep last }; enum class RsEventsErrorNum : int32_t diff --git a/libretroshare/src/tor/AddOnionCommand.h b/libretroshare/src/tor/AddOnionCommand.h index a51888b2f..7c0afaf5e 100644 --- a/libretroshare/src/tor/AddOnionCommand.h +++ b/libretroshare/src/tor/AddOnionCommand.h @@ -34,7 +34,9 @@ #define ADDONIONCOMMAND_H #include "TorControlCommand.h" -#include +#include +#include +#include namespace Tor { @@ -43,28 +45,27 @@ class HiddenService; class AddOnionCommand : public TorControlCommand { -#ifdef NO_TOR_CONTROL_PROPERTIES - Q_PROPERTY(std::string errorMessage READ errorMessage CONSTANT) + Q_OBJECT + Q_DISABLE_COPY(AddOnionCommand) + + Q_PROPERTY(QString errorMessage READ errorMessage CONSTANT) Q_PROPERTY(bool successful READ isSuccessful CONSTANT) -#endif public: AddOnionCommand(HiddenService *service); QByteArray build(); - std::string errorMessage() const { return m_errorMessage; } + QString errorMessage() const { return m_errorMessage; } bool isSuccessful() const; -#ifdef NO_TOR_CONTROL_SIGNALS signals: void succeeded(); void failed(int code); -#endif protected: HiddenService *m_service; - std::string m_errorMessage; + QString m_errorMessage; virtual void onReply(int statusCode, const QByteArray &data); virtual void onFinished(int statusCode); diff --git a/libretroshare/src/tor/CryptoKey.cpp b/libretroshare/src/tor/CryptoKey.cpp index d5b66c988..9be9a6699 100644 --- a/libretroshare/src/tor/CryptoKey.cpp +++ b/libretroshare/src/tor/CryptoKey.cpp @@ -31,13 +31,13 @@ */ #include -#include #include "CryptoKey.h" #include "SecureRNG.h" #include "Useful.h" -#include "TorTypes.h" - +#include +#include +#include #include #include #include @@ -120,23 +120,17 @@ bool CryptoKey::loadFromData(const QByteArray &data, KeyType type, KeyFormat for } #endif -bool CryptoKey::loadFromFile(const std::string &path) +bool CryptoKey::loadFromFile(const QString& path) { - FILE *f = fopen(path.c_str(),"r"); - - if(!f) + QFile file(path); + if (!file.open(QIODevice::ReadOnly)) { - std::cerr << "Failed to open Tor key file " << path << std::endl; + qWarning() << "Failed to open Tor key file " << path << ": " << file.errorString(); return false; } - Tor::TorByteArray data ; - int c; - - while( EOF != (c=fgetc(f))) - data += (unsigned char)c; - - fclose(f); + QByteArray data = file.readAll(); + file.close(); if(data.contains("-----BEGIN RSA PRIVATE KEY-----")) { @@ -152,14 +146,14 @@ bool CryptoKey::loadFromFile(const std::string &path) } std::cerr << "Have read the following key: " << std::endl; - std::cerr << data.toStdString() << std::endl; + std::cerr << QString(data).toStdString() << std::endl; key_data = data; return true; } -bool CryptoKey::loadFromTorMessage(const Tor::TorByteArray& b) +bool CryptoKey::loadFromTorMessage(const QByteArray& b) { // note: We should probably check the structure a bit more, for security. @@ -169,7 +163,7 @@ bool CryptoKey::loadFromTorMessage(const Tor::TorByteArray& b) std::cerr << " type: RSA-1024 (Tor v2)" << std::endl; else if(b.startsWith("ED25519-V3")) std::cerr << " type: ED25519-V3 (Tor v3)" << std::endl; - else if(b.indexOf(':') >= 0) + else if(b.indexOf(':')) { std::cerr << " unknown type, or bad syntax in key: \"" << b.left(b.indexOf(':')).toStdString() << "\". Not accepted." << std::endl; return false; @@ -180,22 +174,22 @@ bool CryptoKey::loadFromTorMessage(const Tor::TorByteArray& b) } /* Cryptographic hash of a password as expected by Tor's HashedControlPassword */ -Tor::TorByteArray torControlHashedPassword(const Tor::TorByteArray& password) +QByteArray torControlHashedPassword(const QByteArray &password) { - Tor::TorByteArray salt = SecureRNG::random(8); + QByteArray salt = SecureRNG::random(8); if (salt.isNull()) - return Tor::TorByteArray(); + return QByteArray(); int count = ((quint32)16 + (96 & 15)) << ((96 >> 4) + 6); SHA_CTX hash; SHA1_Init(&hash); - Tor::TorByteArray tmp = salt + password; + QByteArray tmp = salt + password; while (count) { - int c = std::min(count, tmp.size()); - SHA1_Update(&hash, reinterpret_cast(tmp.data()), c); + int c = qMin(count, tmp.size()); + SHA1_Update(&hash, reinterpret_cast(tmp.constData()), c); count -= c; } @@ -203,8 +197,8 @@ Tor::TorByteArray torControlHashedPassword(const Tor::TorByteArray& password) SHA1_Final(md, &hash); /* 60 is the hex-encoded value of 96, which is a constant used by Tor's algorithm. */ - return Tor::TorByteArray("16:") + salt.toHex().toUpper() + Tor::TorByteArray("60") + - Tor::TorByteArray::fromRawData(reinterpret_cast(md), 20).toHex().toUpper(); + return QByteArray("16:") + salt.toHex().toUpper() + QByteArray("60") + + QByteArray::fromRawData(reinterpret_cast(md), 20).toHex().toUpper(); } diff --git a/libretroshare/src/tor/CryptoKey.h b/libretroshare/src/tor/CryptoKey.h index 57c22476f..c99703444 100644 --- a/libretroshare/src/tor/CryptoKey.h +++ b/libretroshare/src/tor/CryptoKey.h @@ -33,7 +33,9 @@ #ifndef CRYPTOKEY_H #define CRYPTOKEY_H -#include "tor/TorTypes.h" +#include +#include +#include class CryptoKey { @@ -55,13 +57,12 @@ public: bool loadFromData(const QByteArray &data, KeyType type, KeyFormat format = PEM); bool loadFromFile(const QString &path, KeyType type, KeyFormat format = PEM); #endif - bool loadFromFile(const std::string& path); + bool loadFromFile(const QString &path); void clear(); - const Tor::TorByteArray& bytes() const { return key_data; } - bool loadFromTorMessage(const Tor::TorByteArray& b); - bool isLoaded() const { return !key_data.empty(); } - + const QByteArray bytes() const { return key_data; } + bool loadFromTorMessage(const QByteArray& b); + bool isLoaded() const { return !key_data.isNull(); } #ifdef TO_REMOVE bool isPrivate() const; @@ -100,6 +101,6 @@ private: #endif }; -Tor::TorByteArray torControlHashedPassword(const Tor::TorByteArray& password); +QByteArray torControlHashedPassword(const QByteArray &password); #endif // CRYPTOKEY_H diff --git a/libretroshare/src/tor/GetConfCommand.cpp b/libretroshare/src/tor/GetConfCommand.cpp index 7da0a46cc..933def562 100644 --- a/libretroshare/src/tor/GetConfCommand.cpp +++ b/libretroshare/src/tor/GetConfCommand.cpp @@ -30,11 +30,9 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#include - -#include "TorTypes.h" #include "GetConfCommand.h" #include "StrUtil.h" +#include using namespace Tor; @@ -45,28 +43,27 @@ GetConfCommand::GetConfCommand(Type t) QByteArray GetConfCommand::build(const QByteArray &key) { - return build(std::list{key}); + return build(QList() << key); } -QByteArray GetConfCommand::build(const std::list &keys) +QByteArray GetConfCommand::build(const QList &keys) { QByteArray out; if (type == GetConf) { - out = QByteArray("GETCONF"); + out = "GETCONF"; } else if (type == GetInfo) { - out = QByteArray("GETINFO"); + out = "GETINFO"; } else { - throw std::runtime_error("Unsupported build type in GetConfCommand"); + Q_ASSERT(false); return out; } - for(const QByteArray& key: keys) - { - out += (' '); - out += key; + foreach (const QByteArray &key, keys) { + out.append(' '); + out.append(key); } - out += std::string("\r\n"); + out.append("\r\n"); return out; } @@ -77,7 +74,7 @@ void GetConfCommand::onReply(int statusCode, const QByteArray &data) return; int kep = data.indexOf('='); - std::string key = QString::fromLatin1(data.mid(0, kep)); + QString key = QString::fromLatin1(data.mid(0, kep)); QVariant value; if (kep >= 0) value = QString::fromLatin1(unquotedString(data.mid(kep + 1))); diff --git a/libretroshare/src/tor/GetConfCommand.h b/libretroshare/src/tor/GetConfCommand.h index 0289d5e40..0de97d1b7 100644 --- a/libretroshare/src/tor/GetConfCommand.h +++ b/libretroshare/src/tor/GetConfCommand.h @@ -34,16 +34,18 @@ #define GETCONFCOMMAND_H #include "TorControlCommand.h" -#include +#include +#include namespace Tor { class GetConfCommand : public TorControlCommand { -#ifdef NO_TOR_CONTROL_PROPERTIES + Q_OBJECT + Q_DISABLE_COPY(GetConfCommand) + Q_PROPERTY(QVariantMap results READ results CONSTANT) -#endif public: enum Type { @@ -55,10 +57,10 @@ public: GetConfCommand(Type type); QByteArray build(const QByteArray &key); - QByteArray build(const std::list &keys); + QByteArray build(const QList &keys); - const QVariantMap& results() const { return m_results; } - QVariant get(const QByteArray& key) const; + const QVariantMap &results() const { return m_results; } + QVariant get(const QByteArray &key) const; protected: virtual void onReply(int statusCode, const QByteArray &data); @@ -67,7 +69,7 @@ protected: private: QVariantMap m_results; - std::string m_lastKey; + QString m_lastKey; }; } diff --git a/libretroshare/src/tor/HiddenService.cpp b/libretroshare/src/tor/HiddenService.cpp index 6b28ebd6f..b2b58626a 100644 --- a/libretroshare/src/tor/HiddenService.cpp +++ b/libretroshare/src/tor/HiddenService.cpp @@ -90,7 +90,7 @@ void HiddenService::addTarget(quint16 servicePort, QHostAddress targetAddress, q m_targets.append(t); } -void HiddenService::setServiceId(const TorByteArray &sid) +void HiddenService::setServiceId(const QByteArray& sid) { m_service_id = sid; m_hostname = sid + ".onion"; diff --git a/libretroshare/src/tor/HiddenService.h b/libretroshare/src/tor/HiddenService.h index 19f1e561d..20fa1d851 100644 --- a/libretroshare/src/tor/HiddenService.h +++ b/libretroshare/src/tor/HiddenService.h @@ -33,25 +33,28 @@ #ifndef HIDDENSERVICE_H #define HIDDENSERVICE_H -#include -#include - -#include "tor/CryptoKey.h" -#include "tor/TorTypes.h" +#include +#include +#include +#include "CryptoKey.h" namespace Tor { + class TorSocket; -class HiddenService : public NonCopiable +class HiddenService : public QObject { + Q_OBJECT + Q_DISABLE_COPY(HiddenService) + friend class TorControlPrivate; public: struct Target { - TorHostAddress targetAddress; - unsigned short servicePort, targetPort; + QHostAddress targetAddress; + quint16 servicePort, targetPort; }; enum Status @@ -61,25 +64,24 @@ public: Online /* Published */ }; - HiddenService(); - HiddenService(const std::string& dataPath); - HiddenService(const CryptoKey& privateKey, const std::string& dataPath = std::string()); + HiddenService(QObject *parent = 0); + HiddenService(const QString &dataPath, QObject *parent = 0); + HiddenService(const CryptoKey &privateKey, const QString &dataPath = QString(), QObject *parent = 0); Status status() const { return m_status; } - const std::string& hostname() const { return m_hostname; } - const std::string serviceId() const { return std::string(m_service_id.data()); } - const std::string& dataPath() const { return m_dataPath; } + const QString& hostname() const { return m_hostname; } + const QString serviceId() const { return QString(m_service_id); } + const QString& dataPath() const { return m_dataPath; } CryptoKey privateKey() { return m_privateKey; } void setPrivateKey(const CryptoKey &privateKey); - void setServiceId(const TorByteArray& sid); + void setServiceId(const QByteArray& sid); - const std::list& targets() const { return m_targets; } + const QList &targets() const { return m_targets; } void addTarget(const Target &target); - void addTarget(unsigned short servicePort, TorHostAddress targetAddress, unsigned short targetPort); + void addTarget(quint16 servicePort, QHostAddress targetAddress, quint16 targetPort); -#ifdef NO_TOR_CONTROL_SIGNALS signals: void statusChanged(int newStatus, int oldStatus); void serviceOnline(); @@ -88,15 +90,14 @@ signals: private slots: void servicePublished(); -#endif private: - std::string m_dataPath; - std::list m_targets; - std::string m_hostname; + QString m_dataPath; + QList m_targets; + QString m_hostname; Status m_status; CryptoKey m_privateKey; - TorByteArray m_service_id; + QByteArray m_service_id; void loadPrivateKey(); void setStatus(Status newStatus); diff --git a/libretroshare/src/tor/ProtocolInfoCommand.h b/libretroshare/src/tor/ProtocolInfoCommand.h index 1ead20d29..7789cfefd 100644 --- a/libretroshare/src/tor/ProtocolInfoCommand.h +++ b/libretroshare/src/tor/ProtocolInfoCommand.h @@ -33,17 +33,8 @@ #ifndef PROTOCOLINFOCOMMAND_H #define PROTOCOLINFOCOMMAND_H -#include #include "TorControlCommand.h" - -enum class AuthMethods: uint8_t -{ - AuthUnknown = 0x0, - AuthNull = 0x1, - AuthHashedPassword = 0x2, - AuthCookie = 0x4 -}; -RS_REGISTER_ENUM_FLAGS_TYPE(AuthMethods) +#include namespace Tor { @@ -52,13 +43,25 @@ class TorControl; class ProtocolInfoCommand : public TorControlCommand { + Q_OBJECT + Q_DISABLE_COPY(ProtocolInfoCommand) + public: + enum AuthMethod + { + AuthUnknown = 0, + AuthNull = 0x1, + AuthHashedPassword = 0x2, + AuthCookie = 0x4 + }; + Q_DECLARE_FLAGS(AuthMethods, AuthMethod) + ProtocolInfoCommand(TorControl *manager); QByteArray build(); AuthMethods authMethods() const { return m_authMethods; } - std::string torVersion() const { return m_torVersion; } - std::string cookieFile() const { return m_cookieFile; } + QString torVersion() const { return m_torVersion; } + QString cookieFile() const { return m_cookieFile; } protected: virtual void onReply(int statusCode, const QByteArray &data); @@ -66,8 +69,8 @@ protected: private: TorControl *manager; AuthMethods m_authMethods; - std::string m_torVersion; - std::string m_cookieFile; + QString m_torVersion; + QString m_cookieFile; }; } diff --git a/libretroshare/src/tor/SecureRNG.cpp b/libretroshare/src/tor/SecureRNG.cpp index e07ef8e72..60cf3c048 100644 --- a/libretroshare/src/tor/SecureRNG.cpp +++ b/libretroshare/src/tor/SecureRNG.cpp @@ -31,12 +31,10 @@ */ #include "SecureRNG.h" - +#include #include #include #include -#include -#include #ifdef Q_OS_WIN #include @@ -84,7 +82,7 @@ bool SecureRNG::seed() #else if (!RAND_poll()) { - std::cerr << "OpenSSL RNG seed failed:" << ERR_get_error(); + qWarning() << "OpenSSL RNG seed failed:" << ERR_get_error(); return false; } #endif @@ -96,16 +94,11 @@ bool SecureRNG::seed() return true; } -void SecureRNG::random(unsigned char *buf, int size) +void SecureRNG::random(char *buf, int size) { - int r = RAND_bytes(buf, size); - + int r = RAND_bytes(reinterpret_cast(buf), size); if (r <= 0) - { - std::ostringstream s; - s << "RNG failed: " << ERR_get_error() ; - throw std::runtime_error(s.str()); - } + qFatal("RNG failed: %lu", ERR_get_error()); } QByteArray SecureRNG::random(int size) @@ -118,7 +111,7 @@ QByteArray SecureRNG::random(int size) QByteArray SecureRNG::randomPrintable(int length) { QByteArray re(length, 0); - for (uint32_t i = 0; i < re.size(); i++) + for (int i = 0; i < re.size(); i++) re[i] = randomInt(95) + 32; return re; } @@ -130,24 +123,24 @@ unsigned SecureRNG::randomInt(unsigned max) for (;;) { - random(reinterpret_cast(&value), sizeof(value)); + random(reinterpret_cast(&value), sizeof(value)); if (value < cutoff) return value % max; } } #ifndef UINT64_MAX -#define UINT64_MAX ((uint64_t)-1) +#define UINT64_MAX ((quint64)-1) #endif -uint64_t SecureRNG::randomInt64(uint64_t max) +quint64 SecureRNG::randomInt64(quint64 max) { - uint64_t cutoff = UINT64_MAX - (UINT64_MAX % max); - uint64_t value = 0; + quint64 cutoff = UINT64_MAX - (UINT64_MAX % max); + quint64 value = 0; for (;;) { - random(reinterpret_cast(value), sizeof(value)); + random(reinterpret_cast(value), sizeof(value)); if (value < cutoff) return value % max; } diff --git a/libretroshare/src/tor/SecureRNG.h b/libretroshare/src/tor/SecureRNG.h index cce43cec5..f3b2a4b64 100644 --- a/libretroshare/src/tor/SecureRNG.h +++ b/libretroshare/src/tor/SecureRNG.h @@ -33,19 +33,19 @@ #ifndef SECURERNG_H #define SECURERNG_H -#include "TorTypes.h" +#include class SecureRNG { public: static bool seed(); - static void random(unsigned char *buf, int size); - static Tor::TorByteArray random(int size); + static void random(char *buf, int size); + static QByteArray random(int size); - static Tor::TorByteArray randomPrintable(int length); + static QByteArray randomPrintable(int length); static unsigned randomInt(unsigned max); - static uint64_t randomInt64(uint64_t max); + static quint64 randomInt64(quint64 max); }; #endif // SECURERNG_H diff --git a/libretroshare/src/tor/StrUtil.cpp b/libretroshare/src/tor/StrUtil.cpp index b78b50ae5..81de151b0 100644 --- a/libretroshare/src/tor/StrUtil.cpp +++ b/libretroshare/src/tor/StrUtil.cpp @@ -32,14 +32,14 @@ #include "StrUtil.h" -QByteArray quotedString(const QByteArray& string) +QByteArray quotedString(const QByteArray &string) { QByteArray out; out.reserve(string.size() * 2); - out += '"'; + out.append('"'); - for (uint32_t i = 0; i < string.size(); ++i) + for (int i = 0; i < string.size(); ++i) { switch (string[i]) { @@ -67,7 +67,7 @@ QByteArray unquotedString(const QByteArray &string) QByteArray out; out.reserve(string.size() - 2); - for (uint32_t i = 1; i < string.size(); ++i) + for (int i = 1; i < string.size(); ++i) { switch (string[i]) { @@ -85,9 +85,9 @@ QByteArray unquotedString(const QByteArray &string) return out; } -std::list splitQuotedStrings(const QByteArray &input, char separator) +QList splitQuotedStrings(const QByteArray &input, char separator) { - std::list out; + QList out; bool inquote = false; int start = 0; diff --git a/libretroshare/src/tor/StrUtil.h b/libretroshare/src/tor/StrUtil.h index ba9b5ac3a..c86d2c6ec 100644 --- a/libretroshare/src/tor/StrUtil.h +++ b/libretroshare/src/tor/StrUtil.h @@ -33,14 +33,14 @@ #ifndef STRINGUTIL_H #define STRINGUTIL_H -#include "TorTypes.h" -#include +#include +#include QByteArray quotedString(const QByteArray &string); /* Return the unquoted contents of a string, either until an end quote or an unescaped separator character. */ QByteArray unquotedString(const QByteArray &string); -std::list splitQuotedStrings(const QByteArray &input, char separator); +QList splitQuotedStrings(const QByteArray &input, char separator); #endif // STRINGUTIL_H diff --git a/libretroshare/src/tor/TorControlCommand.h b/libretroshare/src/tor/TorControlCommand.h index 6c8693682..894381054 100644 --- a/libretroshare/src/tor/TorControlCommand.h +++ b/libretroshare/src/tor/TorControlCommand.h @@ -33,31 +33,32 @@ #ifndef TORCONTROLCOMMAND_H #define TORCONTROLCOMMAND_H -#include -#include "tor/TorTypes.h" +#include +#include namespace Tor { -class TorControlCommand : public NonCopiable + +class TorControlCommand : public QObject { + Q_OBJECT + Q_DISABLE_COPY(TorControlCommand) + friend class TorControlSocket; public: TorControlCommand(); - virtual ~TorControlCommand() {} int statusCode() const { return m_finalStatus; } -#ifdef NO_TOR_CONTROL_SIGNALS signals: - void replyLine(int statusCode, const TorByteArray& data); + void replyLine(int statusCode, const QByteArray &data); void finished(); -#endif protected: - virtual void onReply(int statusCode, const TorByteArray& data); + virtual void onReply(int statusCode, const QByteArray &data); virtual void onFinished(int statusCode); - virtual void onDataLine(const TorByteArray& data); + virtual void onDataLine(const QByteArray &data); virtual void onDataFinished(); private: diff --git a/libretroshare/src/tor/TorManager.cpp b/libretroshare/src/tor/TorManager.cpp index 9f31777e6..a9daa8986 100644 --- a/libretroshare/src/tor/TorManager.cpp +++ b/libretroshare/src/tor/TorManager.cpp @@ -118,11 +118,6 @@ TorProcess *TorManager::process() return d->process; } -bool TorManager::isTorAvailable() -{ - return !instance()->d->torExecutablePath().isNull(); -} - QString TorManager::torDataDirectory() const { return d->dataDir; @@ -524,3 +519,47 @@ void TorManagerPrivate::setError(const QString &message) #include "TorManager.moc" +bool RsTor::isTorAvailable() +{ + return !instance()->d->torExecutablePath().isNull(); +} + +bool RsTor::getHiddenServiceInfo(std::string& service_id, + std::string& service_onion_address, + uint16_t& service_port, + std::string& service_target_address, + uint16_t& target_port) +{ + QString sid; + QString soa; + QHostAddress sta; + + if(!instance()->getHiddenServiceInfo(sid,soa,service_port,sta,target_port)) + return false; + + service_id = sid.toStdString(); + service_onion_address = soa.toStdString(); + service_target_address = sta.toString().toStdString(); + + return true; +} + +std::list RsTor::logMessages() +{ + QStringList qs = instance()->logMessages(); + + std::list s; + for(auto& ss:qs) + s.push_back(ss.toStdString()); + + return s; +} + +std::string RsTor::socksAddress() +{ + return instance()->control()->socksAddress().toString().toStdString(); +} +uint16_t RsTor::socksPort() +{ + return instance()->control()->socksPort(); +} diff --git a/libretroshare/src/tor/TorManager.h b/libretroshare/src/tor/TorManager.h index e9acc1208..9d3dd388d 100644 --- a/libretroshare/src/tor/TorManager.h +++ b/libretroshare/src/tor/TorManager.h @@ -35,6 +35,8 @@ #ifndef TORMANAGER_H #define TORMANAGER_H +#include "retroshare/rstor.h" + #include #include #include @@ -48,7 +50,8 @@ class TorManagerPrivate; /* Run/connect to an instance of Tor according to configuration, and manage * UI interaction, first time configuration, etc. */ -class TorManager : public QObject + +class TorManager : public QObject, public RsTor { Q_OBJECT @@ -61,7 +64,6 @@ class TorManager : public QObject Q_PROPERTY(QString torDataDirectory READ torDataDirectory WRITE setTorDataDirectory) public: - static bool isTorAvailable() ; static TorManager *instance(); TorProcess *process(); @@ -103,6 +105,7 @@ signals: private: explicit TorManager(QObject *parent = 0); TorManagerPrivate *d; + friend class RsTor; }; } diff --git a/libretroshare/src/tor/TorTypes.h b/libretroshare/src/tor/TorTypes.h index a3ebb523a..393e6a849 100644 --- a/libretroshare/src/tor/TorTypes.h +++ b/libretroshare/src/tor/TorTypes.h @@ -1,7 +1,9 @@ #pragma once #include +#include #include +#include namespace Tor { @@ -18,7 +20,13 @@ private: class TorByteArray: public std::vector { public: - TorByteArray(const std::string& s = std::string()) + TorByteArray(const unsigned char *data,uint32_t len) + { + clear(); + for(uint32_t i=0;i size()) + if(s.size() > size()) return false; - for(uint32_t i=0;i size()) - return false; - - for(uint32_t i=0;i size()) return false; + + for(uint32_t i=0;i size()) + throw std::runtime_error("Length out of range in TorByteArray::mid()"); + + TorByteArray b; + for(uint32_t i=0;i<(uint32_t)length;++i) + b.push_back(data()[i+start]); + + return b; + } + + static TorByteArray number(uint64_t n) + { + std::ostringstream o; + o << n ; + return TorByteArray(o.str()); + } }; typedef std::string TorHostAddress; } -typedef Tor::TorByteArray QByteArray; // to be removed diff --git a/retroshare-gui/src/gui/GenCertDialog.cpp b/retroshare-gui/src/gui/GenCertDialog.cpp index e106146fb..7c89d9834 100644 --- a/retroshare-gui/src/gui/GenCertDialog.cpp +++ b/retroshare-gui/src/gui/GenCertDialog.cpp @@ -33,15 +33,15 @@ #include #include "gui/settings/rsharesettings.h" -#include "TorControl/TorManager.h" #include "util/misc.h" #include "gui/common/FilesDefs.h" -#include -#include -#include -#include -#include +#include "retroshare/rstor.h" +#include "retroshare/rsidentity.h" +#include "retroshare/rsinit.h" +#include "retroshare/rsnotify.h" +#include "rsserver/rsaccounts.h" +#include "util/rsrandom.h" #include #include diff --git a/retroshare-gui/src/main.cpp b/retroshare-gui/src/main.cpp index cfb9932ca..404fa6466 100644 --- a/retroshare-gui/src/main.cpp +++ b/retroshare-gui/src/main.cpp @@ -66,7 +66,7 @@ CrashStackTrace gCrashStackTrace; # include "gui/settings/JsonApiPage.h" #endif // RS_JSONAPI -#include "TorControl/TorManager.h" +#include "retroshare/rstor.h" #include "TorControl/TorControlWindow.h" #include "retroshare/rsidentity.h" From 43e8ed3d98c88d9cf65a26b56671814dd4573428 Mon Sep 17 00:00:00 2001 From: csoler Date: Sat, 26 Jun 2021 17:12:17 +0200 Subject: [PATCH 03/65] fixed compilation --- libretroshare/src/tor/TorManager.cpp | 107 ++++++++++++++++++ retroshare-gui/src/gui/GenCertDialog.cpp | 2 +- .../src/gui/statusbar/torstatus.cpp | 27 +++-- retroshare-gui/src/main.cpp | 44 ++++--- 4 files changed, 142 insertions(+), 38 deletions(-) diff --git a/libretroshare/src/tor/TorManager.cpp b/libretroshare/src/tor/TorManager.cpp index a9daa8986..8ba1eb456 100644 --- a/libretroshare/src/tor/TorManager.cpp +++ b/libretroshare/src/tor/TorManager.cpp @@ -563,3 +563,110 @@ uint16_t RsTor::socksPort() { return instance()->control()->socksPort(); } + +RsTorStatus RsTor::torStatus() +{ + TorControl::TorStatus ts = instance()->control()->torStatus(); + + switch(ts) + { + case TorControl::TorOffline: return RsTorStatus::OFFLINE; + case TorControl::TorReady: return RsTorStatus::READY; + + default: + case TorControl::TorUnknown: return RsTorStatus::UNKNOWN; + } +} + +RsTorControlStatus RsTor::torControlStatus() +{ + TorControl::Status ts = instance()->control()->status(); + + switch(ts) + { + default: + case Tor::TorControl::Error : return RsTorControlStatus::ERROR; + case Tor::TorControl::NotConnected : return RsTorControlStatus::NOT_CONNECTED; + case Tor::TorControl::Authenticating: return RsTorControlStatus::AUTHENTICATING; + case Tor::TorControl::Connecting: return RsTorControlStatus::CONNECTING; + case Tor::TorControl::Connected : return RsTorControlStatus::CONNECTED; + } +} + +bool RsTor::setupHiddenService() +{ + return instance()->setupHiddenService(); +} + +RsTorHiddenServiceStatus RsTor::getHiddenServiceStatus(std::string& service_id) +{ + service_id.clear(); + auto list = instance()->control()->hiddenServices(); + + if(list.empty()) + return RsTorHiddenServiceStatus::NOT_CREATRED; + + service_id = (*list.begin())->serviceId().toStdString(); + + switch((*list.begin())->status()) + { + default: + case Tor::HiddenService::NotCreated: return RsTorHiddenServiceStatus::NOT_CREATRED; + case Tor::HiddenService::Offline : return RsTorHiddenServiceStatus::OFFLINE; + case Tor::HiddenService::Online : return RsTorHiddenServiceStatus::ONLINE; + } +} + +std::map RsTor::bootstrapStatus() +{ + QVariantMap m = instance()->control()->bootstrapStatus(); + std::map res; + + for(auto it(m.begin());it!=m.end();++it) + res.insert(std::make_pair(it.key().toStdString(),it.value().toString().toStdString())); + + return res; +} + +bool RsTor::hasError() +{ + return instance()->hasError(); +} +std::string RsTor::errorMessage() +{ + return instance()->errorMessage().toStdString(); +} + +void RsTor::getProxyServerInfo(std::string& server_address, uint16_t& server_port) +{ + QHostAddress qserver_address; + instance()->getProxyServerInfo(qserver_address,server_port); + + server_address = qserver_address.toString().toStdString(); +} + +bool RsTor::start() +{ + return instance()->start(); +} + +void RsTor::setTorDataDirectory(const std::string& dir) +{ + instance()->setTorDataDirectory(QString::fromStdString(dir)); +} +void RsTor::setHiddenServiceDirectory(const std::string& dir) +{ + instance()->setHiddenServiceDirectory(QString::fromStdString(dir)); +} + +TorManager *RsTor::instance() +{ + assert(getpid() == gettid()); // make sure we're not in a thread + + static TorManager *rsTor = nullptr; + + if(rsTor == nullptr) + rsTor = new TorManager; + + return rsTor; +} diff --git a/retroshare-gui/src/gui/GenCertDialog.cpp b/retroshare-gui/src/gui/GenCertDialog.cpp index 7c89d9834..f9511a46c 100644 --- a/retroshare-gui/src/gui/GenCertDialog.cpp +++ b/retroshare-gui/src/gui/GenCertDialog.cpp @@ -528,7 +528,7 @@ void GenCertDialog::genPerson() bool isHiddenLoc = (ui.nodeType_CB->currentIndex()>0); bool isAutoTor = (ui.nodeType_CB->currentIndex()==1); - if(isAutoTor && !Tor::TorManager::isTorAvailable()) + if(isAutoTor && !RsTor::isTorAvailable()) { QMessageBox::critical(this,tr("Tor is not available"),tr("No Tor executable has been found on your system. You need to install Tor before creating a hidden identity.")) ; return ; diff --git a/retroshare-gui/src/gui/statusbar/torstatus.cpp b/retroshare-gui/src/gui/statusbar/torstatus.cpp index f046f09cc..cac12f3d8 100644 --- a/retroshare-gui/src/gui/statusbar/torstatus.cpp +++ b/retroshare-gui/src/gui/statusbar/torstatus.cpp @@ -28,11 +28,10 @@ #include "retroshare/rsconfig.h" #include "retroshare/rsinit.h" #include "retroshare/rspeers.h" +#include "retroshare/rstor.h" #include #include "util/misc.h" -#include "TorControl/TorManager.h" -#include "TorControl/TorControl.h" #include "gui/common/FilesDefs.h" #include @@ -92,8 +91,8 @@ void TorStatus::getTorStatus() if(RsAccounts::isTorAuto()) { // get Tor status - int tor_control_status = Tor::TorManager::instance()->control()->status(); - int torstatus = Tor::TorManager::instance()->control()->torStatus(); + RsTorControlStatus tor_control_status = RsTor::torControlStatus(); + RsTorStatus torstatus = RsTor::torStatus(); QString tor_control_status_str,torstatus_str ; bool tor_control_ok ; @@ -101,30 +100,30 @@ void TorStatus::getTorStatus() switch(tor_control_status) { default: - case Tor::TorControl::Error : tor_control_ok = false ; tor_control_status_str = "Error" ; break ; - case Tor::TorControl::NotConnected: tor_control_ok = false ; tor_control_status_str = "Not connected" ; break ; - case Tor::TorControl::Connecting: tor_control_ok = false ; tor_control_status_str = "Connecting" ; break ; - case Tor::TorControl::Authenticating: tor_control_ok = false ; tor_control_status_str = "Authenticating" ; break ; - case Tor::TorControl::Connected: tor_control_ok = true ; tor_control_status_str = "Connected" ; break ; + case RsTorControlStatus::ERROR : tor_control_ok = false ; tor_control_status_str = "Error" ; break ; + case RsTorControlStatus::NOT_CONNECTED: tor_control_ok = false ; tor_control_status_str = "Not connected" ; break ; + case RsTorControlStatus::CONNECTING: tor_control_ok = false ; tor_control_status_str = "Connecting" ; break ; + case RsTorControlStatus::AUTHENTICATING: tor_control_ok = false ; tor_control_status_str = "Authenticating" ; break ; + case RsTorControlStatus::CONNECTED: tor_control_ok = true ; tor_control_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 ; + case RsTorStatus::UNKNOWN: torstatus_str = "Unknown" ; break ; + case RsTorStatus::OFFLINE: torstatus_str = "Tor offline" ; break ; + case RsTorStatus::READY: torstatus_str = "Tor ready" ; break ; } #define MIN_RS_NET_SIZE 10 - if(torstatus == Tor::TorControl::TorOffline || !online || !tor_control_ok) + if(torstatus == RsTorStatus::OFFLINE || !online || !tor_control_ok) { // RED - some issue. torstatusLabel->setPixmap(FilesDefs::getPixmapFromQtResourcePath(":/icons/tor-stopping.png").scaledToHeight(1.5*S,Qt::SmoothTransformation)); torstatusLabel->setToolTip( text + tr("Tor is currently offline")); } - else if(torstatus == Tor::TorControl::TorReady && online && tor_control_ok) + else if(torstatus == RsTorStatus::READY && online && tor_control_ok) { torstatusLabel->setPixmap(FilesDefs::getPixmapFromQtResourcePath(":/icons/tor-on.png").scaledToHeight(1.5*S,Qt::SmoothTransformation)); torstatusLabel->setToolTip( text + tr("Tor is OK")); diff --git a/retroshare-gui/src/main.cpp b/retroshare-gui/src/main.cpp index 404fa6466..104f525a8 100644 --- a/retroshare-gui/src/main.cpp +++ b/retroshare-gui/src/main.cpp @@ -399,24 +399,23 @@ 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 - QString tor_hidden_service_dir = QString::fromStdString(RsAccounts::AccountDirectory()) + QString("/hidden_service/") ; + std::string tor_hidden_service_dir = RsAccounts::AccountDirectory() + "/hidden_service/" ; - Tor::TorManager *torManager = Tor::TorManager::instance(); - torManager->setTorDataDirectory(Rshare::dataDirectory() + QString("/tor/")); - torManager->setHiddenServiceDirectory(tor_hidden_service_dir); // re-set it, because now it's changed to the specific location that is run + RsTor::setTorDataDirectory(Rshare::dataDirectory().toStdString() + "/tor/"); + RsTor::setHiddenServiceDirectory(tor_hidden_service_dir); // re-set it, because now it's changed to the specific location that is run - RsDirUtil::checkCreateDirectory(std::string(tor_hidden_service_dir.toUtf8())) ; + RsDirUtil::checkCreateDirectory(std::string(tor_hidden_service_dir)) ; - torManager->setupHiddenService(); + RsTor::setupHiddenService(); - if(! torManager->start() || torManager->hasError()) + if(! RsTor::start() || RsTor::hasError()) { - QMessageBox::critical(NULL,QObject::tr("Cannot start Tor Manager!"),QObject::tr("Tor cannot be started on your system: \n\n")+torManager->errorMessage()) ; + QMessageBox::critical(NULL,QObject::tr("Cannot start Tor Manager!"),QObject::tr("Tor cannot be started on your system: \n\n")+QString::fromStdString(RsTor::errorMessage())) ; return 1 ; } { - TorControlDialog tcd(torManager) ; + TorControlDialog tcd; QString error_msg ; tcd.show(); @@ -460,30 +459,29 @@ feenableexcept(FE_INVALID | FE_DIVBYZERO); { // Tor works with viable hidden service. Let's use it! - QString service_id ; - QString onion_address ; + std::string service_id ; + std::string onion_address ; uint16_t service_port ; uint16_t service_target_port ; uint16_t proxy_server_port ; - QHostAddress service_target_address ; - QHostAddress proxy_server_address ; + std::string service_target_address ; + std::string proxy_server_address ; - Tor::TorManager *torManager = Tor::TorManager::instance(); - torManager->getHiddenServiceInfo(service_id,onion_address,service_port,service_target_address,service_target_port); - torManager->getProxyServerInfo(proxy_server_address,proxy_server_port) ; + RsTor::getHiddenServiceInfo(service_id,onion_address,service_port,service_target_address,service_target_port); + RsTor::getProxyServerInfo(proxy_server_address,proxy_server_port) ; std::cerr << "Got hidden service info: " << std::endl; - std::cerr << " onion address : " << onion_address.toStdString() << std::endl; - std::cerr << " service_id : " << service_id.toStdString() << std::endl; + std::cerr << " onion address : " << onion_address << std::endl; + std::cerr << " service_id : " << service_id << std::endl; std::cerr << " service port : " << service_port << std::endl; std::cerr << " target port : " << service_target_port << std::endl; - std::cerr << " target address : " << service_target_address.toString().toStdString() << std::endl; + std::cerr << " target address : " << service_target_address << std::endl; - std::cerr << "Setting proxy server to " << service_target_address.toString().toStdString() << ":" << service_target_port << std::endl; + std::cerr << "Setting proxy server to " << service_target_address << ":" << service_target_port << std::endl; - rsPeers->setLocalAddress(rsPeers->getOwnId(), service_target_address.toString().toStdString(), service_target_port); - rsPeers->setHiddenNode(rsPeers->getOwnId(), onion_address.toStdString(), service_port); - rsPeers->setProxyServer(RS_HIDDEN_TYPE_TOR, proxy_server_address.toString().toStdString(),proxy_server_port) ; + rsPeers->setLocalAddress(rsPeers->getOwnId(), service_target_address, service_target_port); + rsPeers->setHiddenNode(rsPeers->getOwnId(), onion_address, service_port); + rsPeers->setProxyServer(RS_HIDDEN_TYPE_TOR, proxy_server_address,proxy_server_port) ; } Rshare::initPlugins(); From 607c1896e56d02182c565e7012d5bb5b8f4a3895 Mon Sep 17 00:00:00 2001 From: csoler Date: Sat, 26 Jun 2021 18:52:48 +0200 Subject: [PATCH 04/65] progress in event handling in RsTor --- libretroshare/src/tor/TorControl.cpp | 43 ++++++++++++++++++- libretroshare/src/tor/TorManager.cpp | 12 +++--- .../src/gui/statusbar/torstatus.cpp | 12 +++--- 3 files changed, 54 insertions(+), 13 deletions(-) diff --git a/libretroshare/src/tor/TorControl.cpp b/libretroshare/src/tor/TorControl.cpp index 29979e2b3..35cc96664 100644 --- a/libretroshare/src/tor/TorControl.cpp +++ b/libretroshare/src/tor/TorControl.cpp @@ -32,6 +32,7 @@ #include +#include "retroshare/rstor.h" #include "TorControl.h" #include "TorControlSocket.h" #include "HiddenService.h" @@ -139,6 +140,29 @@ QNetworkProxy TorControl::connectionProxy() return QNetworkProxy(QNetworkProxy::Socks5Proxy, d->socksAddress.toString(), d->socksPort); } +static RsTorConnectivityStatus torConnectivityStatus(Tor::TorControl::Status t) +{ + switch(t) + { + default: + case TorControl::Error: return RsTorConnectivityStatus::ERROR; + case TorControl::NotConnected: return RsTorConnectivityStatus::NOT_CONNECTED; + case TorControl::Connecting: return RsTorConnectivityStatus::CONNECTING; + case TorControl::Authenticating: return RsTorConnectivityStatus::AUTHENTICATING; + case TorControl::Connected: return RsTorConnectivityStatus::CONNECTED; + } +} +static RsTorStatus torStatus(Tor::TorControl::TorStatus t) +{ + switch(t) + { + default: + case TorControl::TorUnknown: return RsTorStatus::UNKNOWN; + case TorControl::TorOffline: return RsTorStatus::OFFLINE; + case TorControl::TorReady: return RsTorStatus::READY; + } +} + void TorControlPrivate::setStatus(TorControl::Status n) { if (n == status) @@ -150,12 +174,23 @@ void TorControlPrivate::setStatus(TorControl::Status n) if (old == TorControl::Error) errorMessage.clear(); + if(rsEvents) + { + auto ev = std::make_shared(); + + ev->mTorManagerEventType = RsTorManagerEventCode::TOR_CONTROL_STATUS_CHANGED; + ev->mTorConnectivityStatus = torConnectivityStatus(status); + + rsEvents->postEvent(ev); + } +#ifdef TO_REMOVE emit q->statusChanged(status, old); if (status == TorControl::Connected && old < TorControl::Connected) emit q->connected(); else if (status < TorControl::Connected && old >= TorControl::Connected) emit q->disconnected(); +#endif } void TorControlPrivate::setTorStatus(TorControl::TorStatus n) @@ -617,7 +652,13 @@ void TorControlPrivate::updateBootstrap(const QList &data) //torCtrlDebug() << bootstrapStatus << std::endl; - emit q->bootstrapStatusChanged(); + if(rsEvents) + { + auto ev = std::make_shared(); + + ev->mTorManagerEventType = RsTorManagerEventCode::BOOTSTRAP_STATUS_CHANGED; + rsEvents->postEvent(ev); + } } QObject *TorControl::getConfiguration(const QString &options) diff --git a/libretroshare/src/tor/TorManager.cpp b/libretroshare/src/tor/TorManager.cpp index 8ba1eb456..d167c9cba 100644 --- a/libretroshare/src/tor/TorManager.cpp +++ b/libretroshare/src/tor/TorManager.cpp @@ -578,18 +578,18 @@ RsTorStatus RsTor::torStatus() } } -RsTorControlStatus RsTor::torControlStatus() +RsTorConnectivityStatus RsTor::torConnectivityStatus() { TorControl::Status ts = instance()->control()->status(); switch(ts) { default: - case Tor::TorControl::Error : return RsTorControlStatus::ERROR; - case Tor::TorControl::NotConnected : return RsTorControlStatus::NOT_CONNECTED; - case Tor::TorControl::Authenticating: return RsTorControlStatus::AUTHENTICATING; - case Tor::TorControl::Connecting: return RsTorControlStatus::CONNECTING; - case Tor::TorControl::Connected : return RsTorControlStatus::CONNECTED; + case Tor::TorControl::Error : return RsTorConnectivityStatus::ERROR; + case Tor::TorControl::NotConnected : return RsTorConnectivityStatus::NOT_CONNECTED; + case Tor::TorControl::Authenticating: return RsTorConnectivityStatus::AUTHENTICATING; + case Tor::TorControl::Connecting: return RsTorConnectivityStatus::CONNECTING; + case Tor::TorControl::Connected : return RsTorConnectivityStatus::CONNECTED; } } diff --git a/retroshare-gui/src/gui/statusbar/torstatus.cpp b/retroshare-gui/src/gui/statusbar/torstatus.cpp index cac12f3d8..319d8da3d 100644 --- a/retroshare-gui/src/gui/statusbar/torstatus.cpp +++ b/retroshare-gui/src/gui/statusbar/torstatus.cpp @@ -91,7 +91,7 @@ void TorStatus::getTorStatus() if(RsAccounts::isTorAuto()) { // get Tor status - RsTorControlStatus tor_control_status = RsTor::torControlStatus(); + RsTorConnectivityStatus tor_control_status = RsTor::torConnectivityStatus(); RsTorStatus torstatus = RsTor::torStatus(); QString tor_control_status_str,torstatus_str ; @@ -100,11 +100,11 @@ void TorStatus::getTorStatus() switch(tor_control_status) { default: - case RsTorControlStatus::ERROR : tor_control_ok = false ; tor_control_status_str = "Error" ; break ; - case RsTorControlStatus::NOT_CONNECTED: tor_control_ok = false ; tor_control_status_str = "Not connected" ; break ; - case RsTorControlStatus::CONNECTING: tor_control_ok = false ; tor_control_status_str = "Connecting" ; break ; - case RsTorControlStatus::AUTHENTICATING: tor_control_ok = false ; tor_control_status_str = "Authenticating" ; break ; - case RsTorControlStatus::CONNECTED: tor_control_ok = true ; tor_control_status_str = "Connected" ; break ; + case RsTorConnectivityStatus::ERROR : tor_control_ok = false ; tor_control_status_str = "Error" ; break ; + case RsTorConnectivityStatus::NOT_CONNECTED: tor_control_ok = false ; tor_control_status_str = "Not connected" ; break ; + case RsTorConnectivityStatus::CONNECTING: tor_control_ok = false ; tor_control_status_str = "Connecting" ; break ; + case RsTorConnectivityStatus::AUTHENTICATING: tor_control_ok = false ; tor_control_status_str = "Authenticating" ; break ; + case RsTorConnectivityStatus::CONNECTED: tor_control_ok = true ; tor_control_status_str = "Connected" ; break ; } switch(torstatus) From a23ad41b112665fcb5f5a0e5ef5e157afb37edba Mon Sep 17 00:00:00 2001 From: csoler Date: Sat, 26 Jun 2021 23:13:17 +0200 Subject: [PATCH 05/65] fixed event handling in Tor bootstrap process --- libretroshare/src/tor/TorControl.cpp | 34 ++++++++++++++++++++++++---- 1 file changed, 29 insertions(+), 5 deletions(-) diff --git a/libretroshare/src/tor/TorControl.cpp b/libretroshare/src/tor/TorControl.cpp index 35cc96664..2b0040252 100644 --- a/libretroshare/src/tor/TorControl.cpp +++ b/libretroshare/src/tor/TorControl.cpp @@ -178,10 +178,10 @@ void TorControlPrivate::setStatus(TorControl::Status n) { auto ev = std::make_shared(); - ev->mTorManagerEventType = RsTorManagerEventCode::TOR_CONTROL_STATUS_CHANGED; + ev->mTorManagerEventType = RsTorManagerEventCode::TOR_STATUS_CHANGED; ev->mTorConnectivityStatus = torConnectivityStatus(status); - rsEvents->postEvent(ev); + rsEvents->sendEvent(ev); } #ifdef TO_REMOVE emit q->statusChanged(status, old); @@ -200,9 +200,19 @@ void TorControlPrivate::setTorStatus(TorControl::TorStatus n) TorControl::TorStatus old = torStatus; torStatus = n; +#ifdef TO_REMOVE emit q->torStatusChanged(torStatus, old); emit q->connectivityChanged(); +#endif + if(rsEvents) + { + auto ev = std::make_shared(); + + ev->mTorManagerEventType = RsTorManagerEventCode::TOR_STATUS_CHANGED; + ev->mTorStatus = ::torStatus(torStatus); + rsEvents->sendEvent(ev); + } if (torStatus == TorControl::TorReady && socksAddress.isNull()) { // Request info again to read the SOCKS port getTorInfo(); @@ -460,7 +470,14 @@ void TorControlPrivate::getTorInfo() torCtrlDebug() << "torctrl: Using manually specified SOCKS connection settings"; socksAddress = forceAddress; socksPort = port; - emit q->connectivityChanged(); + + if(rsEvents) + { + auto ev = std::make_shared(); + + ev->mTorManagerEventType = RsTorManagerEventCode::TOR_CONNECTIVITY_CHANGED; + rsEvents->sendEvent(ev); + } } else keys << QByteArray("net/listeners/socks"); @@ -496,7 +513,14 @@ void TorControlPrivate::getTorInfoReply() * is reached. */ if (!socksAddress.isNull()) { torCtrlDebug() << "torctrl: SOCKS address is " << socksAddress.toString().toStdString() << ":" << socksPort << std::endl; - emit q->connectivityChanged(); + + if(rsEvents) + { + auto ev = std::make_shared(); + + ev->mTorManagerEventType = RsTorManagerEventCode::TOR_CONNECTIVITY_CHANGED; + rsEvents->sendEvent(ev); + } } if (command->get(QByteArray("status/circuit-established")).toInt() == 1) { @@ -657,7 +681,7 @@ void TorControlPrivate::updateBootstrap(const QList &data) auto ev = std::make_shared(); ev->mTorManagerEventType = RsTorManagerEventCode::BOOTSTRAP_STATUS_CHANGED; - rsEvents->postEvent(ev); + rsEvents->sendEvent(ev); } } From 139b22b41a561e9c6e50bede56d3aa367b6f340b Mon Sep 17 00:00:00 2001 From: csoler Date: Sun, 27 Jun 2021 18:14:22 +0200 Subject: [PATCH 06/65] added rstor.h file --- libretroshare/src/retroshare/rstor.h | 168 +++++++++++++++++++++++++++ 1 file changed, 168 insertions(+) create mode 100644 libretroshare/src/retroshare/rstor.h diff --git a/libretroshare/src/retroshare/rstor.h b/libretroshare/src/retroshare/rstor.h new file mode 100644 index 000000000..7538671b1 --- /dev/null +++ b/libretroshare/src/retroshare/rstor.h @@ -0,0 +1,168 @@ +#pragma once + +// This code stands as an interface for the automatic configuration +// of Tor hidden services to be used by retroshare. +// +// The correct way to use it is to: +// +// 1 - properly set data and hidden service directories. This allowd the TorManager +// to save its keys for the hidden service, or to load one that has previously been created +// +// 2 - call setupHiddenService(). This creates/loads the hidden service. +// +// 3 - call RsTor::start() +// +// 4 - loop/wait until RsTor::getHiddenServiceStatus(service_id) +// returns RsTorHiddenServiceStatus::ONLINE +// +// 5 - call RsTor::getHiddenserviceInfo to properly setup RS internal ports and addresses: +// +// RsTor::getHiddenServiceInfo(service_id,onion_address,service_port,service_target_address,service_target_port); +// RsTor::getProxyServerInfo(proxy_server_address,proxy_server_port) ; +// +// rsPeers->setLocalAddress(rsPeers->getOwnId(), service_target_address, service_target_port); +// rsPeers->setHiddenNode(rsPeers->getOwnId(), onion_address, service_port); +// rsPeers->setProxyServer(RS_HIDDEN_TYPE_TOR, proxy_server_address,proxy_server_port) ; + +#include "retroshare/rsevents.h" + +namespace Tor { + class TorManager; +} + +enum class RsTorManagerEventCode: uint8_t +{ + UNKNOWN = 0x00, + TOR_STATUS_CHANGED = 0x01, + BOOTSTRAP_STATUS_CHANGED = 0x02, + TOR_CONNECTIVITY_CHANGED = 0x03, +}; + +// Status of the Tor hidden service setup/loaded by RS + +enum class RsTorHiddenServiceStatus: uint8_t { + ERROR = 0x00, + NOT_CREATED = 0x01, + OFFLINE = 0x02, + ONLINE = 0x03 +}; + +// Status of the connection/authentication between RS and the Tor service + +enum class RsTorConnectivityStatus: uint8_t { + ERROR = 0x00, + NOT_CONNECTED = 0x01, + CONNECTING = 0x02, + AUTHENTICATING = 0x03, + CONNECTED = 0x04 +}; + +// Status of the Tor service with which RS is talking. + +enum class RsTorStatus: uint8_t { + UNKNOWN = 0x00, + OFFLINE = 0x01, + READY = 0x02 +}; + +struct RsTorManagerEvent: public RsEvent +{ + RsTorManagerEvent(): RsEvent(RsEventType::TOR_MANAGER), + mTorManagerEventType(RsTorManagerEventCode::UNKNOWN) + {} + + RsTorManagerEventCode mTorManagerEventType; + + RsTorConnectivityStatus mTorConnectivityStatus; + RsTorStatus mTorStatus; + + ///* @see RsEvent @see RsSerializable + void serial_process( RsGenericSerializer::SerializeJob j, RsGenericSerializer::SerializeContext& ctx ) override + { + RsEvent::serial_process(j, ctx); + RS_SERIAL_PROCESS(mTorManagerEventType); + RS_SERIAL_PROCESS(mTorConnectivityStatus); + RS_SERIAL_PROCESS(mTorStatus); + } + + ~RsTorManagerEvent() = default; +}; + +class RsTor +{ +public: + /*! + * \brief isTorAvailable + * \return true if a Tor executble has been found. False otherwise. + */ + static bool isTorAvailable() ; + + /*! + * \brief torStatus + * \return Status of the Tor service used by RS + */ + static RsTorStatus torStatus() ; + + /*! + * \brief torConnectivityStatus + * \return Status of the connectivity/authentication between RS and Tor + */ + static RsTorConnectivityStatus torConnectivityStatus() ; + + static void setTorDataDirectory(const std::string& dir); + static void setHiddenServiceDirectory(const std::string& dir); + + static bool setupHiddenService(); + + /*! + * \brief getProxyServerInfo + * \param server_address Address of the proxy used by RS to send data in the Tor network. Usually 127.0.0.1 + * \param server_port Port of the proxy used by RS to send data in the Tor network. Usually 9050. + */ + static void getProxyServerInfo(std::string& server_address, uint16_t& server_port); + + /*! + * \brief getHiddenServiceStatus + * \param service_id onion address of the hidden service (if the service is OFFLINE or ONLINE) + * \return Status of the created/loaded hidden service. + */ + static RsTorHiddenServiceStatus getHiddenServiceStatus(std::string& service_id); + + /*! + * \brief start + * Launches the Tor management threads. + */ + static bool start(); + + /*! + * \brief getHiddenServiceInfo + * Gets information about the hidden service setup by RS to run. + * \param service_id + * \param service_onion_address + * \param service_port + * \param service_target_address + * \param target_port + * \return + */ + static bool getHiddenServiceInfo(std::string& service_id, + std::string& service_onion_address, + uint16_t& service_port, + std::string& service_target_address, + uint16_t& target_port); + + /*! + * \brief bootstrapStatus + * \return Log messages of the Tor bootstrapping status. + */ + static std::map bootstrapStatus(); + static std::list logMessages(); + + static std::string socksAddress(); + static uint16_t socksPort(); + + static bool hasError(); + static std::string errorMessage(); + +private: + static Tor::TorManager *instance(); +}; From da86da29ff12cee1e8ec2dd4105d46468d55b70e Mon Sep 17 00:00:00 2001 From: csoler Date: Tue, 29 Jun 2021 00:23:32 +0200 Subject: [PATCH 07/65] attempt at fixing tor bootstrap. Not working yet --- libretroshare/src/retroshare/rsinit.h | 2 + libretroshare/src/rsserver/rsinit.cc | 51 +++++++++++++++++++ libretroshare/src/tor/TorManager.cpp | 4 +- retroshare-service/src/retroshare-service.cc | 37 +++++++++++++- retroshare-service/src/retroshare-service.pro | 4 +- 5 files changed, 94 insertions(+), 4 deletions(-) diff --git a/libretroshare/src/retroshare/rsinit.h b/libretroshare/src/retroshare/rsinit.h index 73fea2684..11eb54466 100644 --- a/libretroshare/src/retroshare/rsinit.h +++ b/libretroshare/src/retroshare/rsinit.h @@ -159,6 +159,7 @@ public: ERR_ALREADY_RUNNING, /// Another istance is running already ERR_CANT_ACQUIRE_LOCK, /// Another istance is already running? ERR_NO_AVAILABLE_ACCOUNT, /// Used in retroshare-service -U list when no account is available + ERR_CANNOT_CONFIGURE_TOR, /// cannot start/configure Tor for an auto-tor node ERR_UNKNOWN /// Unkown error, maybe password is wrong? }; @@ -184,6 +185,7 @@ public: static bool isPortable(); static bool isWindowsXP(); static bool collectEntropy(uint32_t bytes) ; + static bool startAutoTor(); /*! * \brief lockFilePath diff --git a/libretroshare/src/rsserver/rsinit.cc b/libretroshare/src/rsserver/rsinit.cc index 8449a9e3e..ff411ac2e 100644 --- a/libretroshare/src/rsserver/rsinit.cc +++ b/libretroshare/src/rsserver/rsinit.cc @@ -42,6 +42,7 @@ #include "util/folderiterator.h" #include "util/rsstring.h" #include "retroshare/rsinit.h" +#include "retroshare/rstor.h" #include "retroshare/rsnotify.h" #include "retroshare/rsiface.h" #include "plugins/pluginmanager.h" @@ -1923,6 +1924,46 @@ int RsServer::StartupRetroShare() return 1; } +bool RsInit::startAutoTor() +{ + std::cerr << "(II) node is an automated Tor node => launching Tor auto-configuration." << std::endl; + // Now that we know the Tor service running, and we know the SSL id, we can make sure it provides a viable hidden service + + std::string tor_hidden_service_dir = RsAccounts::AccountDirectory() + "/hidden_service/" ; + + RsTor::setTorDataDirectory(RsAccounts::ConfigDirectory() + "/tor/"); + RsTor::setHiddenServiceDirectory(tor_hidden_service_dir); // re-set it, because now it's changed to the specific location that is run + + RsDirUtil::checkCreateDirectory(std::string(tor_hidden_service_dir)) ; + + if(! RsTor::start() || RsTor::hasError()) + { + std::cerr << "(EE) Tor cannot be started on your system: "+RsTor::errorMessage() << std::endl ; + return false ; + } + std::cerr << "(II) Tor has been started." << std::endl; + + // now start/create the hidden service as needed. + + std::string service_id; + RsTor::setupHiddenService(); + + while(RsTor::torStatus() != RsTorStatus::READY && RsTor::getHiddenServiceStatus(service_id) != RsTorHiddenServiceStatus::ONLINE) // runs until some status is reached: either tor works, or it fails. + { + rstime::rs_usleep(0.5*1000*1000) ; + + std::cerr << "(II) Hidden service ID: " << service_id << ", status: " << (int)RsTor::getHiddenServiceStatus(service_id) << std::endl; + if(RsTor::hasError()) + { + std::string error_msg = RsTor::errorMessage(); + + std::cerr << "(EE) Tor hidden service cannot be started: " << error_msg << std::endl; + return false; + } + } + return true; +} + RsInit::LoadCertificateStatus RsLoginHelper::attemptLogin(const RsPeerId& account, const std::string& password) { if(isLoggedIn()) return RsInit::ERR_ALREADY_RUNNING; @@ -1942,6 +1983,16 @@ RsInit::LoadCertificateStatus RsLoginHelper::attemptLogin(const RsPeerId& accoun rsNotify->setDisableAskPassword(false) ; rsNotify->clearPgpPassphrase() ; + bool is_hidden_node = false; + bool is_auto_tor = false ; + bool is_first_time = false ; + + RsAccounts::getCurrentAccountOptions(is_hidden_node,is_auto_tor,is_first_time); + + if(is_auto_tor) + if(!RsInit::startAutoTor()) + return RsInit::ERR_CANNOT_CONFIGURE_TOR; + if(ret == RsInit::OK && RsControl::instance()->StartupRetroShare() == 1) return RsInit::OK; diff --git a/libretroshare/src/tor/TorManager.cpp b/libretroshare/src/tor/TorManager.cpp index d167c9cba..f21c12709 100644 --- a/libretroshare/src/tor/TorManager.cpp +++ b/libretroshare/src/tor/TorManager.cpp @@ -604,14 +604,14 @@ RsTorHiddenServiceStatus RsTor::getHiddenServiceStatus(std::string& service_id) auto list = instance()->control()->hiddenServices(); if(list.empty()) - return RsTorHiddenServiceStatus::NOT_CREATRED; + return RsTorHiddenServiceStatus::NOT_CREATED; service_id = (*list.begin())->serviceId().toStdString(); switch((*list.begin())->status()) { default: - case Tor::HiddenService::NotCreated: return RsTorHiddenServiceStatus::NOT_CREATRED; + case Tor::HiddenService::NotCreated: return RsTorHiddenServiceStatus::NOT_CREATED; case Tor::HiddenService::Offline : return RsTorHiddenServiceStatus::OFFLINE; case Tor::HiddenService::Online : return RsTorHiddenServiceStatus::ONLINE; } diff --git a/retroshare-service/src/retroshare-service.cc b/retroshare-service/src/retroshare-service.cc index e80d468e1..898d71067 100644 --- a/retroshare-service/src/retroshare-service.cc +++ b/retroshare-service/src/retroshare-service.cc @@ -22,7 +22,10 @@ #include "util/stacktrace.h" #include "util/argstream.h" #include "util/rskbdinput.h" +#include "util/rsdir.h" #include "retroshare/rsinit.h" +#include "retroshare/rstor.h" +#include "retroshare/rspeers.h" #ifdef RS_JSONAPI #include "retroshare/rsjsonapi.h" @@ -47,6 +50,7 @@ static CrashStackTrace gCrashStackTrace; # include "util/androiddebug.h" #endif // def __ANDROID__ +#include #include "retroshare/rsinit.h" #include "retroshare/rsiface.h" @@ -95,7 +99,9 @@ int main(int argc, char* argv[]) #ifdef __ANDROID__ AndroidStdIOCatcher dbg; (void) dbg; QAndroidService app(argc, argv); -#endif // def __ANDROID__ +#else // def __ANDROID__ + QCoreApplication app(argc,argv); // needed for TorManaer (that uses QDir). To be removed when TorManager doesn't use Qt anymore. +#endif signal(SIGINT, signalHandler); signal(SIGTERM, signalHandler); @@ -311,6 +317,35 @@ int main(int argc, char* argv[]) << std::endl; return -result; } + + if(RsAccounts::isTorAuto()) + { + + std::cerr << "(II) Hidden service is ready:" << std::endl; + + std::string service_id ; + std::string onion_address ; + uint16_t service_port ; + uint16_t service_target_port ; + uint16_t proxy_server_port ; + std::string service_target_address ; + std::string proxy_server_address ; + + RsTor::getHiddenServiceInfo(service_id,onion_address,service_port,service_target_address,service_target_port); + RsTor::getProxyServerInfo(proxy_server_address,proxy_server_port) ; + + std::cerr << " onion address : " << onion_address << std::endl; + std::cerr << " service_id : " << service_id << std::endl; + std::cerr << " service port : " << service_port << std::endl; + std::cerr << " target port : " << service_target_port << std::endl; + std::cerr << " target address : " << service_target_address << std::endl; + + std::cerr << "Setting proxy server to " << service_target_address << ":" << service_target_port << std::endl; + + rsPeers->setLocalAddress(rsPeers->getOwnId(), service_target_address, service_target_port); + rsPeers->setHiddenNode(rsPeers->getOwnId(), onion_address, service_port); + rsPeers->setProxyServer(RS_HIDDEN_TYPE_TOR, proxy_server_address,proxy_server_port) ; + } } #endif // def RS_SERVICE_TERMINAL_LOGIN diff --git a/retroshare-service/src/retroshare-service.pro b/retroshare-service/src/retroshare-service.pro index cbd1b9d13..8c5259a7b 100644 --- a/retroshare-service/src/retroshare-service.pro +++ b/retroshare-service/src/retroshare-service.pro @@ -22,7 +22,9 @@ TARGET = retroshare-service -QT += core +CONFIG += qt + +QT += core network QT -= gui !include("../../libretroshare/src/use_libretroshare.pri"):error("Including") From ae79261cbce5156f2ffc95b8e495a0c814a2ef48 Mon Sep 17 00:00:00 2001 From: csoler Date: Fri, 2 Jul 2021 00:11:10 +0200 Subject: [PATCH 08/65] fixed bootstrapping of Tor in retroshare-service --- libretroshare/src/rsserver/rsinit.cc | 5 +++++ libretroshare/src/tor/TorManager.cpp | 5 +++++ 2 files changed, 10 insertions(+) diff --git a/libretroshare/src/rsserver/rsinit.cc b/libretroshare/src/rsserver/rsinit.cc index ff411ac2e..6373e0d3c 100644 --- a/libretroshare/src/rsserver/rsinit.cc +++ b/libretroshare/src/rsserver/rsinit.cc @@ -35,6 +35,8 @@ # include // for QString::fromStdString(...) #endif +#include + #include "util/argstream.h" #include "util/rsdebug.h" #include "util/rsdir.h" @@ -1960,6 +1962,9 @@ bool RsInit::startAutoTor() std::cerr << "(EE) Tor hidden service cannot be started: " << error_msg << std::endl; return false; } + // process Qt event loop to deal with messages of online/offline info + + QCoreApplication::processEvents(); } return true; } diff --git a/libretroshare/src/tor/TorManager.cpp b/libretroshare/src/tor/TorManager.cpp index f21c12709..fc81d943e 100644 --- a/libretroshare/src/tor/TorManager.cpp +++ b/libretroshare/src/tor/TorManager.cpp @@ -357,6 +357,11 @@ bool TorManager::start() emit configurationNeededChanged(); } + std::cerr << "Starting Tor process:" << std::endl; + std::cerr << " Tor executable path: " << executable.toStdString() << std::endl; + std::cerr << " Tor data directory : " << d->dataDir.toStdString() << std::endl; + std::cerr << " Tor default torrc : " << defaultTorrc.toStdString() << std::endl; + d->process->setExecutable(executable); d->process->setDataDir(d->dataDir); d->process->setDefaultTorrc(defaultTorrc); From a43a158750210c259108661ca686e3aad3dbcc5b Mon Sep 17 00:00:00 2001 From: csoler Date: Sat, 3 Jul 2021 00:13:01 +0200 Subject: [PATCH 09/65] added back missing files --- .../src/TorControl/TorControlWindow.cpp | 252 ++++++++++++++++++ .../src/TorControl/TorControlWindow.h | 50 ++++ .../src/TorControl/TorControlWindow.ui | 134 ++++++++++ 3 files changed, 436 insertions(+) create mode 100644 retroshare-gui/src/TorControl/TorControlWindow.cpp create mode 100644 retroshare-gui/src/TorControl/TorControlWindow.h create mode 100644 retroshare-gui/src/TorControl/TorControlWindow.ui diff --git a/retroshare-gui/src/TorControl/TorControlWindow.cpp b/retroshare-gui/src/TorControl/TorControlWindow.cpp new file mode 100644 index 000000000..897bdd35d --- /dev/null +++ b/retroshare-gui/src/TorControl/TorControlWindow.cpp @@ -0,0 +1,252 @@ +#include +#include + +#include +#include +#include +#include + +#include +#include "util/rstime.h" + +#include "retroshare/rstor.h" +#include "retroshare/rsevents.h" + +#include "TorControlWindow.h" +#include "util/qtthreadsutils.h" + +TorControlDialog::TorControlDialog(QWidget *) +{ + setupUi(this) ; + + mEventHandlerId = 0; // very important! + + rsEvents->registerEventsHandler( [this](std::shared_ptr event) + { + RsQThreadUtils::postToObject([=](){ handleEvent_main_thread(event); }, this ); + }, mEventHandlerId, RsEventType::TOR_MANAGER ); + + // 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())); + // QObject::connect(tm ,SIGNAL(errorChanged()),this,SLOT(statusChanged())); + + //QTimer::singleShot(2000,this,SLOT(checkForHiddenService())) ; + + mIncomingServer = new QTcpServer(this) ; + mHiddenServiceStatus = HIDDEN_SERVICE_STATUS_UNKNOWN; + + connect(mIncomingServer, SIGNAL(QTcpServer::newConnection()), this, SLOT(onIncomingConnection())); + + QTimer *timer = new QTimer ; + + QObject::connect(timer,SIGNAL(timeout()),this,SLOT(showLog())) ; + timer->start(500) ; + + // Hide some debug output for the released version + + setWindowFlags( Qt::Dialog | Qt::FramelessWindowHint ); + + adjustSize(); +} + +void TorControlDialog::handleEvent_main_thread(std::shared_ptr event) +{ + if(event->mType != RsEventType::TOR_MANAGER) return; + + const RsTorManagerEvent *fe = dynamic_cast(event.get()); + if(!fe) + return; + + switch (fe->mTorManagerEventType) + { + case RsTorManagerEventCode::BOOTSTRAP_STATUS_CHANGED: + case RsTorManagerEventCode::TOR_CONNECTIVITY_CHANGED: + case RsTorManagerEventCode::TOR_STATUS_CHANGED: statusChanged(fe->mTorStatus,fe->mTorConnectivityStatus); + break; + default: + break; + } +} + +void TorControlDialog::onIncomingConnection() +{ + std::cerr << "Incoming connection !!" << std::endl; +} + +void TorControlDialog::statusChanged(RsTorStatus torstatus, RsTorConnectivityStatus tor_control_status) +{ + QString tor_control_status_str,torstatus_str ; + + if(RsTor::hasError()) + mErrorMsg = QString::fromStdString(RsTor::errorMessage()) ; + + switch(tor_control_status) + { + default: + case RsTorConnectivityStatus::ERROR : tor_control_status_str = tr("Error") ; break ; + case RsTorConnectivityStatus::NOT_CONNECTED: tor_control_status_str = tr("Not connected") ; break ; + case RsTorConnectivityStatus::CONNECTING: tor_control_status_str = tr("Connecting") ; break ; + case RsTorConnectivityStatus::AUTHENTICATING: tor_control_status_str = tr("Authenticating") ; break ; + case RsTorConnectivityStatus::CONNECTED: tor_control_status_str = tr("Connected") ; break ; + } + + switch(torstatus) + { + default: + case RsTorStatus::UNKNOWN: torstatus_str = tr("Unknown") ; break ; + case RsTorStatus::OFFLINE: torstatus_str = tr("Tor offline") ; break ; + case RsTorStatus::READY: torstatus_str = tr("Tor ready") ; break ; + } + + torStatus_LB->setText(torstatus_str) ; + + if(torstatus == RsTorStatus::UNKNOWN) + torStatus_LB->setToolTip(tr("Check that Tor is accessible in your executable path")) ; + else + torStatus_LB->setToolTip("") ; + + std::map qvm = RsTor::bootstrapStatus(); + QString bootstrapstatus_str ; + + std::cerr << "Tor control status: " << tor_control_status_str.toStdString() << std::endl; + std::cerr << "Tor status: " << torstatus_str.toStdString() << std::endl; + + std::cerr << "Bootstrap status map: " << std::endl; + + for(auto it(qvm.begin());it!=qvm.end();++it) + std::cerr << " " << it->first << " : " << it->second << std::endl; + + if(!qvm["progress"].empty()) + torBootstrapStatus_LB->setText(QString::fromStdString(qvm["progress"]) + " % (" + QString::fromStdString(qvm["summary"]) + ")") ; + else + torBootstrapStatus_LB->setText(tr("[Waiting for Tor...]")) ; + + std::string service_id ; + std::string onion_address ; + std::string service_target_address ; + uint16_t service_port ; + uint16_t target_port ; + + if(RsTor::getHiddenServiceInfo(service_id,onion_address,service_port, service_target_address,target_port)) + { + hiddenServiceAddress_LB->setText(QString::number(service_port) + ":" + QString::fromStdString(service_target_address) + ":" + QString::number(target_port)); + onionAddress_LB->setText(QString::fromStdString(onion_address)); + } + else + { + hiddenServiceAddress_LB->setText(QString("[Not ready]")) ; + onionAddress_LB->setText(QString("[Not ready]")) ; + } + + showLog(); + adjustSize(); + + QCoreApplication::processEvents(); // forces update +} + +void TorControlDialog::showLog() +{ + static std::set already_seen ; + + std::string s ; + std::list logmsgs = RsTor::logMessages() ; + bool can_print = false ; + + for(auto it(logmsgs.begin());it!=logmsgs.end();++it) + { + s += *it + "\n" ; + + if(already_seen.find(*it) == already_seen.end()) + { + can_print = true ; + already_seen.insert(*it); + } + + if(can_print) + std::cerr << "[TOR DEBUG LOG] " << *it << std::endl; + } + +// torLog_TB->setText(s) ;: + + std::cerr << "Connexion Proxy: " << RsTor::socksAddress() << ":" << QString::number(RsTor::socksPort()).toStdString() << std::endl; +} + +TorControlDialog::TorStatus TorControlDialog::checkForTor(QString& error_msg) +{ + if(!mErrorMsg.isNull()) + { + error_msg = mErrorMsg ; + return TorControlDialog::TOR_STATUS_FAIL ; + } + + switch(RsTor::torStatus()) + { + case RsTorStatus::READY: rstime::rs_usleep(1*1000*1000);return TOR_STATUS_OK ; + default: + return TOR_STATUS_UNKNOWN ; + } +} + +TorControlDialog::HiddenServiceStatus TorControlDialog::checkForHiddenService() +{ + std::cerr << "Checking for hidden services:" ; + + switch(mHiddenServiceStatus) + { + default: + case HIDDEN_SERVICE_STATUS_UNKNOWN: { + + std::cerr << " trying to setup. " ; + + if(!RsTor::setupHiddenService()) + { + mHiddenServiceStatus = HIDDEN_SERVICE_STATUS_FAIL ; + std::cerr << "Failed." << std::endl; + return mHiddenServiceStatus ; + } + std::cerr << "Done." << std::endl; + mHiddenServiceStatus = HIDDEN_SERVICE_STATUS_REQUESTED ; + return mHiddenServiceStatus ; + } + + case HIDDEN_SERVICE_STATUS_REQUESTED: { + + std::string service_id; + + RsTorHiddenServiceStatus service_status = RsTor::getHiddenServiceStatus(service_id); + + if(service_id.empty()) + { + std::cerr << "Not ready yet." << std::endl; + return mHiddenServiceStatus ; + } + else + { + if(mHiddenService.empty()) + mHiddenService = service_id ; + + std::cerr << "New service acquired. Status is " << (int)service_status ; + + if(service_status == RsTorHiddenServiceStatus::ONLINE) + { + mHiddenServiceStatus = HIDDEN_SERVICE_STATUS_OK ; + std::cerr << ": published and running!" << std::endl; + + return mHiddenServiceStatus ; + } + else + { + std::cerr << ": not ready yet." << std::endl; + return mHiddenServiceStatus ; + } + } + } + case HIDDEN_SERVICE_STATUS_OK : + std::cerr << "New service acquired." << std::endl; + return mHiddenServiceStatus ; + } +} + diff --git a/retroshare-gui/src/TorControl/TorControlWindow.h b/retroshare-gui/src/TorControl/TorControlWindow.h new file mode 100644 index 000000000..5fc23e8e9 --- /dev/null +++ b/retroshare-gui/src/TorControl/TorControlWindow.h @@ -0,0 +1,50 @@ +#include "retroshare/rsevents.h" +#include "retroshare/rstor.h" +#include "ui_TorControlWindow.h" + +class QTcpServer ; + +namespace Tor { + class HiddenService ; + class TorManager ; +} + +class TorControlDialog: public QWidget, public Ui::TorControlDialog +{ + Q_OBJECT + +public: + TorControlDialog(QWidget *parent =NULL); + + enum TorStatus { + TOR_STATUS_UNKNOWN = 0x00, + TOR_STATUS_OK = 0x01, + TOR_STATUS_FAIL = 0x02 + }; + + enum HiddenServiceStatus { + HIDDEN_SERVICE_STATUS_UNKNOWN = 0x00, // no information known. + HIDDEN_SERVICE_STATUS_FAIL = 0x01, // some error occurred + 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 + + TorStatus checkForTor(QString& error_msg) ; + HiddenServiceStatus checkForHiddenService() ; + +protected slots: + void showLog(); + void statusChanged(RsTorStatus torstatus,RsTorConnectivityStatus tor_control_status); + void onIncomingConnection(); + + void handleEvent_main_thread(std::shared_ptr event); +private: + QString mErrorMsg ; + HiddenServiceStatus mHiddenServiceStatus ; + std::string mHiddenService; + + QTcpServer *mIncomingServer ; + RsEventsHandlerId_t mEventHandlerId; +}; diff --git a/retroshare-gui/src/TorControl/TorControlWindow.ui b/retroshare-gui/src/TorControl/TorControlWindow.ui new file mode 100644 index 000000000..602146641 --- /dev/null +++ b/retroshare-gui/src/TorControl/TorControlWindow.ui @@ -0,0 +1,134 @@ + + + TorControlDialog + + + + 0 + 0 + 600 + 228 + + + + + 0 + 0 + + + + Dialog + + + + + + + 75 + true + + + + Setting up Tor... + + + Qt::AlignCenter + + + + + + + + + + + + :/icons/tor-logo.png + + + false + + + + + + + + + Tor status: + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + Unknown + + + + + + + Not started + + + + + + + Hidden service address: + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + Tor bootstrap status: + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + Not set + + + + + + + Onion address: + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + Not set + + + + + + + + + + + + + + From 850554429432964ed0bcab275be2c590b7b07bcb Mon Sep 17 00:00:00 2001 From: csoler Date: Sat, 3 Jul 2021 21:54:44 +0200 Subject: [PATCH 10/65] removed signals in HiddenService class --- libretroshare/src/tor/HiddenService.cpp | 27 +++++++++++++++---------- libretroshare/src/tor/HiddenService.h | 26 +++++++++++++++--------- libretroshare/src/tor/TorManager.cpp | 19 +++++++++++------ libretroshare/src/tor/TorManager.h | 14 +++++++------ 4 files changed, 54 insertions(+), 32 deletions(-) diff --git a/libretroshare/src/tor/HiddenService.cpp b/libretroshare/src/tor/HiddenService.cpp index b2b58626a..22b7200fe 100644 --- a/libretroshare/src/tor/HiddenService.cpp +++ b/libretroshare/src/tor/HiddenService.cpp @@ -42,13 +42,13 @@ using namespace Tor; -HiddenService::HiddenService(QObject *parent) - : QObject(parent), m_status(NotCreated) +HiddenService::HiddenService(HiddenServiceClient *client) + : m_status(NotCreated), m_client(client) { } -HiddenService::HiddenService(const QString &path, QObject *parent) - : QObject(parent), m_dataPath(path), m_status(NotCreated) +HiddenService::HiddenService(HiddenServiceClient *client,const QString &path) + : m_dataPath(path), m_status(NotCreated), m_client(client) { /* Set the initial status and, if possible, load the hostname */ if (QDir(m_dataPath).exists(QLatin1String("private_key"))) { @@ -58,8 +58,8 @@ HiddenService::HiddenService(const QString &path, QObject *parent) } } -HiddenService::HiddenService(const CryptoKey &privateKey, const QString &path, QObject *parent) - : QObject(parent), m_dataPath(path), m_status(NotCreated) +HiddenService::HiddenService(HiddenServiceClient *client,const CryptoKey &privateKey, const QString &path) + : m_dataPath(path), m_status(NotCreated), m_client(client) { setPrivateKey(privateKey); m_status = Offline; @@ -73,10 +73,12 @@ void HiddenService::setStatus(Status newStatus) Status old = m_status; m_status = newStatus; - emit statusChanged(m_status, old); + if(m_client) + m_client->hiddenServiceStatusChanged(m_status,old); //emit statusChanged(m_status, old); if (m_status == Online) - emit serviceOnline(); + if(m_client) + m_client->hiddenServiceOnline(); //emit serviceOnline(); } void HiddenService::addTarget(const Target &target) @@ -95,7 +97,8 @@ void HiddenService::setServiceId(const QByteArray& sid) m_service_id = sid; m_hostname = sid + ".onion"; - emit hostnameChanged(); + if(m_client) + m_client->hiddenServiceHostnameChanged(); // emit hostnameChanged(); } void HiddenService::setPrivateKey(const CryptoKey &key) { @@ -113,7 +116,8 @@ void HiddenService::setPrivateKey(const CryptoKey &key) m_privateKey = key; - emit privateKeyChanged(); + if(m_client) + m_client->hiddenServicePrivateKeyChanged(); //emit privateKeyChanged(); } void HiddenService::loadPrivateKey() @@ -128,7 +132,8 @@ void HiddenService::loadPrivateKey() return; } - emit privateKeyChanged(); + if(m_client) + m_client->hiddenServicePrivateKeyChanged(); // emit privateKeyChanged(); } void HiddenService::servicePublished() diff --git a/libretroshare/src/tor/HiddenService.h b/libretroshare/src/tor/HiddenService.h index 20fa1d851..4efa55582 100644 --- a/libretroshare/src/tor/HiddenService.h +++ b/libretroshare/src/tor/HiddenService.h @@ -43,6 +43,18 @@ namespace Tor class TorSocket; +// This class is used to receive synchroneous notifications from the hidden service. +// Each client should implement its own notification handling. + +class HiddenServiceClient +{ +public: + virtual void hiddenServiceStatusChanged(int /* newStatus */, int /* oldStatus */) =0; + virtual void hiddenServiceOnline() =0; + virtual void hiddenServicePrivateKeyChanged() =0; + virtual void hiddenServiceHostnameChanged() =0; +}; + class HiddenService : public QObject { Q_OBJECT @@ -64,9 +76,9 @@ public: Online /* Published */ }; - HiddenService(QObject *parent = 0); - HiddenService(const QString &dataPath, QObject *parent = 0); - HiddenService(const CryptoKey &privateKey, const QString &dataPath = QString(), QObject *parent = 0); + HiddenService(HiddenServiceClient *client); + HiddenService(HiddenServiceClient *client,const QString &dataPath); + HiddenService(HiddenServiceClient *client,const CryptoKey &privateKey, const QString &dataPath = QString()); Status status() const { return m_status; } @@ -82,12 +94,6 @@ public: void addTarget(const Target &target); void addTarget(quint16 servicePort, QHostAddress targetAddress, quint16 targetPort); -signals: - void statusChanged(int newStatus, int oldStatus); - void serviceOnline(); - void privateKeyChanged(); - void hostnameChanged(); - private slots: void servicePublished(); @@ -101,6 +107,8 @@ private: void loadPrivateKey(); void setStatus(Status newStatus); + + HiddenServiceClient *m_client; }; } diff --git a/libretroshare/src/tor/TorManager.cpp b/libretroshare/src/tor/TorManager.cpp index fc81d943e..7fa645beb 100644 --- a/libretroshare/src/tor/TorManager.cpp +++ b/libretroshare/src/tor/TorManager.cpp @@ -175,23 +175,24 @@ bool TorManager::setupHiddenService() return false; } - d->hiddenService = new Tor::HiddenService(key, legacyDir, this); + d->hiddenService = new Tor::HiddenService(this,key, legacyDir); std::cerr << "Got key from legacy dir: " << std::endl; std::cerr << key.bytes().toStdString() << std::endl; } else { - d->hiddenService = new Tor::HiddenService(legacyDir, this); + d->hiddenService = new Tor::HiddenService(this,legacyDir); std::cerr << "Creating new hidden service." << std::endl; - connect(d->hiddenService, SIGNAL(privateKeyChanged()), this, SLOT(hiddenServicePrivateKeyChanged())) ; - connect(d->hiddenService, SIGNAL(hostnameChanged()), this, SLOT(hiddenServiceHostnameChanged())) ; + // connect(d->hiddenService, SIGNAL(privateKeyChanged()), this, SLOT(hiddenServicePrivateKeyChanged())) ; + // connect(d->hiddenService, SIGNAL(hostnameChanged()), this, SLOT(hiddenServiceHostnameChanged())) ; } - Q_ASSERT(d->hiddenService); - connect(d->hiddenService, SIGNAL(statusChanged(int,int)), this, SLOT(hiddenServiceStatusChanged(int,int))); + assert(d->hiddenService); + + // connect(d->hiddenService, SIGNAL(statusChanged(int,int)), this, SLOT(hiddenServiceStatusChanged(int,int))); // Generally, these are not used, and we bind to localhost and port 0 // for an automatic (and portable) selection. @@ -225,6 +226,9 @@ void TorManager::hiddenServiceStatusChanged(int old_status,int new_status) void TorManager::hiddenServicePrivateKeyChanged() { + if(!d->hiddenService) + return ; + QString key = QString::fromLatin1(d->hiddenService->privateKey().bytes()); QFile outfile(d->hiddenServiceDir + QLatin1String("/private_key")) ; @@ -249,6 +253,9 @@ void TorManager::hiddenServicePrivateKeyChanged() void TorManager::hiddenServiceHostnameChanged() { + if(!d->hiddenService) + return ; + QFile outfile2(d->hiddenServiceDir + QLatin1String("/hostname")) ; outfile2.open( QIODevice::WriteOnly | QIODevice::Text ); QTextStream t(&outfile2); diff --git a/libretroshare/src/tor/TorManager.h b/libretroshare/src/tor/TorManager.h index 9d3dd388d..3c9733519 100644 --- a/libretroshare/src/tor/TorManager.h +++ b/libretroshare/src/tor/TorManager.h @@ -36,6 +36,7 @@ #define TORMANAGER_H #include "retroshare/rstor.h" +#include "HiddenService.h" #include #include @@ -51,7 +52,7 @@ class TorManagerPrivate; /* Run/connect to an instance of Tor according to configuration, and manage * UI interaction, first time configuration, etc. */ -class TorManager : public QObject, public RsTor +class TorManager : public QObject, public HiddenServiceClient, public RsTor { Q_OBJECT @@ -90,13 +91,14 @@ public: bool getHiddenServiceInfo(QString& service_id,QString& service_onion_address,uint16_t& service_port, QHostAddress& service_target_address,uint16_t& target_port); bool getProxyServerInfo(QHostAddress& proxy_server_adress,uint16_t& proxy_server_port); -public slots: +//public slots: bool start(); -private slots: - void hiddenServicePrivateKeyChanged(); - void hiddenServiceHostnameChanged(); - void hiddenServiceStatusChanged(int old_status,int new_status); +//private slots: + virtual void hiddenServiceOnline() override {} // do nothing here. + virtual void hiddenServicePrivateKeyChanged() override; + virtual void hiddenServiceHostnameChanged() override; + virtual void hiddenServiceStatusChanged(int old_status,int new_status) override; signals: void configurationNeededChanged(); From b6156bff00f17cac02f79d0a5d7e3d45a8e3c78f Mon Sep 17 00:00:00 2001 From: csoler Date: Sun, 4 Jul 2021 14:06:37 +0200 Subject: [PATCH 11/65] fixed compilation for appveyor --- libretroshare/src/tor/TorManager.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/libretroshare/src/tor/TorManager.cpp b/libretroshare/src/tor/TorManager.cpp index 7fa645beb..18cb963cd 100644 --- a/libretroshare/src/tor/TorManager.cpp +++ b/libretroshare/src/tor/TorManager.cpp @@ -30,6 +30,7 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ +#include #include #include "TorManager.h" @@ -673,7 +674,7 @@ void RsTor::setHiddenServiceDirectory(const std::string& dir) TorManager *RsTor::instance() { - assert(getpid() == gettid()); // make sure we're not in a thread + assert(getpid() == syscall(SYS_gettid));// make sure we're not in a thread static TorManager *rsTor = nullptr; From abf481b0a181b51df03bca46715d80d3ed1bcda1 Mon Sep 17 00:00:00 2001 From: csoler Date: Sun, 4 Jul 2021 18:27:12 +0200 Subject: [PATCH 12/65] removal of slignal/slots --- libretroshare/src/libretroshare.pro | 2 +- libretroshare/src/retroshare/rstor.h | 4 ++ libretroshare/src/tor/TorManager.cpp | 61 ++++++++++++++++++++-------- libretroshare/src/tor/TorManager.h | 27 ++++++------ libretroshare/src/tor/TorProcess.cpp | 56 +++++++++++++++++-------- libretroshare/src/tor/TorProcess.h | 33 ++++++++++----- 6 files changed, 122 insertions(+), 61 deletions(-) diff --git a/libretroshare/src/libretroshare.pro b/libretroshare/src/libretroshare.pro index 0d3889708..21161433a 100644 --- a/libretroshare/src/libretroshare.pro +++ b/libretroshare/src/libretroshare.pro @@ -448,7 +448,7 @@ HEADERS += rsitems/rsitem.h \ serialiser/rstlvkeyvalue.h \ serialiser/rstlvgenericparam.h \ serialiser/rstlvgenericmap.h \ - serialiser/rstlvgenericmap.inl \ + serialiser/rstlvgenericmap.inl \ serialiser/rstlvlist.h \ serialiser/rstlvmaps.h \ serialiser/rstlvbanlist.h \ diff --git a/libretroshare/src/retroshare/rstor.h b/libretroshare/src/retroshare/rstor.h index 7538671b1..dd4739304 100644 --- a/libretroshare/src/retroshare/rstor.h +++ b/libretroshare/src/retroshare/rstor.h @@ -36,6 +36,8 @@ enum class RsTorManagerEventCode: uint8_t TOR_STATUS_CHANGED = 0x01, BOOTSTRAP_STATUS_CHANGED = 0x02, TOR_CONNECTIVITY_CHANGED = 0x03, + TOR_MANAGER_ERROR = 0x04, + CONFIGURATION_NEEDED = 0x05, }; // Status of the Tor hidden service setup/loaded by RS @@ -75,6 +77,7 @@ struct RsTorManagerEvent: public RsEvent RsTorConnectivityStatus mTorConnectivityStatus; RsTorStatus mTorStatus; + std::string mErrorMessage; ///* @see RsEvent @see RsSerializable void serial_process( RsGenericSerializer::SerializeJob j, RsGenericSerializer::SerializeContext& ctx ) override @@ -83,6 +86,7 @@ struct RsTorManagerEvent: public RsEvent RS_SERIAL_PROCESS(mTorManagerEventType); RS_SERIAL_PROCESS(mTorConnectivityStatus); RS_SERIAL_PROCESS(mTorStatus); + RS_SERIAL_PROCESS(mErrorMessage); } ~RsTorManagerEvent() = default; diff --git a/libretroshare/src/tor/TorManager.cpp b/libretroshare/src/tor/TorManager.cpp index 18cb963cd..9983d8c1f 100644 --- a/libretroshare/src/tor/TorManager.cpp +++ b/libretroshare/src/tor/TorManager.cpp @@ -33,6 +33,8 @@ #include #include +#include + #include "TorManager.h" #include "TorProcess.h" #include "TorControl.h" @@ -51,7 +53,7 @@ using namespace Tor; namespace Tor { -class TorManagerPrivate : public QObject +class TorManagerPrivate : public QObject, public TorProcessClient { Q_OBJECT @@ -75,23 +77,24 @@ public: void setError(const QString &errorMessage); + virtual void processStateChanged(int state) override; + virtual void processErrorChanged(const QString &errorMessage) override; + virtual void processLogMessage(const QString &message) override; + public slots: - void processStateChanged(int state); - void processErrorChanged(const QString &errorMessage); - void processLogMessage(const QString &message); void controlStatusChanged(int status); void getConfFinished(); }; } -TorManager::TorManager(QObject *parent) - : QObject(parent), d(new TorManagerPrivate(this)) +TorManager::TorManager() + : d(new TorManagerPrivate(this)) { } TorManagerPrivate::TorManagerPrivate(TorManager *parent) - : QObject(parent) + : QObject(nullptr) , q(parent) , process(0) , control(new TorControl(this)) @@ -105,7 +108,7 @@ TorManager *TorManager::instance() { static TorManager *p = 0; if (!p) - p = new TorManager(qApp); + p = new TorManager(); return p; } @@ -293,7 +296,8 @@ bool TorManager::start() { if (!d->errorMessage.isEmpty()) { d->errorMessage.clear(); - emit errorChanged(); + + //emit errorChanged(); // not needed because there's no error to handle } SettingsObject settings(QStringLiteral("tor")); @@ -341,11 +345,11 @@ bool TorManager::start() } if (!d->process) { - d->process = new TorProcess(this); - connect(d->process, SIGNAL(stateChanged(int)), d, SLOT(processStateChanged(int))); - connect(d->process, SIGNAL(errorMessageChanged(QString)), d, - SLOT(processErrorChanged(QString))); - connect(d->process, SIGNAL(logMessage(QString)), d, SLOT(processLogMessage(QString))); + d->process = new TorProcess(d); + + // QObject::connect(d->process, SIGNAL(stateChanged(int)), d, SLOT(processStateChanged(int))); + // QObject::connect(d->process, SIGNAL(errorMessageChanged(QString)), d, SLOT(processErrorChanged(QString))); + // QObject::connect(d->process, SIGNAL(logMessage(QString)), d, SLOT(processLogMessage(QString))); } if (!QFile::exists(d->dataDir) && !d->createDataDir(d->dataDir)) { @@ -362,7 +366,14 @@ bool TorManager::start() QFile torrc(d->dataDir + QStringLiteral("torrc")); if (!torrc.exists() || torrc.size() == 0) { d->configNeeded = true; - emit configurationNeededChanged(); + + if(rsEvents) + { + auto ev = std::make_shared(); + ev->mTorManagerEventType = RsTorManagerEventCode::CONFIGURATION_NEEDED; + rsEvents->sendEvent(ev); + } + //emit configurationNeededChanged(); } std::cerr << "Starting Tor process:" << std::endl; @@ -460,7 +471,14 @@ void TorManagerPrivate::getConfFinished() if (command->get("DisableNetwork").toInt() == 1 && !configNeeded) { configNeeded = true; - emit q->configurationNeededChanged(); + //emit q->configurationNeededChanged(); + + if(rsEvents) + { + auto ev = std::make_shared(); + ev->mTorManagerEventType = RsTorManagerEventCode::CONFIGURATION_NEEDED; + rsEvents->sendEvent(ev); + } } } @@ -527,7 +545,16 @@ bool TorManagerPrivate::createDefaultTorrc(const QString &path) void TorManagerPrivate::setError(const QString &message) { errorMessage = message; - emit q->errorChanged(); + + if(rsEvents) + { + auto ev = std::make_shared(); + + ev->mTorManagerEventType = RsTorManagerEventCode::TOR_MANAGER_ERROR; + ev->mErrorMessage = message.toStdString(); + rsEvents->sendEvent(ev); + } + //emit q->errorChanged(); } #include "TorManager.moc" diff --git a/libretroshare/src/tor/TorManager.h b/libretroshare/src/tor/TorManager.h index 3c9733519..e0a24ae15 100644 --- a/libretroshare/src/tor/TorManager.h +++ b/libretroshare/src/tor/TorManager.h @@ -38,7 +38,6 @@ #include "retroshare/rstor.h" #include "HiddenService.h" -#include #include #include @@ -52,17 +51,17 @@ class TorManagerPrivate; /* Run/connect to an instance of Tor according to configuration, and manage * UI interaction, first time configuration, etc. */ -class TorManager : public QObject, public HiddenServiceClient, public RsTor +class TorManager : public HiddenServiceClient, public RsTor { - Q_OBJECT + // Q_OBJECT - Q_PROPERTY(bool configurationNeeded READ configurationNeeded NOTIFY configurationNeededChanged) - Q_PROPERTY(QStringList logMessages READ logMessages CONSTANT) - Q_PROPERTY(Tor::TorProcess* process READ process CONSTANT) - Q_PROPERTY(Tor::TorControl* control READ control CONSTANT) - Q_PROPERTY(bool hasError READ hasError NOTIFY errorChanged) - Q_PROPERTY(QString errorMessage READ errorMessage NOTIFY errorChanged) - Q_PROPERTY(QString torDataDirectory READ torDataDirectory WRITE setTorDataDirectory) + // Q_PROPERTY(bool configurationNeeded READ configurationNeeded NOTIFY configurationNeededChanged) + // Q_PROPERTY(QStringList logMessages READ logMessages CONSTANT) + // Q_PROPERTY(Tor::TorProcess* process READ process CONSTANT) + // Q_PROPERTY(Tor::TorControl* control READ control CONSTANT) + // Q_PROPERTY(bool hasError READ hasError NOTIFY errorChanged) + // Q_PROPERTY(QString errorMessage READ errorMessage NOTIFY errorChanged) + // Q_PROPERTY(QString torDataDirectory READ torDataDirectory WRITE setTorDataDirectory) public: static TorManager *instance(); @@ -100,12 +99,12 @@ public: virtual void hiddenServiceHostnameChanged() override; virtual void hiddenServiceStatusChanged(int old_status,int new_status) override; -signals: - void configurationNeededChanged(); - void errorChanged(); +//signals: +// void configurationNeededChanged(); +// void errorChanged(); private: - explicit TorManager(QObject *parent = 0); + explicit TorManager(); TorManagerPrivate *d; friend class RsTor; }; diff --git a/libretroshare/src/tor/TorProcess.cpp b/libretroshare/src/tor/TorProcess.cpp index ca1aecfe5..1ad48db2d 100644 --- a/libretroshare/src/tor/TorProcess.cpp +++ b/libretroshare/src/tor/TorProcess.cpp @@ -39,8 +39,8 @@ using namespace Tor; -TorProcess::TorProcess(QObject *parent) - : QObject(parent), d(new TorProcessPrivate(this)) +TorProcess::TorProcess(TorProcessClient *client,QObject *parent) + : d(new TorProcessPrivate(this)),m_client(client) { } @@ -51,7 +51,7 @@ TorProcess::~TorProcess() } TorProcessPrivate::TorProcessPrivate(TorProcess *q) - : QObject(q), q(q), state(TorProcess::NotStarted), controlPort(0), controlPortAttempts(0) + : q(q), state(TorProcess::NotStarted), controlPort(0), controlPortAttempts(0) { connect(&process, &QProcess::started, this, &TorProcessPrivate::processStarted); connect(&process, (void (QProcess::*)(int, QProcess::ExitStatus))&QProcess::finished, @@ -124,15 +124,16 @@ void TorProcess::start() if (d->executable.isEmpty() || d->dataDir.isEmpty()) { d->errorMessage = QStringLiteral("Tor executable and data directory not specified"); d->state = Failed; - emit errorMessageChanged(d->errorMessage); - emit stateChanged(d->state); + + if(m_client) m_client->processStateChanged(d->state); // emit stateChanged(d->state); + if(m_client) m_client->processErrorChanged(d->errorMessage); // emit errorMessageChanged(d->errorMessage); return; } if (!d->ensureFilesExist()) { d->state = Failed; - emit errorMessageChanged(d->errorMessage); - emit stateChanged(d->state); + if(m_client) m_client->processErrorChanged(d->errorMessage);// emit errorMessageChanged(d->errorMessage); + if(m_client) m_client->processStateChanged(d->state);// emit stateChanged(d->state); return; } @@ -141,8 +142,8 @@ void TorProcess::start() if (password.isEmpty() || hashedPassword.isEmpty()) { d->errorMessage = QStringLiteral("Random password generation failed"); d->state = Failed; - emit errorMessageChanged(d->errorMessage); - emit stateChanged(d->state); + if(m_client) m_client->processErrorChanged(d->errorMessage);// emit errorMessageChanged(d->errorMessage); + if(m_client) m_client->processStateChanged(d->state); // emit stateChanged(d->state); } QStringList args; @@ -157,7 +158,8 @@ void TorProcess::start() args << d->extraSettings; d->state = Starting; - emit stateChanged(d->state); + + if(m_client) m_client->processStateChanged(d->state);// emit stateChanged(d->state); if (QFile::exists(d->controlPortFilePath())) QFile::remove(d->controlPortFilePath()); @@ -194,7 +196,23 @@ void TorProcess::stop() } #endif - emit stateChanged(d->state); + if(m_client) m_client->processStateChanged(d->state);// emit stateChanged(d->state); +} + +void TorProcess::stateChanged(int newState) +{ + if(m_client) + m_client->processStateChanged(newState); +} +void TorProcess::errorMessageChanged(const QString &errorMessage) +{ + if(m_client) + m_client->processErrorChanged(errorMessage); +} +void TorProcess::logMessage(const QString &message) +{ + if(m_client) + m_client->processLogMessage(message); } QByteArray TorProcess::controlPassword() @@ -246,7 +264,9 @@ QString TorProcessPrivate::controlPortFilePath() const void TorProcessPrivate::processStarted() { state = TorProcess::Connecting; - emit q->stateChanged(state); + + /*emit*/ q->stateChanged(state); + /*emit*/ q->stateChanged(state); controlPortAttempts = 0; controlPortTimer.start(); @@ -262,8 +282,8 @@ void TorProcessPrivate::processFinished() if (errorMessage.isEmpty()) errorMessage = QStringLiteral("Process exited unexpectedly (code %1)").arg(process.exitCode()); state = TorProcess::Failed; - emit q->errorMessageChanged(errorMessage); - emit q->stateChanged(state); + /*emit*/ q->errorMessageChanged(errorMessage); + /*emit*/ q->stateChanged(state); } void TorProcessPrivate::processError(QProcess::ProcessError error) @@ -277,7 +297,7 @@ void TorProcessPrivate::processReadable() while (process.bytesAvailable() > 0) { QByteArray line = process.readLine(2048).trimmed(); if (!line.isEmpty()) - emit q->logMessage(QString::fromLatin1(line)); + /*emit*/ q->logMessage(QString::fromLatin1(line)); } } @@ -295,7 +315,7 @@ void TorProcessPrivate::tryReadControlPort() if (!controlHost.isNull() && controlPort > 0) { controlPortTimer.stop(); state = TorProcess::Ready; - emit q->stateChanged(state); + /*emit*/ q->stateChanged(state); return; } } @@ -304,8 +324,8 @@ void TorProcessPrivate::tryReadControlPort() if (++controlPortAttempts * controlPortTimer.interval() > 10000) { errorMessage = QStringLiteral("No control port available after launching process"); state = TorProcess::Failed; - emit q->errorMessageChanged(errorMessage); - emit q->stateChanged(state); + /*emit*/ q->errorMessageChanged(errorMessage); + /*emit*/ q->stateChanged(state); } } diff --git a/libretroshare/src/tor/TorProcess.h b/libretroshare/src/tor/TorProcess.h index ad489dc43..9a2511f09 100644 --- a/libretroshare/src/tor/TorProcess.h +++ b/libretroshare/src/tor/TorProcess.h @@ -41,15 +41,25 @@ namespace Tor class TorProcessPrivate; +// This class is used to inherit calls from the TorProcess + +class TorProcessClient +{ +public: + virtual void processStateChanged(int) = 0; + virtual void processErrorChanged(const QString&) = 0; + virtual void processLogMessage(const QString&) = 0; +}; + /* Launches and controls a Tor instance with behavior suitable for bundling * an instance with the application. */ -class TorProcess : public QObject +class TorProcess { - Q_OBJECT - Q_ENUMS(State) + //Q_OBJECT + //Q_ENUMS(State) - Q_PROPERTY(State state READ state NOTIFY stateChanged) - Q_PROPERTY(QString errorMessage READ errorMessage NOTIFY errorMessageChanged) + //Q_PROPERTY(State state READ state NOTIFY stateChanged) + //Q_PROPERTY(QString errorMessage READ errorMessage NOTIFY errorMessageChanged) public: enum State { @@ -60,7 +70,7 @@ public: Ready }; - explicit TorProcess(QObject *parent = 0); + explicit TorProcess(TorProcessClient *client,QObject *parent = 0); virtual ~TorProcess(); QString executable() const; @@ -81,17 +91,18 @@ public: quint16 controlPort(); QByteArray controlPassword(); -public slots: - void start(); - void stop(); - -signals: +//signals: void stateChanged(int newState); void errorMessageChanged(const QString &errorMessage); void logMessage(const QString &message); +//public slots: + void start(); + void stop(); + private: TorProcessPrivate *d; + TorProcessClient *m_client; }; } From f5f608dbec8086ea553d4bd4135212c595e84a1b Mon Sep 17 00:00:00 2001 From: csoler Date: Sat, 28 Aug 2021 21:39:12 +0200 Subject: [PATCH 13/65] trying to fix compilation on windows --- libretroshare/src/tor/TorManager.cpp | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/libretroshare/src/tor/TorManager.cpp b/libretroshare/src/tor/TorManager.cpp index 9983d8c1f..a4bb04e4f 100644 --- a/libretroshare/src/tor/TorManager.cpp +++ b/libretroshare/src/tor/TorManager.cpp @@ -30,9 +30,14 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#include #include +#if defined(_WIN32) || defined(__MINGW32__) +#include +#else +#include +#endif + #include #include "TorManager.h" From 5e851b4efdbf6036c9b86fe3dd9631b876a8a522 Mon Sep 17 00:00:00 2001 From: csoler Date: Sat, 28 Aug 2021 21:46:02 +0200 Subject: [PATCH 14/65] trying to fix compilation on windows --- libretroshare/src/tor/TorManager.cpp | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/libretroshare/src/tor/TorManager.cpp b/libretroshare/src/tor/TorManager.cpp index a4bb04e4f..f825bbfc7 100644 --- a/libretroshare/src/tor/TorManager.cpp +++ b/libretroshare/src/tor/TorManager.cpp @@ -32,9 +32,10 @@ #include -#if defined(_WIN32) || defined(__MINGW32__) -#include -#else +// This works on linux only. I have no clue how to do that on windows. Anyway, this +// is only needed for an assert that should normaly never be triggered. + +#if !defined(_WIN32) && !defined(__MINGW32__) #include #endif @@ -706,7 +707,9 @@ void RsTor::setHiddenServiceDirectory(const std::string& dir) TorManager *RsTor::instance() { +#if !defined(_WIN32) && !defined(__MINGW32__) assert(getpid() == syscall(SYS_gettid));// make sure we're not in a thread +#endif static TorManager *rsTor = nullptr; From 3845dc1ea7fa759793f76cb55ae66f6979006a2b Mon Sep 17 00:00:00 2001 From: csoler Date: Mon, 22 Nov 2021 20:06:01 +0100 Subject: [PATCH 15/65] added new files --- libretroshare/src/pqi/pqifdbin.cc | 272 +++++++++++++++++++++++++++ libretroshare/src/pqi/pqifdbin.h | 77 ++++++++ libretroshare/src/pqi/rstcpsocket.cc | 75 ++++++++ libretroshare/src/pqi/rstcpsocket.h | 41 ++++ 4 files changed, 465 insertions(+) create mode 100644 libretroshare/src/pqi/pqifdbin.cc create mode 100644 libretroshare/src/pqi/pqifdbin.h create mode 100644 libretroshare/src/pqi/rstcpsocket.cc create mode 100644 libretroshare/src/pqi/rstcpsocket.h diff --git a/libretroshare/src/pqi/pqifdbin.cc b/libretroshare/src/pqi/pqifdbin.cc new file mode 100644 index 000000000..68798bf3d --- /dev/null +++ b/libretroshare/src/pqi/pqifdbin.cc @@ -0,0 +1,272 @@ +/******************************************************************************* + * libretroshare/src/file_sharing: fsbio.cc * + * * + * libretroshare: retroshare core library * + * * + * Copyright 2021 by retroshare team * + * * + * This program is free software: you can redistribute it and/or modify * + * it under the terms of the GNU Lesser General Public License as * + * published by the Free Software Foundation, either version 3 of the * + * License, or (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU Lesser General Public License for more details. * + * * + * You should have received a copy of the GNU Lesser General Public License * + * along with this program. If not, see . * + * * + ******************************************************************************/ + +#include "util/rsprint.h" +#include "pqi/pqifdbin.h" + +RsFdBinInterface::RsFdBinInterface(int file_descriptor) + : mCLintConnt(file_descriptor),mIsActive(file_descriptor!=0) +{ + mTotalReadBytes=0; + mTotalInBufferBytes=0; + mTotalWrittenBytes=0; + mTotalOutBufferBytes=0; +} + +void RsFdBinInterface::setSocket(int s) +{ + if(mIsActive != 0) + { + RsErr() << "Changing socket to active FsBioInterface! Canceling all pending R/W data." ; + close(); + } + mCLintConnt = s; + mIsActive = (s!=0); +} +int RsFdBinInterface::tick() +{ + if(!mIsActive) + { + RsErr() << "Ticking a non active FsBioInterface!" ; + return 0; + } + // 2 - read incoming data pending on existing connections + + int res=0; + + res += read_pending(); + res += write_pending(); + + return res; +} + +int RsFdBinInterface::read_pending() +{ + char inBuffer[1025]; + memset(inBuffer,0,1025); + + ssize_t readbytes = recv(mCLintConnt, inBuffer, sizeof(inBuffer),MSG_DONTWAIT); + + if(readbytes == 0) + { + RsDbg() << "Reached END of the stream!" ; + RsDbg() << "Closing!" ; + + close(); + return mTotalInBufferBytes; + } + if(readbytes < 0) + { + if(errno != EWOULDBLOCK && errno != EAGAIN) + RsErr() << "read() failed. Errno=" << errno ; + + return mTotalInBufferBytes; + } + + RsDbg() << "clintConnt: " << mCLintConnt << ", readbytes: " << readbytes ; + + // display some debug info + + if(readbytes > 0) + { + RsDbg() << "Received the following bytes: " << RsUtil::BinToHex( reinterpret_cast(inBuffer),readbytes,50) << std::endl; + //RsDbg() << "Received the following bytes: " << std::string(inBuffer,readbytes) << std::endl; + + void *ptr = malloc(readbytes); + + if(!ptr) + throw std::runtime_error("Cannot allocate memory! Go buy some RAM!"); + + memcpy(ptr,inBuffer,readbytes); + + in_buffer.push_back(std::make_pair(ptr,readbytes)); + mTotalInBufferBytes += readbytes; + mTotalReadBytes += readbytes; + + RsDbg() << "Socket: " << mCLintConnt << ". Total read: " << mTotalReadBytes << ". Buffer size: " << mTotalInBufferBytes ; + } + return mTotalInBufferBytes; +} + +int RsFdBinInterface::write_pending() +{ + if(out_buffer.empty()) + return mTotalOutBufferBytes; + + auto& p = out_buffer.front(); + int written = write(mCLintConnt, p.first, p.second); + + if(written < 0) + { + if(errno != EWOULDBLOCK && errno != EAGAIN) + RsErr() << "write() failed. Errno=" << errno ; + + return mTotalOutBufferBytes; + } + + if(written == 0) + { + RsErr() << "write() failed. Nothing sent."; + return mTotalOutBufferBytes; + } + + RsDbg() << "clintConnt: " << mCLintConnt << ", written: " << written ; + + // display some debug info + + RsDbg() << "Sent the following bytes: " << RsUtil::BinToHex( reinterpret_cast(p.first),written,50) << std::endl; + + if(written < p.second) + { + void *ptr = malloc(p.second - written); + + if(!ptr) + throw std::runtime_error("Cannot allocate memory! Go buy some RAM!"); + + memcpy(ptr,static_cast(p.first) + written,p.second - written); + free(p.first); + + out_buffer.front().first = ptr; + out_buffer.front().second = p.second - written; + } + else + { + free(p.first); + out_buffer.pop_front(); + } + + mTotalOutBufferBytes -= written; + mTotalWrittenBytes += written; + + return mTotalOutBufferBytes; +} + +RsFdBinInterface::~RsFdBinInterface() +{ + clean(); +} + +void RsFdBinInterface::clean() +{ + for(auto p:in_buffer) free(p.first); + for(auto p:out_buffer) free(p.first); + + in_buffer.clear(); + out_buffer.clear(); +} +int RsFdBinInterface::readdata(void *data, int len) +{ + // read incoming bytes in the buffer + + int total_len = 0; + + while(total_len < len) + { + if(in_buffer.empty()) + { + mTotalInBufferBytes -= total_len; + return total_len; + } + + // If the remaining buffer is too large, chop of the beginning of it. + + if(total_len + in_buffer.front().second > len) + { + memcpy(&(static_cast(data)[total_len]),in_buffer.front().first,len - total_len); + + void *ptr = malloc(in_buffer.front().second - (len - total_len)); + memcpy(ptr,&(static_cast(in_buffer.front().first)[len - total_len]),in_buffer.front().second - (len - total_len)); + + free(in_buffer.front().first); + in_buffer.front().first = ptr; + in_buffer.front().second -= len-total_len; + + mTotalInBufferBytes -= len; + return len; + } + else // copy everything + { + memcpy(&(static_cast(data)[total_len]),in_buffer.front().first,in_buffer.front().second); + + total_len += in_buffer.front().second; + + free(in_buffer.front().first); + in_buffer.pop_front(); + } + } + mTotalInBufferBytes -= len; + return len; +} + +int RsFdBinInterface::senddata(void *data, int len) +{ + // shouldn't we better send in multiple packets, similarly to how we read? + + if(len == 0) + { + RsErr() << "Calling FsBioInterface::senddata() with null size or null data pointer"; + return 0; + } + void *ptr = malloc(len); + + if(!ptr) + { + RsErr() << "Cannot allocate data of size " << len ; + return 0; + } + + memcpy(ptr,data,len); + out_buffer.push_back(std::make_pair(ptr,len)); + + mTotalOutBufferBytes += len; + return len; +} +int RsFdBinInterface::netstatus() +{ + return mIsActive; // dummy response. +} + +int RsFdBinInterface::isactive() +{ + return mIsActive ; +} + +bool RsFdBinInterface::moretoread(uint32_t /* usec */) +{ + return mTotalInBufferBytes > 0; +} +bool RsFdBinInterface::cansend(uint32_t) +{ + return isactive(); +} + +int RsFdBinInterface::close() +{ + RsDbg() << "Stopping network interface" << std::endl; + mIsActive = false; + mCLintConnt = 0; + clean(); + + return 1; +} + + diff --git a/libretroshare/src/pqi/pqifdbin.h b/libretroshare/src/pqi/pqifdbin.h new file mode 100644 index 000000000..4c532b436 --- /dev/null +++ b/libretroshare/src/pqi/pqifdbin.h @@ -0,0 +1,77 @@ +/******************************************************************************* + * libretroshare/src/file_sharing: fsbio.h * + * * + * libretroshare: retroshare core library * + * * + * Copyright 2021 by retroshare team * + * * + * This program is free software: you can redistribute it and/or modify * + * it under the terms of the GNU Lesser General Public License as * + * published by the Free Software Foundation, either version 3 of the * + * License, or (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU Lesser General Public License for more details. * + * * + * You should have received a copy of the GNU Lesser General Public License * + * along with this program. If not, see . * + * * + ******************************************************************************/ + +#include "pqi/pqi_base.h" + +class RsFdBinInterface: public BinInterface +{ +public: + RsFdBinInterface(int file_descriptor); + ~RsFdBinInterface(); + + // Implements BinInterface methods + + int tick() override; + + // Schedule data to be sent at the next tick(). The caller keeps memory ownership. + // + int senddata(void *data, int len) override; + + // Obtains new data from the interface. "data" needs to be initialized for room + // to len bytes. The returned value is the actual size of what was read. + // + int readdata(void *data, int len) override; + + int netstatus() override; + int isactive() override; + bool moretoread(uint32_t usec) override; + bool cansend(uint32_t usec) override; + + int close() override; + + /** + * If hashing data + **/ + RsFileHash gethash() override { return RsFileHash() ; } + uint64_t bytecount() override { return mTotalReadBytes; } + + bool bandwidthLimited() override { return false; } + +protected: + void setSocket(int s); + void clean(); + +private: + int read_pending(); + int write_pending(); + + int mCLintConnt; + bool mIsActive; + uint32_t mTotalReadBytes; + uint32_t mTotalInBufferBytes; + uint32_t mTotalWrittenBytes; + uint32_t mTotalOutBufferBytes; + + std::list > in_buffer; + std::list > out_buffer; +}; + diff --git a/libretroshare/src/pqi/rstcpsocket.cc b/libretroshare/src/pqi/rstcpsocket.cc new file mode 100644 index 000000000..25f830914 --- /dev/null +++ b/libretroshare/src/pqi/rstcpsocket.cc @@ -0,0 +1,75 @@ +#include +#include +#include +#include +#include + +#include "rstcpsocket.h" + +RsTcpSocket::RsTcpSocket(const std::string& tcp_address,uint16_t tcp_port) + :RsFdBinInterface(0),mState(DISCONNECTED),mConnectAddress(tcp_address),mConnectPort(tcp_port),mSocket(0) +{ +} +int RsTcpSocket::connect() +{ + int CreateSocket = 0; + char dataReceived[1024]; + struct sockaddr_in ipOfServer; + + memset(dataReceived, '0' ,sizeof(dataReceived)); + + if((CreateSocket = socket(AF_INET, SOCK_STREAM, 0))< 0) + { + printf("Socket not created \n"); + return false; + } + + ipOfServer.sin_family = AF_INET; + ipOfServer.sin_port = htons(mConnectPort); + ipOfServer.sin_addr.s_addr = inet_addr(mConnectAddress.c_str()); + + if(::connect(mSocket, (struct sockaddr *)&ipOfServer, sizeof(ipOfServer))<0) + { + printf("Connection failed due to port and ip problems, or server is not available\n"); + return false; + } + mState = CONNECTED; + setSocket(mSocket); + + return true; +} + +int RsTcpSocket::close() +{ + RsFdBinInterface::close(); + + return !::close(mSocket); +} + +RsThreadedTcpSocket::RsThreadedTcpSocket(const std::string& tcp_address,uint16_t tcp_port) + : RsTcpSocket(tcp_address,tcp_port) +{ +} + +void RsThreadedTcpSocket::run() +{ + if(!connect()) + { + RsErr() << "Cannot connect socket to " << connectAddress() << ":" << connectPort() ; + return ; + } + + while(connectionState() == CONNECTED) + { + tick(); + std::this_thread::sleep_for(std::chrono::milliseconds(200)); + } + RsWarn() << "Connection to " << connectAddress() << ":" << connectPort() << " is now closed."; +} + +RsThreadedTcpSocket::~RsThreadedTcpSocket() +{ + fullstop(); // fully wait for stopping. + + close(); +} diff --git a/libretroshare/src/pqi/rstcpsocket.h b/libretroshare/src/pqi/rstcpsocket.h new file mode 100644 index 000000000..bdc127f91 --- /dev/null +++ b/libretroshare/src/pqi/rstcpsocket.h @@ -0,0 +1,41 @@ +#include +#include "util/rsthreads.h" +#include "pqi/pqifdbin.h" + +class RsTcpSocket: public RsFdBinInterface +{ +public: + RsTcpSocket(const std::string& tcp_address,uint16_t tcp_port); + + enum State: uint8_t { + UNKNOWN = 0x00, + DISCONNECTED = 0x01, + CONNECTED = 0x02 + }; + + // Return 1 when OK, 0 otherwise. + int connect(); + + // Returns 1 when OK, 0 otherwise. + int close(); + + State connectionState() const { return mState; } + const std::string& connectAddress() const { return mConnectAddress ; } + uint16_t connectPort() const { return mConnectPort ; } + +private: + State mState; + std::string mConnectAddress; + uint16_t mConnectPort; + int mSocket; +}; + +class RsThreadedTcpSocket: public RsTcpSocket, public RsThread +{ +public: + RsThreadedTcpSocket(const std::string& tcp_address,uint16_t tcp_port); + virtual ~RsThreadedTcpSocket(); + + virtual void run() override; +}; + From e4ce32bef8d2d8e8593fd0c12f244e670e15498e Mon Sep 17 00:00:00 2001 From: csoler Date: Thu, 25 Nov 2021 23:28:01 +0100 Subject: [PATCH 16/65] switching QString to std::string and QByteArray to ByteArray. Unfinished yet. --- libretroshare/src/libretroshare.pro | 5 + libretroshare/src/tor/AuthenticateCommand.cpp | 20 +- libretroshare/src/tor/AuthenticateCommand.h | 9 +- libretroshare/src/tor/CryptoKey.cpp | 450 ++---------------- libretroshare/src/tor/CryptoKey.h | 49 +- libretroshare/src/tor/GetConfCommand.cpp | 55 +-- libretroshare/src/tor/GetConfCommand.h | 16 +- libretroshare/src/tor/HiddenService.cpp | 8 +- libretroshare/src/tor/HiddenService.h | 26 +- libretroshare/src/tor/ProtocolInfoCommand.cpp | 16 +- libretroshare/src/tor/ProtocolInfoCommand.h | 4 +- libretroshare/src/tor/SetConfCommand.cpp | 60 +-- libretroshare/src/tor/SetConfCommand.h | 11 +- libretroshare/src/tor/Settings.cpp | 16 +- libretroshare/src/tor/Settings.h | 1 - libretroshare/src/tor/StrUtil.cpp | 24 +- libretroshare/src/tor/StrUtil.h | 11 +- libretroshare/src/tor/TorControl.cpp | 44 +- libretroshare/src/tor/TorControlCommand.cpp | 4 +- libretroshare/src/tor/TorControlCommand.h | 9 +- libretroshare/src/tor/TorControlSocket.cpp | 9 +- libretroshare/src/tor/TorControlSocket.h | 21 +- libretroshare/src/tor/TorSocket.cpp | 155 ------ libretroshare/src/tor/TorSocket.h | 97 ---- libretroshare/src/tor/bytearray.h | 91 ++++ 25 files changed, 312 insertions(+), 899 deletions(-) delete mode 100644 libretroshare/src/tor/TorSocket.cpp delete mode 100644 libretroshare/src/tor/TorSocket.h create mode 100644 libretroshare/src/tor/bytearray.h diff --git a/libretroshare/src/libretroshare.pro b/libretroshare/src/libretroshare.pro index 5d9a764a9..e1ed55b95 100644 --- a/libretroshare/src/libretroshare.pro +++ b/libretroshare/src/libretroshare.pro @@ -369,6 +369,8 @@ HEADERS += pqi/authssl.h \ pqi/authgpg.h \ pgp/pgphandler.h \ pgp/pgpkeyutil.h \ + pqi/pqifdbin.h \ + pqi/rstcpsocket.h \ pgp/rscertificate.h \ pgp/pgpauxutils.h \ pqi/p3cfgmgr.h \ @@ -545,6 +547,8 @@ SOURCES += pqi/authgpg.cc \ pqi/p3cfgmgr.cc \ pqi/p3peermgr.cc \ pqi/p3linkmgr.cc \ + pqi/pqifdbin.cc \ + pqi/rstcpsocket.cc \ pqi/p3netmgr.cc \ pqi/p3notify.cc \ pqi/pqiqos.cc \ @@ -733,6 +737,7 @@ HEADERS += tor/AddOnionCommand.h \ tor/SetConfCommand.h \ tor/Settings.h \ tor/StrUtil.h \ + tor/bytearray.h \ tor/TorControl.h \ tor/TorControlCommand.h \ tor/TorControlSocket.h \ diff --git a/libretroshare/src/tor/AuthenticateCommand.cpp b/libretroshare/src/tor/AuthenticateCommand.cpp index 497c28f89..ab510c24b 100644 --- a/libretroshare/src/tor/AuthenticateCommand.cpp +++ b/libretroshare/src/tor/AuthenticateCommand.cpp @@ -38,27 +38,29 @@ AuthenticateCommand::AuthenticateCommand() { } -QByteArray AuthenticateCommand::build(const QByteArray &data) +ByteArray AuthenticateCommand::build(const ByteArray& data) { if (data.isNull()) - return QByteArray("AUTHENTICATE\r\n"); + return ByteArray("AUTHENTICATE\r\n"); - return QByteArray("AUTHENTICATE ") + data.toHex() + "\r\n"; + return ByteArray("AUTHENTICATE ") + data.toHex() + "\r\n"; } -void AuthenticateCommand::onReply(int statusCode, const QByteArray &data) +void AuthenticateCommand::onReply(int statusCode, const ByteArray &data) { TorControlCommand::onReply(statusCode, data); - m_statusMessage = QString::fromLatin1(data); + m_statusMessage = data.toString(); } void AuthenticateCommand::onFinished(int statusCode) { if (statusCode == 515) { - m_statusMessage = QStringLiteral("Authentication failed - incorrect password"); - } else if (statusCode != 250) { - if (m_statusMessage.isEmpty()) - m_statusMessage = QStringLiteral("Authentication failed (error %1").arg(statusCode); + m_statusMessage = "Authentication failed - incorrect password"; + } + else if (statusCode != 250) + { + if (m_statusMessage.empty()) + m_statusMessage = "Authentication failed (error " + RsUtil::NumberToString(statusCode) + ")"; } TorControlCommand::onFinished(statusCode); } diff --git a/libretroshare/src/tor/AuthenticateCommand.h b/libretroshare/src/tor/AuthenticateCommand.h index 79c901d98..86c1b7f56 100644 --- a/libretroshare/src/tor/AuthenticateCommand.h +++ b/libretroshare/src/tor/AuthenticateCommand.h @@ -33,6 +33,7 @@ #ifndef AUTHENTICATECOMMAND_H #define AUTHENTICATECOMMAND_H +#include "bytearray.h" #include "TorControlCommand.h" namespace Tor @@ -45,17 +46,17 @@ class AuthenticateCommand : public TorControlCommand public: AuthenticateCommand(); - QByteArray build(const QByteArray &data = QByteArray()); + ByteArray build(const ByteArray& data = ByteArray()); bool isSuccessful() const { return statusCode() == 250; } - QString errorMessage() const { return m_statusMessage; } + std::string errorMessage() const { return m_statusMessage; } protected: - virtual void onReply(int statusCode, const QByteArray &data); + virtual void onReply(int statusCode, const ByteArray &data); virtual void onFinished(int statusCode); private: - QString m_statusMessage; + std::string m_statusMessage; }; } diff --git a/libretroshare/src/tor/CryptoKey.cpp b/libretroshare/src/tor/CryptoKey.cpp index 9be9a6699..2dd151bad 100644 --- a/libretroshare/src/tor/CryptoKey.cpp +++ b/libretroshare/src/tor/CryptoKey.cpp @@ -35,13 +35,18 @@ #include "CryptoKey.h" #include "SecureRNG.h" #include "Useful.h" -#include -#include -#include + #include #include #include +#include "stdio.h" +#include "util/rsdebug.h" +#include "util/rsrandom.h" +#include "util/rsdir.h" +#include "retroshare/rsids.h" +#include "bytearray.h" + #if OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER) void RSA_get0_factors(const RSA *r, const BIGNUM **p, const BIGNUM **q) { @@ -51,11 +56,6 @@ void RSA_get0_factors(const RSA *r, const BIGNUM **p, const BIGNUM **q) #define RSA_bits(o) (BN_num_bits((o)->n)) #endif -#ifdef TO_REMOVE -void base32_encode(char *dest, unsigned destlen, const char *src, unsigned srclen); -bool base32_decode(char *dest, unsigned destlen, const char *src, unsigned srclen); -#endif - CryptoKey::CryptoKey() { } @@ -65,95 +65,50 @@ CryptoKey::~CryptoKey() clear(); } -#ifdef TO_REMOVE -CryptoKey::Data::~Data() -{ - if (key) - { - RSA_free(key); - key = 0; - } -} -#endif - void CryptoKey::clear() { key_data.clear(); } -#ifdef TO_REMOVE -bool CryptoKey::loadFromData(const QByteArray &data, KeyType type, KeyFormat format) +bool CryptoKey::loadFromFile(const std::string& path) { - RSA *key = NULL; - clear(); + FILE *file = fopen(path.c_str(),"r"); - if (data.isEmpty()) - return false; - - if (format == PEM) { - BIO *b = BIO_new_mem_buf((void*)data.constData(), -1); - - if (type == PrivateKey) - key = PEM_read_bio_RSAPrivateKey(b, NULL, NULL, NULL); - else - key = PEM_read_bio_RSAPublicKey(b, NULL, NULL, NULL); - - BIO_free(b); - } else if (format == DER) { - const uchar *dp = reinterpret_cast(data.constData()); - - if (type == PrivateKey) - key = d2i_RSAPrivateKey(NULL, &dp, data.size()); - else - key = d2i_RSAPublicKey(NULL, &dp, data.size()); - } else { - Q_UNREACHABLE(); - } - - if (!key) { - qWarning() << "Failed to parse" << (type == PrivateKey ? "private" : "public") << "key from data"; - return false; - } - - d = new Data(key); - return true; -} -#endif - -bool CryptoKey::loadFromFile(const QString& path) -{ - QFile file(path); - if (!file.open(QIODevice::ReadOnly)) + if (!file) { - qWarning() << "Failed to open Tor key file " << path << ": " << file.errorString(); + RsWarn() << "Failed to open Tor key file " << path << ": errno = " << errno ; return false; } - QByteArray data = file.readAll(); - file.close(); + ByteArray data ; + int c; + while(EOF != (c=fgetc(file))) + data.append((unsigned char)c); - if(data.contains("-----BEGIN RSA PRIVATE KEY-----")) + fclose(file); + + if(data.startsWith("-----BEGIN RSA PRIVATE KEY-----")) { std::cerr << "Note: Reading/converting Tor v2 key format." << std::endl; // This to be compliant with old format. New format is oblivious to the type of key so we dont need a header - data = data.replace("-----BEGIN RSA PRIVATE KEY-----",nullptr); - data = data.replace("-----END RSA PRIVATE KEY-----",nullptr); - data = data.replace("\n",nullptr); - data = data.replace("\t",nullptr); + data = data.replace(ByteArray("-----BEGIN RSA PRIVATE KEY-----"),ByteArray()); + data = data.replace(ByteArray("-----END RSA PRIVATE KEY-----"),ByteArray()); + data = data.replace(ByteArray("\n"),ByteArray()); + data = data.replace(ByteArray("\t"),ByteArray()); - data = "RSA1024:"+data; + data = ByteArray("RSA1024:")+data; } std::cerr << "Have read the following key: " << std::endl; - std::cerr << QString(data).toStdString() << std::endl; + std::cerr << data.toString() << std::endl; key_data = data; return true; } -bool CryptoKey::loadFromTorMessage(const QByteArray& b) +bool CryptoKey::loadFromTorMessage(const ByteArray& b) { // note: We should probably check the structure a bit more, for security. @@ -165,7 +120,7 @@ bool CryptoKey::loadFromTorMessage(const QByteArray& b) std::cerr << " type: ED25519-V3 (Tor v3)" << std::endl; else if(b.indexOf(':')) { - std::cerr << " unknown type, or bad syntax in key: \"" << b.left(b.indexOf(':')).toStdString() << "\". Not accepted." << std::endl; + std::cerr << " unknown type, or bad syntax in key: \"" << b.left(b.indexOf(':')).toString() << "\". Not accepted." << std::endl; return false; } @@ -174,354 +129,15 @@ bool CryptoKey::loadFromTorMessage(const QByteArray& b) } /* Cryptographic hash of a password as expected by Tor's HashedControlPassword */ -QByteArray torControlHashedPassword(const QByteArray &password) +ByteArray torControlHashedPassword(const ByteArray &password) { - QByteArray salt = SecureRNG::random(8); - if (salt.isNull()) - return QByteArray(); + ByteArray salt(8); + RsRandom::random_bytes(&salt[0],8); - int count = ((quint32)16 + (96 & 15)) << ((96 >> 4) + 6); + uint32_t count = ((quint32)16 + (96 & 15)) << ((96 >> 4) + 6); - SHA_CTX hash; - SHA1_Init(&hash); - - QByteArray tmp = salt + password; - while (count) - { - int c = qMin(count, tmp.size()); - SHA1_Update(&hash, reinterpret_cast(tmp.constData()), c); - count -= c; - } - - unsigned char md[20]; - SHA1_Final(md, &hash); + Sha1CheckSum md = RsDirUtil::sha1sum((salt+password).data(),count); /* 60 is the hex-encoded value of 96, which is a constant used by Tor's algorithm. */ - return QByteArray("16:") + salt.toHex().toUpper() + QByteArray("60") + - QByteArray::fromRawData(reinterpret_cast(md), 20).toHex().toUpper(); + return ByteArray("16:") + salt.toHex().toUpper() + ByteArray("60") + ByteArray(md.toByteArray(), md.SIZE_IN_BYTES).toHex().toUpper(); } - - -#ifdef TO_REMOVE -bool CryptoKey::isPrivate() const -{ - if (!isLoaded()) { - return false; - } else { - const BIGNUM *p, *q; - RSA_get0_factors(d->key, &p, &q); - return (p != 0); - } -} - -int CryptoKey::bits() const -{ - return isLoaded() ? RSA_bits(d->key) : 0; -} - -QByteArray CryptoKey::publicKeyDigest() const -{ - if (!isLoaded()) - return QByteArray(); - - QByteArray buf = encodedPublicKey(DER); - - QByteArray re(20, 0); - bool ok = SHA1(reinterpret_cast(buf.constData()), buf.size(), - reinterpret_cast(re.data())) != NULL; - - if (!ok) - { - qWarning() << "Failed to hash public key data for digest"; - return QByteArray(); - } - - return re; -} - -QByteArray CryptoKey::encodedPublicKey(KeyFormat format) const -{ - if (!isLoaded()) - return QByteArray(); - - if (format == PEM) { - BIO *b = BIO_new(BIO_s_mem()); - - if (!PEM_write_bio_RSAPublicKey(b, d->key)) { - BUG() << "Failed to encode public key in PEM format"; - BIO_free(b); - return QByteArray(); - } - - BUF_MEM *buf; - BIO_get_mem_ptr(b, &buf); - - /* Close BIO, but don't free buf. */ - (void)BIO_set_close(b, BIO_NOCLOSE); - BIO_free(b); - - QByteArray re((const char *)buf->data, (int)buf->length); - BUF_MEM_free(buf); - return re; - } else if (format == DER) { - uchar *buf = NULL; - int len = i2d_RSAPublicKey(d->key, &buf); - if (len <= 0 || !buf) { - BUG() << "Failed to encode public key in DER format"; - return QByteArray(); - } - - QByteArray re((const char*)buf, len); - OPENSSL_free(buf); - return re; - } else { - Q_UNREACHABLE(); - } - - return QByteArray(); -} - -QByteArray CryptoKey::encodedPrivateKey(KeyFormat format) const -{ - if (!isLoaded() || !isPrivate()) - return QByteArray(); - - if (format == PEM) { - BIO *b = BIO_new(BIO_s_mem()); - - if (!PEM_write_bio_RSAPrivateKey(b, d->key, NULL, NULL, 0, NULL, NULL)) { - BUG() << "Failed to encode private key in PEM format"; - BIO_free(b); - return QByteArray(); - } - - BUF_MEM *buf; - BIO_get_mem_ptr(b, &buf); - - /* Close BIO, but don't free buf. */ - (void)BIO_set_close(b, BIO_NOCLOSE); - BIO_free(b); - - QByteArray re((const char *)buf->data, (int)buf->length); - BUF_MEM_free(buf); - return re; - } else if (format == DER) { - uchar *buf = NULL; - int len = i2d_RSAPrivateKey(d->key, &buf); - if (len <= 0 || !buf) { - BUG() << "Failed to encode private key in DER format"; - return QByteArray(); - } - - QByteArray re((const char*)buf, len); - OPENSSL_free(buf); - return re; - } else { - Q_UNREACHABLE(); - } - - return QByteArray(); -} - -QString CryptoKey::torServiceID() const -{ - if (!isLoaded()) - return QString(); - - QByteArray digest = publicKeyDigest(); - if (digest.isNull()) - return QString(); - - static const int hostnameDigestSize = 10; - static const int hostnameEncodedSize = 16; - - QByteArray re(hostnameEncodedSize+1, 0); - base32_encode(re.data(), re.size(), digest.constData(), hostnameDigestSize); - - // Chop extra null byte - re.chop(1); - - return QString::fromLatin1(re); -} - -QByteArray CryptoKey::signData(const QByteArray &data) const -{ - QByteArray digest(32, 0); - bool ok = SHA256(reinterpret_cast(data.constData()), data.size(), - reinterpret_cast(digest.data())) != NULL; - if (!ok) { - qWarning() << "Digest for RSA signature failed"; - return QByteArray(); - } - - return signSHA256(digest); -} - -QByteArray CryptoKey::signSHA256(const QByteArray &digest) const -{ - if (!isPrivate()) - return QByteArray(); - - QByteArray re(RSA_size(d->key), 0); - unsigned sigsize = 0; - int r = RSA_sign(NID_sha256, reinterpret_cast(digest.constData()), digest.size(), - reinterpret_cast(re.data()), &sigsize, d->key); - - if (r != 1) { - qWarning() << "RSA encryption failed when generating signature"; - return QByteArray(); - } - - re.truncate(sigsize); - return re; -} - -bool CryptoKey::verifyData(const QByteArray &data, QByteArray signature) const -{ - QByteArray digest(32, 0); - bool ok = SHA256(reinterpret_cast(data.constData()), data.size(), - reinterpret_cast(digest.data())) != NULL; - - if (!ok) { - qWarning() << "Digest for RSA verify failed"; - return false; - } - - return verifySHA256(digest, signature); -} - -bool CryptoKey::verifySHA256(const QByteArray &digest, QByteArray signature) const -{ - if (!isLoaded()) - return false; - - int r = RSA_verify(NID_sha256, reinterpret_cast(digest.constData()), digest.size(), - reinterpret_cast(signature.data()), signature.size(), d->key); - if (r != 1) - return false; - return true; -} - -/* Copyright (c) 2001-2004, Roger Dingledine - * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson - * Copyright (c) 2007-2010, The Tor Project, Inc. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following disclaimer - * in the documentation and/or other materials provided with the - * distribution. - * - * Neither the names of the copyright owners nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#define BASE32_CHARS "abcdefghijklmnopqrstuvwxyz234567" - -/* Implements base32 encoding as in rfc3548. Requires that srclen*8 is a multiple of 5. */ -void base32_encode(char *dest, unsigned destlen, const char *src, unsigned srclen) -{ - unsigned i, bit, v, u; - unsigned nbits = srclen * 8; - - /* We need an even multiple of 5 bits, and enough space */ - if ((nbits%5) != 0 || destlen > (nbits/5)+1) { - Q_ASSERT(false); - memset(dest, 0, destlen); - return; - } - - for (i = 0, bit = 0; bit < nbits; ++i, bit += 5) - { - /* set v to the 16-bit value starting at src[bits/8], 0-padded. */ - v = ((quint8) src[bit / 8]) << 8; - if (bit + 5 < nbits) - v += (quint8) src[(bit/8)+1]; - - /* set u to the 5-bit value at the bit'th bit of src. */ - u = (v >> (11 - (bit % 8))) & 0x1F; - dest[i] = BASE32_CHARS[u]; - } - - dest[i] = '\0'; -} - -/* Implements base32 decoding as in rfc3548. Requires that srclen*5 is a multiple of 8. */ -bool base32_decode(char *dest, unsigned destlen, const char *src, unsigned srclen) -{ - unsigned int i, j, bit; - unsigned nbits = srclen * 5; - - /* We need an even multiple of 8 bits, and enough space */ - if ((nbits%8) != 0 || (nbits/8)+1 > destlen) { - Q_ASSERT(false); - return false; - } - - char *tmp = new char[srclen]; - - /* Convert base32 encoded chars to the 5-bit values that they represent. */ - for (j = 0; j < srclen; ++j) - { - if (src[j] > 0x60 && src[j] < 0x7B) - tmp[j] = src[j] - 0x61; - else if (src[j] > 0x31 && src[j] < 0x38) - tmp[j] = src[j] - 0x18; - else if (src[j] > 0x40 && src[j] < 0x5B) - tmp[j] = src[j] - 0x41; - else - { - delete[] tmp; - return false; - } - } - - /* Assemble result byte-wise by applying five possible cases. */ - for (i = 0, bit = 0; bit < nbits; ++i, bit += 8) - { - switch (bit % 40) - { - case 0: - dest[i] = (((quint8)tmp[(bit/5)]) << 3) + (((quint8)tmp[(bit/5)+1]) >> 2); - break; - case 8: - dest[i] = (((quint8)tmp[(bit/5)]) << 6) + (((quint8)tmp[(bit/5)+1]) << 1) - + (((quint8)tmp[(bit/5)+2]) >> 4); - break; - case 16: - dest[i] = (((quint8)tmp[(bit/5)]) << 4) + (((quint8)tmp[(bit/5)+1]) >> 1); - break; - case 24: - dest[i] = (((quint8)tmp[(bit/5)]) << 7) + (((quint8)tmp[(bit/5)+1]) << 2) - + (((quint8)tmp[(bit/5)+2]) >> 3); - break; - case 32: - dest[i] = (((quint8)tmp[(bit/5)]) << 5) + ((quint8)tmp[(bit/5)+1]); - break; - } - } - - delete[] tmp; - return true; -} - -#endif diff --git a/libretroshare/src/tor/CryptoKey.h b/libretroshare/src/tor/CryptoKey.h index c99703444..7cb1d6562 100644 --- a/libretroshare/src/tor/CryptoKey.h +++ b/libretroshare/src/tor/CryptoKey.h @@ -37,6 +37,8 @@ #include #include +#include "bytearray.h" + class CryptoKey { public: @@ -53,54 +55,17 @@ public: CryptoKey(); ~CryptoKey(); -#ifdef TO_REMOVE - bool loadFromData(const QByteArray &data, KeyType type, KeyFormat format = PEM); - bool loadFromFile(const QString &path, KeyType type, KeyFormat format = PEM); -#endif - bool loadFromFile(const QString &path); + bool loadFromFile(const std::string &path); void clear(); - const QByteArray bytes() const { return key_data; } - bool loadFromTorMessage(const QByteArray& b); + const ByteArray bytes() const { return key_data; } + bool loadFromTorMessage(const ByteArray& b); bool isLoaded() const { return !key_data.isNull(); } -#ifdef TO_REMOVE - bool isPrivate() const; - - QByteArray publicKeyDigest() const; - QByteArray encodedPublicKey(KeyFormat format) const; - QByteArray encodedPrivateKey(KeyFormat format) const; - QString torServiceID() const; - int bits() const; - - // Calculate and sign SHA-256 digest of data using this key and PKCS #1 v2.0 padding - QByteArray signData(const QByteArray &data) const; - // Verify a signature as per signData - bool verifyData(const QByteArray &data, QByteArray signature) const; - - // Sign the input SHA-256 digest using this key and PKCS #1 v2.0 padding - QByteArray signSHA256(const QByteArray &digest) const; - // Verify a signature as per signSHA256 - bool verifySHA256(const QByteArray &digest, QByteArray signature) const; -#endif private: -#ifdef TO_REMOVE - struct Data : public QSharedData - { - typedef struct rsa_st RSA; - RSA *key; - - Data(RSA *k = 0) : key(k) { } - ~Data(); - }; -#endif - - QByteArray key_data; -#ifdef TO_REMOVE - QExplicitlySharedDataPointer d; -#endif + ByteArray key_data; }; -QByteArray torControlHashedPassword(const QByteArray &password); +ByteArray torControlHashedPassword(const ByteArray &password); #endif // CRYPTOKEY_H diff --git a/libretroshare/src/tor/GetConfCommand.cpp b/libretroshare/src/tor/GetConfCommand.cpp index 933def562..3ed5e9263 100644 --- a/libretroshare/src/tor/GetConfCommand.cpp +++ b/libretroshare/src/tor/GetConfCommand.cpp @@ -41,14 +41,14 @@ GetConfCommand::GetConfCommand(Type t) { } -QByteArray GetConfCommand::build(const QByteArray &key) +ByteArray GetConfCommand::build(const ByteArray &key) { - return build(QList() << key); + return build(QList() << key); } -QByteArray GetConfCommand::build(const QList &keys) +ByteArray GetConfCommand::build(const QList &keys) { - QByteArray out; + ByteArray out; if (type == GetConf) { out = "GETCONF"; } else if (type == GetInfo) { @@ -58,7 +58,7 @@ QByteArray GetConfCommand::build(const QList &keys) return out; } - foreach (const QByteArray &key, keys) { + foreach (const ByteArray &key, keys) { out.append(' '); out.append(key); } @@ -67,49 +67,29 @@ QByteArray GetConfCommand::build(const QList &keys) return out; } -void GetConfCommand::onReply(int statusCode, const QByteArray &data) +void GetConfCommand::onReply(int statusCode, const ByteArray &data) { TorControlCommand::onReply(statusCode, data); if (statusCode != 250) return; int kep = data.indexOf('='); - QString key = QString::fromLatin1(data.mid(0, kep)); - QVariant value; + std::string key = data.mid(0, kep).toString(); + std::string value; if (kep >= 0) - value = QString::fromLatin1(unquotedString(data.mid(kep + 1))); + value = unquotedString(data.mid(kep + 1)).toString(); m_lastKey = key; - QVariantMap::iterator it = m_results.find(key); - if (it != m_results.end()) { - // Make a list of values - QVariantList results = it->toList(); - if (results.isEmpty()) - results.append(*it); - results.append(value); - *it = QVariant(results); - } else { - m_results.insert(key, value); - } + m_results[key].push_back(value); } -void GetConfCommand::onDataLine(const QByteArray &data) +void GetConfCommand::onDataLine(const ByteArray &data) { - if (m_lastKey.isEmpty()) { + if (m_lastKey.empty()) { qWarning() << "torctrl: Unexpected data line in GetConf command"; return; } - - QVariantMap::iterator it = m_results.find(m_lastKey); - if (it != m_results.end()) { - QVariantList results = it->toList(); - if (results.isEmpty() && !it->toByteArray().isEmpty()) - results.append(*it); - results.append(data); - *it = QVariant(results); - } else { - m_results.insert(m_lastKey, QVariantList() << data); - } + m_results[m_lastKey].push_back(data.toString()); } void GetConfCommand::onDataFinished() @@ -117,8 +97,13 @@ void GetConfCommand::onDataFinished() m_lastKey.clear(); } -QVariant GetConfCommand::get(const QByteArray &key) const +std::list GetConfCommand::get(const ByteArray& key) const { - return m_results.value(QString::fromLatin1(key)); + auto it = m_results.find(key.toString()); + + if(it != m_results.end()) + return it->second; + else + return std::list(); } diff --git a/libretroshare/src/tor/GetConfCommand.h b/libretroshare/src/tor/GetConfCommand.h index 0de97d1b7..aa79bcff7 100644 --- a/libretroshare/src/tor/GetConfCommand.h +++ b/libretroshare/src/tor/GetConfCommand.h @@ -56,20 +56,20 @@ public: GetConfCommand(Type type); - QByteArray build(const QByteArray &key); - QByteArray build(const QList &keys); + ByteArray build(const ByteArray &key); + ByteArray build(const QList &keys); - const QVariantMap &results() const { return m_results; } - QVariant get(const QByteArray &key) const; + const std::map > &results() const { return m_results; } + std::list get(const ByteArray &key) const; protected: - virtual void onReply(int statusCode, const QByteArray &data); - virtual void onDataLine(const QByteArray &data); + virtual void onReply(int statusCode, const ByteArray &data); + virtual void onDataLine(const ByteArray &data); virtual void onDataFinished(); private: - QVariantMap m_results; - QString m_lastKey; + std::map > m_results; + std::string m_lastKey; }; } diff --git a/libretroshare/src/tor/HiddenService.cpp b/libretroshare/src/tor/HiddenService.cpp index 22b7200fe..d65320067 100644 --- a/libretroshare/src/tor/HiddenService.cpp +++ b/libretroshare/src/tor/HiddenService.cpp @@ -32,11 +32,9 @@ #include "HiddenService.h" #include "TorControl.h" -#include "TorSocket.h" #include "CryptoKey.h" #include "Useful.h" #include -#include #include #include @@ -47,7 +45,7 @@ HiddenService::HiddenService(HiddenServiceClient *client) { } -HiddenService::HiddenService(HiddenServiceClient *client,const QString &path) +HiddenService::HiddenService(HiddenServiceClient *client,const std::string& path) : m_dataPath(path), m_status(NotCreated), m_client(client) { /* Set the initial status and, if possible, load the hostname */ @@ -58,7 +56,7 @@ HiddenService::HiddenService(HiddenServiceClient *client,const QString &path) } } -HiddenService::HiddenService(HiddenServiceClient *client,const CryptoKey &privateKey, const QString &path) +HiddenService::HiddenService(HiddenServiceClient *client,const CryptoKey &privateKey, const std::string &path) : m_dataPath(path), m_status(NotCreated), m_client(client) { setPrivateKey(privateKey); @@ -92,7 +90,7 @@ void HiddenService::addTarget(quint16 servicePort, QHostAddress targetAddress, q m_targets.append(t); } -void HiddenService::setServiceId(const QByteArray& sid) +void HiddenService::setServiceId(const ByteArray& sid) { m_service_id = sid; m_hostname = sid + ".onion"; diff --git a/libretroshare/src/tor/HiddenService.h b/libretroshare/src/tor/HiddenService.h index 4efa55582..6c2fff4b8 100644 --- a/libretroshare/src/tor/HiddenService.h +++ b/libretroshare/src/tor/HiddenService.h @@ -38,11 +38,11 @@ #include #include "CryptoKey.h" +#include "bytearray.h" + namespace Tor { -class TorSocket; - // This class is used to receive synchroneous notifications from the hidden service. // Each client should implement its own notification handling. @@ -77,20 +77,20 @@ public: }; HiddenService(HiddenServiceClient *client); - HiddenService(HiddenServiceClient *client,const QString &dataPath); - HiddenService(HiddenServiceClient *client,const CryptoKey &privateKey, const QString &dataPath = QString()); + HiddenService(HiddenServiceClient *client, const std::string &dataPath); + HiddenService(HiddenServiceClient *client, const CryptoKey &privateKey, const std::string &dataPath = QString()); Status status() const { return m_status; } - const QString& hostname() const { return m_hostname; } - const QString serviceId() const { return QString(m_service_id); } - const QString& dataPath() const { return m_dataPath; } + const std::string& hostname() const { return m_hostname; } + const std::string serviceId() const { return m_service_id.toString(); } + const std::string& dataPath() const { return m_dataPath; } CryptoKey privateKey() { return m_privateKey; } void setPrivateKey(const CryptoKey &privateKey); - void setServiceId(const QByteArray& sid); + void setServiceId(const ByteArray &sid); - const QList &targets() const { return m_targets; } + const std::list &targets() const { return m_targets; } void addTarget(const Target &target); void addTarget(quint16 servicePort, QHostAddress targetAddress, quint16 targetPort); @@ -98,12 +98,12 @@ private slots: void servicePublished(); private: - QString m_dataPath; - QList m_targets; - QString m_hostname; + std::string m_dataPath; + std::list m_targets; + std::string m_hostname; Status m_status; CryptoKey m_privateKey; - QByteArray m_service_id; + ByteArray m_service_id; void loadPrivateKey(); void setStatus(Status newStatus); diff --git a/libretroshare/src/tor/ProtocolInfoCommand.cpp b/libretroshare/src/tor/ProtocolInfoCommand.cpp index a365a5c4d..7d2cb519f 100644 --- a/libretroshare/src/tor/ProtocolInfoCommand.cpp +++ b/libretroshare/src/tor/ProtocolInfoCommand.cpp @@ -42,12 +42,12 @@ ProtocolInfoCommand::ProtocolInfoCommand(TorControl *m) { } -QByteArray ProtocolInfoCommand::build() +ByteArray ProtocolInfoCommand::build() { - return QByteArray("PROTOCOLINFO 1\r\n"); + return ByteArray("PROTOCOLINFO 1\r\n"); } -void ProtocolInfoCommand::onReply(int statusCode, const QByteArray &data) +void ProtocolInfoCommand::onReply(int statusCode, const ByteArray &data) { TorControlCommand::onReply(statusCode, data); if (statusCode != 250) @@ -55,14 +55,14 @@ void ProtocolInfoCommand::onReply(int statusCode, const QByteArray &data) if (data.startsWith("AUTH ")) { - QList tokens = splitQuotedStrings(data.mid(5), ' '); + QList tokens = splitQuotedStrings(data.mid(5), ' '); - foreach (QByteArray token, tokens) + foreach (ByteArray token, tokens) { if (token.startsWith("METHODS=")) { - QList textMethods = unquotedString(token.mid(8)).split(','); - for (QList::Iterator it = textMethods.begin(); it != textMethods.end(); ++it) + QList textMethods = unquotedString(token.mid(8)).split(','); + for (QList::Iterator it = textMethods.begin(); it != textMethods.end(); ++it) { if (*it == "NULL") m_authMethods |= AuthNull; @@ -80,6 +80,6 @@ void ProtocolInfoCommand::onReply(int statusCode, const QByteArray &data) } else if (data.startsWith("VERSION Tor=")) { - m_torVersion = QString::fromLatin1(unquotedString(data.mid(12, data.indexOf(' ', 12)))); + m_torVersion = std::string(unquotedString(data.mid(12, data.indexOf(' ', 12)))); } } diff --git a/libretroshare/src/tor/ProtocolInfoCommand.h b/libretroshare/src/tor/ProtocolInfoCommand.h index 7789cfefd..c3d88182f 100644 --- a/libretroshare/src/tor/ProtocolInfoCommand.h +++ b/libretroshare/src/tor/ProtocolInfoCommand.h @@ -57,14 +57,14 @@ public: Q_DECLARE_FLAGS(AuthMethods, AuthMethod) ProtocolInfoCommand(TorControl *manager); - QByteArray build(); + ByteArray build(); AuthMethods authMethods() const { return m_authMethods; } QString torVersion() const { return m_torVersion; } QString cookieFile() const { return m_cookieFile; } protected: - virtual void onReply(int statusCode, const QByteArray &data); + virtual void onReply(int statusCode, const ByteArray &data); private: TorControl *manager; diff --git a/libretroshare/src/tor/SetConfCommand.cpp b/libretroshare/src/tor/SetConfCommand.cpp index f13a9fdef..2134b9150 100644 --- a/libretroshare/src/tor/SetConfCommand.cpp +++ b/libretroshare/src/tor/SetConfCommand.cpp @@ -50,49 +50,55 @@ bool SetConfCommand::isSuccessful() const return statusCode() == 250; } -QByteArray SetConfCommand::build(const QByteArray &key, const QByteArray &value) +ByteArray SetConfCommand::build(const ByteArray &key, const ByteArray &value) { - return build(QList >() << qMakePair(key, value)); + return build(std::list > { std::make_pair(key, value) } ); } -QByteArray SetConfCommand::build(const QVariantMap &data) +// ByteArray SetConfCommand::build(const std::list > &data) +// { +// QList > out; +// +// for (QVariantMap::ConstIterator it = data.begin(); it != data.end(); it++) { +// QByteArray key = it.key().toLatin1(); +// +// if (static_cast(it.value().type()) == QMetaType::QVariantList) { +// QVariantList values = it.value().value(); +// foreach (const QVariant &value, values) +// out.append(qMakePair(key, value.toString().toLatin1())); +// } else { +// out.append(qMakePair(key, it.value().toString().toLatin1())); +// } +// } +// +// return build(out); +// } + +ByteArray SetConfCommand::build(const std::list >& data) { - QList > out; + ByteArray out(m_resetMode ? "RESETCONF" : "SETCONF"); - for (QVariantMap::ConstIterator it = data.begin(); it != data.end(); it++) { - QByteArray key = it.key().toLatin1(); + for (auto& p:data) + { + out += " " ; + out += p.first; - if (static_cast(it.value().type()) == QMetaType::QVariantList) { - QVariantList values = it.value().value(); - foreach (const QVariant &value, values) - out.append(qMakePair(key, value.toString().toLatin1())); - } else { - out.append(qMakePair(key, it.value().toString().toLatin1())); + if (!p.second.empty()) + { + out += "=" ; + out += quotedString(p.second); } } - return build(out); -} - -QByteArray SetConfCommand::build(const QList > &data) -{ - QByteArray out(m_resetMode ? "RESETCONF" : "SETCONF"); - - for (int i = 0; i < data.size(); i++) { - out += " " + data[i].first; - if (!data[i].second.isEmpty()) - out += "=" + quotedString(data[i].second); - } - out.append("\r\n"); return out; } -void SetConfCommand::onReply(int statusCode, const QByteArray &data) +void SetConfCommand::onReply(int statusCode, const ByteArray &data) { TorControlCommand::onReply(statusCode, data); if (statusCode != 250) - m_errorMessage = QString::fromLatin1(data); + m_errorMessage = data.toString(); } void SetConfCommand::onFinished(int statusCode) diff --git a/libretroshare/src/tor/SetConfCommand.h b/libretroshare/src/tor/SetConfCommand.h index 5bdcb9329..f46d7ba9e 100644 --- a/libretroshare/src/tor/SetConfCommand.h +++ b/libretroshare/src/tor/SetConfCommand.h @@ -54,11 +54,10 @@ public: void setResetMode(bool resetMode); - QByteArray build(const QByteArray &key, const QByteArray &value); - QByteArray build(const QVariantMap &data); - QByteArray build(const QList > &data); + ByteArray build(const ByteArray &key, const ByteArray &value); + ByteArray build(const std::list > &data); - QString errorMessage() const { return m_errorMessage; } + std::string errorMessage() const { return m_errorMessage; } bool isSuccessful() const; signals: @@ -66,10 +65,10 @@ signals: void setConfFailed(int code); protected: - QString m_errorMessage; + std::string m_errorMessage; bool m_resetMode; - virtual void onReply(int statusCode, const QByteArray &data); + virtual void onReply(int statusCode, const ByteArray &data); virtual void onFinished(int statusCode); }; diff --git a/libretroshare/src/tor/Settings.cpp b/libretroshare/src/tor/Settings.cpp index b20d330b7..16b805a36 100644 --- a/libretroshare/src/tor/Settings.cpp +++ b/libretroshare/src/tor/Settings.cpp @@ -48,8 +48,8 @@ class SettingsFilePrivate : public QObject public: SettingsFile *q; - QString filePath; - QString errorMessage; + std::string filePath; + std::string errorMessage; QTimer syncTimer; QJsonObject jsonRoot; SettingsObject *rootObject; @@ -58,17 +58,17 @@ public: virtual ~SettingsFilePrivate(); void reset(); - void setError(const QString &message); - bool checkDirPermissions(const QString &path); + void setError(const std::string &message); + bool checkDirPermissions(const std::string &path); bool readFile(); bool writeFile(); - static QStringList splitPath(const QString &input, bool &ok); - QJsonValue read(const QJsonObject &base, const QStringList &path); - bool write(const QStringList &path, const QJsonValue &value); + static std::list splitPath(const std::string& input, bool &ok); + QJsonValue read(const QJsonObject &base, const std::list &path); + bool write(const std::list &path, const QJsonValue &value); signals: - void modified(const QStringList &path, const QJsonValue &value); + void modified(const std::list &path, const QJsonValue &value); private slots: void sync(); diff --git a/libretroshare/src/tor/Settings.h b/libretroshare/src/tor/Settings.h index 79ad032d1..e42cd684e 100644 --- a/libretroshare/src/tor/Settings.h +++ b/libretroshare/src/tor/Settings.h @@ -37,7 +37,6 @@ #include #include #include -#include #include class SettingsObject; diff --git a/libretroshare/src/tor/StrUtil.cpp b/libretroshare/src/tor/StrUtil.cpp index 81de151b0..1bbc95353 100644 --- a/libretroshare/src/tor/StrUtil.cpp +++ b/libretroshare/src/tor/StrUtil.cpp @@ -32,14 +32,14 @@ #include "StrUtil.h" -QByteArray quotedString(const QByteArray &string) +ByteArray quotedString(const ByteArray &string) { - QByteArray out; + ByteArray out; out.reserve(string.size() * 2); out.append('"'); - for (int i = 0; i < string.size(); ++i) + for (uint i = 0; i < string.size(); ++i) { switch (string[i]) { @@ -59,15 +59,15 @@ QByteArray quotedString(const QByteArray &string) return out; } -QByteArray unquotedString(const QByteArray &string) +ByteArray unquotedString(const ByteArray &string) { if (string.size() < 2 || string[0] != '"') return string; - QByteArray out; + ByteArray out; out.reserve(string.size() - 2); - for (int i = 1; i < string.size(); ++i) + for (uint i = 1; i < string.size(); ++i) { switch (string[i]) { @@ -85,13 +85,13 @@ QByteArray unquotedString(const QByteArray &string) return out; } -QList splitQuotedStrings(const QByteArray &input, char separator) +std::list splitQuotedStrings(const ByteArray &input, char separator) { - QList out; + std::list out; bool inquote = false; - int start = 0; + uint start = 0; - for (int i = 0; i < input.size(); ++i) + for (uint i = 0; i < input.size(); ++i) { switch (input[i]) { @@ -106,13 +106,13 @@ QList splitQuotedStrings(const QByteArray &input, char separator) if (!inquote && input[i] == separator) { - out.append(input.mid(start, i - start)); + out.push_back(input.mid(start, i - start)); start = i+1; } } if (start < input.size()) - out.append(input.mid(start)); + out.push_back(input.mid(start)); return out; } diff --git a/libretroshare/src/tor/StrUtil.h b/libretroshare/src/tor/StrUtil.h index c86d2c6ec..8f986a9a8 100644 --- a/libretroshare/src/tor/StrUtil.h +++ b/libretroshare/src/tor/StrUtil.h @@ -33,14 +33,15 @@ #ifndef STRINGUTIL_H #define STRINGUTIL_H -#include -#include +#include -QByteArray quotedString(const QByteArray &string); +#include "bytearray.h" + +ByteArray quotedString(const ByteArray &string); /* Return the unquoted contents of a string, either until an end quote or an unescaped separator character. */ -QByteArray unquotedString(const QByteArray &string); +ByteArray unquotedString(const ByteArray &string); -QList splitQuotedStrings(const QByteArray &input, char separator); +std::list splitQuotedStrings(const ByteArray& input, char separator); #endif // STRINGUTIL_H diff --git a/libretroshare/src/tor/TorControl.cpp b/libretroshare/src/tor/TorControl.cpp index 2b0040252..d1c3e8b74 100644 --- a/libretroshare/src/tor/TorControl.cpp +++ b/libretroshare/src/tor/TorControl.cpp @@ -85,7 +85,7 @@ public: QHostAddress torAddress; QString errorMessage; QString torVersion; - QByteArray authPassword; + ByteArray authPassword; QHostAddress socksAddress; QList services; quint16 controlPort, socksPort; @@ -112,8 +112,8 @@ public slots: void getTorInfoReply(); void setError(const QString &message); - void statusEvent(int code, const QByteArray &data); - void updateBootstrap(const QList &data); + void statusEvent(int code, const ByteArray &data); + void updateBootstrap(const QList &data); }; } @@ -276,7 +276,7 @@ QVariantMap TorControl::bootstrapStatus() const return d->bootstrapStatus; } -void TorControl::setAuthPassword(const QByteArray &password) +void TorControl::setAuthPassword(const ByteArray &password) { d->authPassword = password; } @@ -385,7 +385,7 @@ void TorControlPrivate::protocolInfoReply() AuthenticateCommand *auth = new AuthenticateCommand; connect(auth, &TorControlCommand::finished, this, &TorControlPrivate::authenticateReply); - QByteArray data; + ByteArray data; ProtocolInfoCommand::AuthMethods methods = info->authMethods(); if (methods.testFlag(ProtocolInfoCommand::AuthNull)) @@ -402,7 +402,7 @@ void TorControlPrivate::protocolInfoReply() QFile file(cookieFile); if (file.open(QIODevice::ReadOnly)) { - QByteArray cookie = file.readAll(); + ByteArray cookie = file.readAll(); file.close(); /* Simple test to avoid a vulnerability where any process listening on what we think is @@ -458,8 +458,8 @@ void TorControlPrivate::getTorInfo() GetConfCommand *command = new GetConfCommand(GetConfCommand::GetInfo); connect(command, &TorControlCommand::finished, this, &TorControlPrivate::getTorInfoReply); - QList keys; - keys << QByteArray("status/circuit-established") << QByteArray("status/bootstrap-phase"); + QList keys; + keys << ByteArray("status/circuit-established") << ByteArray("status/bootstrap-phase"); /* If these are set in the config, they override the automatic behavior. */ SettingsObject settings(QStringLiteral("tor")); @@ -479,7 +479,7 @@ void TorControlPrivate::getTorInfo() rsEvents->sendEvent(ev); } } else - keys << QByteArray("net/listeners/socks"); + keys << ByteArray("net/listeners/socks"); socket->sendCommand(command, command->build(keys)); } @@ -490,9 +490,9 @@ void TorControlPrivate::getTorInfoReply() if (!command || !q->isConnected()) return; - QList listenAddresses = splitQuotedStrings(command->get(QByteArray("net/listeners/socks")).toString().toLatin1(), ' '); - for (QList::Iterator it = listenAddresses.begin(); it != listenAddresses.end(); ++it) { - QByteArray value = unquotedString(*it); + QList listenAddresses = splitQuotedStrings(command->get(ByteArray("net/listeners/socks")).toString().toLatin1(), ' '); + for (QList::Iterator it = listenAddresses.begin(); it != listenAddresses.end(); ++it) { + ByteArray value = unquotedString(*it); int sepp = value.indexOf(':'); QHostAddress address(QString::fromLatin1(value.mid(0, sepp))); quint16 port = (quint16)value.mid(sepp+1).toUInt(); @@ -523,14 +523,14 @@ void TorControlPrivate::getTorInfoReply() } } - if (command->get(QByteArray("status/circuit-established")).toInt() == 1) { + if (command->get(ByteArray("status/circuit-established")).toInt() == 1) { torCtrlDebug() << "torctrl: Tor indicates that circuits have been established; state is TorReady" << std::endl; setTorStatus(TorControl::TorReady); } else { setTorStatus(TorControl::TorOffline); } - QByteArray bootstrap = command->get(QByteArray("status/bootstrap-phase")).toString().toLatin1(); + ByteArray bootstrap = command->get(ByteArray("status/bootstrap-phase")).toString().toLatin1(); if (!bootstrap.isEmpty()) updateBootstrap(splitQuotedStrings(bootstrap, ' ')); } @@ -580,7 +580,7 @@ void TorControlPrivate::publishServices() } else { torCtrlDebug() << "torctrl: Using legacy SETCONF hidden service configuration for tor" << torVersion.toStdString() << std::endl; SetConfCommand *command = new SetConfCommand; - QList > torConfig; + QList > torConfig; foreach (HiddenService *service, services) { @@ -596,7 +596,7 @@ void TorControlPrivate::publishServices() torCtrlDebug() << "torctrl: Configuring hidden service at" << service->dataPath().toStdString() << std::endl; QDir dir(service->dataPath()); - torConfig.append(qMakePair(QByteArray("HiddenServiceDir"), dir.absolutePath().toLocal8Bit())); + torConfig.append(qMakePair(ByteArray("HiddenServiceDir"), dir.absolutePath().toLocal8Bit())); const QList &targets = service->targets(); for (QList::ConstIterator tit = targets.begin(); tit != targets.end(); ++tit) @@ -604,7 +604,7 @@ void TorControlPrivate::publishServices() QString target = QString::fromLatin1("%1 %2:%3").arg(tit->servicePort) .arg(tit->targetAddress.toString()) .arg(tit->targetPort); - torConfig.append(qMakePair(QByteArray("HiddenServicePort"), target.toLatin1())); + torConfig.append(qMakePair(ByteArray("HiddenServicePort"), target.toLatin1())); } QObject::connect(command, &SetConfCommand::setConfSucceeded, service, &HiddenService::servicePublished); @@ -640,11 +640,11 @@ void TorControl::shutdownSync() } } -void TorControlPrivate::statusEvent(int code, const QByteArray &data) +void TorControlPrivate::statusEvent(int code, const ByteArray &data) { Q_UNUSED(code); - QList tokens = splitQuotedStrings(data.trimmed(), ' '); + QList tokens = splitQuotedStrings(data.trimmed(), ' '); if (tokens.size() < 3) return; @@ -660,7 +660,7 @@ void TorControlPrivate::statusEvent(int code, const QByteArray &data) } } -void TorControlPrivate::updateBootstrap(const QList &data) +void TorControlPrivate::updateBootstrap(const QList &data) { bootstrapStatus.clear(); // WARN or NOTICE @@ -721,7 +721,7 @@ public: Q_ASSERT(!command); command = new GetConfCommand(GetConfCommand::GetInfo); QObject::connect(command, &TorControlCommand::finished, this, &SaveConfigOperation::configTextReply); - socket->sendCommand(command, command->build(QList() << "config-text" << "config-file")); + socket->sendCommand(command, command->build(QList() << "config-text" << "config-file")); } private slots: @@ -763,7 +763,7 @@ private slots: QVariantList configText = command->get("config-text").toList(); foreach (const QVariant &value, configText) { - QByteArray line = value.toByteArray(); + ByteArray line = value.toByteArray(); bool skip = false; for (const char **key = bannedKeys; *key; key++) { diff --git a/libretroshare/src/tor/TorControlCommand.cpp b/libretroshare/src/tor/TorControlCommand.cpp index 48d4aab8b..702392ac0 100644 --- a/libretroshare/src/tor/TorControlCommand.cpp +++ b/libretroshare/src/tor/TorControlCommand.cpp @@ -40,7 +40,7 @@ TorControlCommand::TorControlCommand() { } -void TorControlCommand::onReply(int statusCode, const QByteArray &data) +void TorControlCommand::onReply(int statusCode, const ByteArray &data) { emit replyLine(statusCode, data); } @@ -51,7 +51,7 @@ void TorControlCommand::onFinished(int statusCode) emit finished(); } -void TorControlCommand::onDataLine(const QByteArray &data) +void TorControlCommand::onDataLine(const ByteArray &data) { Q_UNUSED(data); } diff --git a/libretroshare/src/tor/TorControlCommand.h b/libretroshare/src/tor/TorControlCommand.h index 894381054..a33c12ffa 100644 --- a/libretroshare/src/tor/TorControlCommand.h +++ b/libretroshare/src/tor/TorControlCommand.h @@ -34,7 +34,8 @@ #define TORCONTROLCOMMAND_H #include -#include + +#include "bytearray.h" namespace Tor { @@ -52,13 +53,13 @@ public: int statusCode() const { return m_finalStatus; } signals: - void replyLine(int statusCode, const QByteArray &data); + void replyLine(int statusCode, const ByteArray &data); void finished(); protected: - virtual void onReply(int statusCode, const QByteArray &data); + virtual void onReply(int statusCode, const ByteArray &data); virtual void onFinished(int statusCode); - virtual void onDataLine(const QByteArray &data); + virtual void onDataLine(const ByteArray &data); virtual void onDataFinished(); private: diff --git a/libretroshare/src/tor/TorControlSocket.cpp b/libretroshare/src/tor/TorControlSocket.cpp index c6b1eb707..3517907b6 100644 --- a/libretroshare/src/tor/TorControlSocket.cpp +++ b/libretroshare/src/tor/TorControlSocket.cpp @@ -34,12 +34,11 @@ #include "TorControlSocket.h" #include "TorControlCommand.h" -#include using namespace Tor; -TorControlSocket::TorControlSocket(QObject *parent) - : QTcpSocket(parent), currentCommand(0), inDataReply(false) +TorControlSocket::TorControlSocket() + : currentCommand(0), inDataReply(false) { connect(this, SIGNAL(readyRead()), this, SLOT(process())); connect(this, SIGNAL(disconnected()), this, SLOT(clear())); @@ -54,7 +53,7 @@ void TorControlSocket::sendCommand(TorControlCommand *command, const QByteArray { Q_ASSERT(data.endsWith("\r\n")); - commandQueue.append(command); + commandQueue.push_back(command); write(data); std::cerr << "[TOR CTRL] Sent: \"" << QString(data.trimmed()).toStdString() << "\"" << std::endl; @@ -84,7 +83,7 @@ void TorControlSocket::clear() currentCommand = 0; } -void TorControlSocket::setError(const QString &message) +void TorControlSocket::setError(const std::string &message) { m_errorMessage = message; emit error(message); diff --git a/libretroshare/src/tor/TorControlSocket.h b/libretroshare/src/tor/TorControlSocket.h index 2db911503..e5c1c17e8 100644 --- a/libretroshare/src/tor/TorControlSocket.h +++ b/libretroshare/src/tor/TorControlSocket.h @@ -30,29 +30,26 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#ifndef TORCONTROLSOCKET_H -#define TORCONTROLSOCKET_H +#pragma once -#include -#include +#include "pqi/rstcpsocket.h" namespace Tor { class TorControlCommand; -class TorControlSocket : public QTcpSocket +class TorControlSocket : public RsTcpSocket { -Q_OBJECT public: - explicit TorControlSocket(QObject *parent = 0); + explicit TorControlSocket(); virtual ~TorControlSocket(); - QString errorMessage() const { return m_errorMessage; } + std::string errorMessage() const { return m_errorMessage; } void registerEvent(const QByteArray &event, TorControlCommand *handler); - void sendCommand(const QByteArray &data) { sendCommand(0, data); } + void sendCommand(const std::string& data) { sendCommand(0, data); } void sendCommand(TorControlCommand *command, const QByteArray &data); signals: @@ -63,13 +60,13 @@ private slots: void clear(); private: - QQueue commandQueue; + std::list commandQueue; QHash eventCommands; - QString m_errorMessage; + std::string m_errorMessage; TorControlCommand *currentCommand; bool inDataReply; - void setError(const QString &message); + void setError(const std::string& message); }; } diff --git a/libretroshare/src/tor/TorSocket.cpp b/libretroshare/src/tor/TorSocket.cpp deleted file mode 100644 index fb9c07b26..000000000 --- a/libretroshare/src/tor/TorSocket.cpp +++ /dev/null @@ -1,155 +0,0 @@ -/* Ricochet - https://ricochet.im/ - * Copyright (C) 2014, John Brooks - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * * Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following disclaimer - * in the documentation and/or other materials provided with the - * distribution. - * - * * Neither the names of the copyright owners nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include "TorSocket.h" -#include "TorControl.h" -#include - -using namespace Tor; - -TorSocket::TorSocket(QObject *parent) - : QTcpSocket(parent) - , m_port(0) - , m_reconnectEnabled(true) - , m_maxInterval(900) - , m_connectAttempts(0) -{ - connect(torControl, SIGNAL(connectivityChanged()), SLOT(connectivityChanged())); - connect(&m_connectTimer, SIGNAL(timeout()), SLOT(reconnect())); - connect(this, SIGNAL(disconnected()), SLOT(onFailed())); - connect(this, SIGNAL(error(QAbstractSocket::SocketError)), SLOT(onFailed())); - - m_connectTimer.setSingleShot(true); - connectivityChanged(); -} - -TorSocket::~TorSocket() -{ -} - -void TorSocket::setReconnectEnabled(bool enabled) -{ - if (enabled == m_reconnectEnabled) - return; - - m_reconnectEnabled = enabled; - if (m_reconnectEnabled) { - m_connectAttempts = 0; - reconnect(); - } else { - m_connectTimer.stop(); - } -} - -void TorSocket::setMaxAttemptInterval(int interval) -{ - m_maxInterval = interval; -} - -void TorSocket::resetAttempts() -{ - m_connectAttempts = 0; - if (m_connectTimer.isActive()) { - m_connectTimer.stop(); - m_connectTimer.start(reconnectInterval() * 1000); - } -} - -int TorSocket::reconnectInterval() -{ - int delay = 0; - if (m_connectAttempts <= 4) - delay = 30; - else if (m_connectAttempts <= 6) - delay = 120; - else - delay = m_maxInterval; - - return qMin(delay, m_maxInterval); -} - -void TorSocket::reconnect() -{ - if (!torControl->hasConnectivity() || !reconnectEnabled()) - return; - - m_connectTimer.stop(); - if (!m_host.isEmpty() && m_port) { - std::cerr << "Attempting reconnection of socket to" << m_host.toStdString() << ":" << m_port << std::endl; - connectToHost(m_host, m_port); - } -} - -void TorSocket::connectivityChanged() -{ - if (torControl->hasConnectivity()) { - setProxy(torControl->connectionProxy()); - if (state() == QAbstractSocket::UnconnectedState) - reconnect(); - } else { - m_connectTimer.stop(); - m_connectAttempts = 0; - } -} - -void TorSocket::connectToHost(const QString &hostName, quint16 port, OpenMode openMode, - NetworkLayerProtocol protocol) -{ - m_host = hostName; - m_port = port; - - if (!torControl->hasConnectivity()) - return; - - if (proxy() != torControl->connectionProxy()) - setProxy(torControl->connectionProxy()); - - QAbstractSocket::connectToHost(hostName, port, openMode, protocol); -} - -void TorSocket::connectToHost(const QHostAddress &address, quint16 port, OpenMode openMode) -{ - TorSocket::connectToHost(address.toString(), port, openMode); -} - -void TorSocket::onFailed() -{ - // Make sure the internal connection to the SOCKS proxy is closed - // Otherwise reconnect attempts will fail (#295) - close(); - - if (reconnectEnabled() && !m_connectTimer.isActive()) { - m_connectAttempts++; - m_connectTimer.start(reconnectInterval() * 1000); - std::cerr << "Reconnecting socket to" << m_host.toStdString() << ":" << m_port << "in" << m_connectTimer.interval() / 1000 << "seconds" << std::endl; - } -} diff --git a/libretroshare/src/tor/TorSocket.h b/libretroshare/src/tor/TorSocket.h deleted file mode 100644 index 0c68f7854..000000000 --- a/libretroshare/src/tor/TorSocket.h +++ /dev/null @@ -1,97 +0,0 @@ -/* Ricochet - https://ricochet.im/ - * Copyright (C) 2014, John Brooks - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * * Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following disclaimer - * in the documentation and/or other materials provided with the - * distribution. - * - * * Neither the names of the copyright owners nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef TORSOCKET_H -#define TORSOCKET_H - -#include -#include - -namespace Tor { - -/* Specialized QTcpSocket which makes connections over the SOCKS proxy - * from a TorControl instance, automatically attempts reconnections, and - * reacts to Tor's connectivity state. - * - * Use normal QTcpSocket/QAbstractSocket API. When a connection fails, it - * will be retried automatically after the correct interval and when - * connectivity is available. - * - * To fully disconnect, destroy the object, or call - * setReconnectEnabled(false) and disconnect the socket with - * disconnectFromHost or abort. - * - * The caller is responsible for resetting the attempt counter if a - * connection was successful and reconnection will be used again. - */ -class TorSocket : public QTcpSocket -{ - Q_OBJECT - -public: - explicit TorSocket(QObject *parent = 0); - virtual ~TorSocket(); - - bool reconnectEnabled() const { return m_reconnectEnabled; } - void setReconnectEnabled(bool enabled); - int maxAttemptInterval() { return m_maxInterval; } - void setMaxAttemptInterval(int interval); - void resetAttempts(); - - virtual void connectToHost(const QString &hostName, quint16 port, OpenMode openMode = ReadWrite, NetworkLayerProtocol protocol = AnyIPProtocol); - virtual void connectToHost(const QHostAddress &address, quint16 port, OpenMode openMode = ReadWrite); - - QString hostName() const { return m_host; } - quint16 port() const { return m_port; } - -protected: - virtual int reconnectInterval(); - -private slots: - void reconnect(); - void connectivityChanged(); - void onFailed(); - -private: - QString m_host; - quint16 m_port; - QTimer m_connectTimer; - bool m_reconnectEnabled; - int m_maxInterval; - int m_connectAttempts; - - using QAbstractSocket::connectToHost; -}; - -} - -#endif diff --git a/libretroshare/src/tor/bytearray.h b/libretroshare/src/tor/bytearray.h new file mode 100644 index 000000000..05badb23e --- /dev/null +++ b/libretroshare/src/tor/bytearray.h @@ -0,0 +1,91 @@ +#include +#include + +#include +#include + +#include "util/rsprint.h" +#include "util/rsdebug.h" + +class ByteArray: public std::vector +{ +public: + ByteArray() =default; + ByteArray(int n) : std::vector(n) {} + ByteArray(const unsigned char *d,int n) : std::vector(n) { memcpy(data(),d,n); } + virtual ~ByteArray() =default; + + ByteArray(const std::string& c) { resize(c.size()); memcpy(data(),c.c_str(),c.size()); } + const ByteArray& operator=(const std::string& c) { resize(c.size()); memcpy(data(),c.c_str(),c.size()); return *this; } + + bool isNull() const { return empty(); } + ByteArray toHex() const { return ByteArray(RsUtil::BinToHex(data(),size(),0)); } + std::string toString() const { std::string res; for(auto c:*this) res += c; return res; } + + ByteArray operator+(const ByteArray& b) const { auto res(*this); for(unsigned char c:b) res.push_back(c); return res; } + ByteArray operator+(const std::string& b) const { return operator+(ByteArray(b)); } + + void append(const ByteArray& b) { for(auto c:b) push_back(c); } + void append(const char *b) { for(uint32_t n=0;b[n]!=0;++n) push_back(b[n]); } + + ByteArray& operator+=(const ByteArray& b) { for(auto c:b) push_back(c); return *this; } + ByteArray& operator+=(const char *b) { for(uint32_t n=0;b[n]!=0;++n) push_back(b[n]); return *this;} + + ByteArray left(uint32_t l) const { auto res = *this; res.resize(std::min((uint32_t)size(),l)); return res; } + ByteArray toUpper() const { auto res = *this; for(uint32_t i=0;i='a') res[i] += 'A'-'a'; return res; } + + bool startsWith(const char *b) const + { + for(uint32_t n=0;b[n]!=0;++n) + if(n >= size() || b[n]!=(*this)[n]) + return false; + + return true; + } + + bool operator==(const char *b) const + { + uint32_t n; + for(n=0;b[n]!=0;++n) + if(n >= size() || b[n]!=(*this)[n]) + return false; + + return n==size(); + } + + ByteArray mid(uint32_t n,int s=-1) const + { + ByteArray res((s>=0)?s:(size()-n)); + memcpy(res.data(),&data()[n],res.size()); + return res; + } + + int indexOf(unsigned char c,int from=0) const + { + for(uint32_t i=from;i Date: Mon, 29 Nov 2021 22:59:46 +0100 Subject: [PATCH 17/65] continue on switching QString and QByteArray --- libretroshare/src/libretroshare.pro | 2 - libretroshare/src/tor/AddOnionCommand.cpp | 16 +- libretroshare/src/tor/AddOnionCommand.h | 10 +- libretroshare/src/tor/GetConfCommand.cpp | 10 +- libretroshare/src/tor/GetConfCommand.h | 6 +- libretroshare/src/tor/HiddenService.cpp | 30 +-- libretroshare/src/tor/HiddenService.h | 4 +- libretroshare/src/tor/PendingOperation.cpp | 14 +- libretroshare/src/tor/PendingOperation.h | 10 +- libretroshare/src/tor/ProtocolInfoCommand.cpp | 12 +- libretroshare/src/tor/ProtocolInfoCommand.h | 9 +- libretroshare/src/tor/SetConfCommand.cpp | 6 +- libretroshare/src/tor/SetConfCommand.h | 4 +- libretroshare/src/tor/Settings.cpp | 8 +- libretroshare/src/tor/Settings.h | 56 ++--- libretroshare/src/tor/StrUtil.cpp | 2 +- libretroshare/src/tor/TorControl.cpp | 197 ++++++++++-------- libretroshare/src/tor/TorControl.h | 15 +- libretroshare/src/tor/TorControlSocket.cpp | 39 ++-- libretroshare/src/tor/TorControlSocket.h | 9 +- libretroshare/src/tor/TorManager.cpp | 160 +++++++------- libretroshare/src/tor/TorManager.h | 15 +- libretroshare/src/tor/TorProcess.cpp | 150 ++++++++----- libretroshare/src/tor/TorProcess.h | 32 +-- libretroshare/src/tor/TorProcess_p.h | 16 +- libretroshare/src/tor/bytearray.h | 62 +++++- libretroshare/src/util/rsdir.cc | 19 ++ libretroshare/src/util/rsdir.h | 9 + 28 files changed, 525 insertions(+), 397 deletions(-) diff --git a/libretroshare/src/libretroshare.pro b/libretroshare/src/libretroshare.pro index e1ed55b95..be1187dcb 100644 --- a/libretroshare/src/libretroshare.pro +++ b/libretroshare/src/libretroshare.pro @@ -744,7 +744,6 @@ HEADERS += tor/AddOnionCommand.h \ tor/TorManager.h \ tor/TorProcess.h \ tor/TorProcess_p.h \ - tor/TorSocket.h \ tor/Useful.h SOURCES += tor/AddOnionCommand.cpp \ @@ -758,7 +757,6 @@ SOURCES += tor/AddOnionCommand.cpp \ tor/TorControlSocket.cpp \ tor/TorManager.cpp \ tor/TorProcess.cpp \ - tor/TorSocket.cpp \ tor/CryptoKey.cpp \ tor/PendingOperation.cpp \ tor/SecureRNG.cpp \ diff --git a/libretroshare/src/tor/AddOnionCommand.cpp b/libretroshare/src/tor/AddOnionCommand.cpp index fb2047dc7..9e8238c14 100644 --- a/libretroshare/src/tor/AddOnionCommand.cpp +++ b/libretroshare/src/tor/AddOnionCommand.cpp @@ -45,12 +45,12 @@ AddOnionCommand::AddOnionCommand(HiddenService *service) bool AddOnionCommand::isSuccessful() const { - return statusCode() == 250 && m_errorMessage.isEmpty(); + return statusCode() == 250 && m_errorMessage.empty(); } -QByteArray AddOnionCommand::build() +ByteArray AddOnionCommand::build() { - QByteArray out("ADD_ONION"); + ByteArray out("ADD_ONION"); if (m_service->privateKey().isLoaded()) { out += " "; @@ -74,11 +74,11 @@ QByteArray AddOnionCommand::build() return out; } -void AddOnionCommand::onReply(int statusCode, const QByteArray &data) +void AddOnionCommand::onReply(int statusCode, const ByteArray &data) { TorControlCommand::onReply(statusCode, data); if (statusCode != 250) { - m_errorMessage = QString::fromLatin1(data); + m_errorMessage = data.toString(); return; } @@ -86,17 +86,17 @@ void AddOnionCommand::onReply(int statusCode, const QByteArray &data) const QByteArray sidPrefix("ServiceID="); if(data.startsWith("ServiceID=")){ - QByteArray service_id = data.mid(sidPrefix.size()); + ByteArray service_id = data.mid(sidPrefix.size()); m_service->setServiceId(service_id); } if (data.startsWith(keyPrefix)) { - QByteArray keyData(data.mid(keyPrefix.size())); + ByteArray keyData(data.mid(keyPrefix.size())); CryptoKey key; if (!key.loadFromTorMessage(keyData)) { - m_errorMessage = QStringLiteral("Key structure check failed"); + m_errorMessage = "Key structure check failed"; return; } diff --git a/libretroshare/src/tor/AddOnionCommand.h b/libretroshare/src/tor/AddOnionCommand.h index 7c0afaf5e..2edbc44a6 100644 --- a/libretroshare/src/tor/AddOnionCommand.h +++ b/libretroshare/src/tor/AddOnionCommand.h @@ -48,15 +48,15 @@ class AddOnionCommand : public TorControlCommand Q_OBJECT Q_DISABLE_COPY(AddOnionCommand) - Q_PROPERTY(QString errorMessage READ errorMessage CONSTANT) + Q_PROPERTY(std::string errorMessage READ errorMessage CONSTANT) Q_PROPERTY(bool successful READ isSuccessful CONSTANT) public: AddOnionCommand(HiddenService *service); - QByteArray build(); + ByteArray build(); - QString errorMessage() const { return m_errorMessage; } + std::string errorMessage() const { return m_errorMessage; } bool isSuccessful() const; signals: @@ -65,9 +65,9 @@ signals: protected: HiddenService *m_service; - QString m_errorMessage; + std::string m_errorMessage; - virtual void onReply(int statusCode, const QByteArray &data); + virtual void onReply(int statusCode, const ByteArray &data); virtual void onFinished(int statusCode); }; diff --git a/libretroshare/src/tor/GetConfCommand.cpp b/libretroshare/src/tor/GetConfCommand.cpp index 3ed5e9263..f85f640c1 100644 --- a/libretroshare/src/tor/GetConfCommand.cpp +++ b/libretroshare/src/tor/GetConfCommand.cpp @@ -41,12 +41,12 @@ GetConfCommand::GetConfCommand(Type t) { } -ByteArray GetConfCommand::build(const ByteArray &key) +ByteArray GetConfCommand::build(const std::string &key) { - return build(QList() << key); + return build(std::list { key } ); } -ByteArray GetConfCommand::build(const QList &keys) +ByteArray GetConfCommand::build(const std::list &keys) { ByteArray out; if (type == GetConf) { @@ -97,9 +97,9 @@ void GetConfCommand::onDataFinished() m_lastKey.clear(); } -std::list GetConfCommand::get(const ByteArray& key) const +std::list GetConfCommand::get(const std::string& key) const { - auto it = m_results.find(key.toString()); + auto it = m_results.find(key); if(it != m_results.end()) return it->second; diff --git a/libretroshare/src/tor/GetConfCommand.h b/libretroshare/src/tor/GetConfCommand.h index aa79bcff7..387a722c6 100644 --- a/libretroshare/src/tor/GetConfCommand.h +++ b/libretroshare/src/tor/GetConfCommand.h @@ -56,11 +56,11 @@ public: GetConfCommand(Type type); - ByteArray build(const ByteArray &key); - ByteArray build(const QList &keys); + ByteArray build(const std::string &key); + ByteArray build(const std::list &keys); const std::map > &results() const { return m_results; } - std::list get(const ByteArray &key) const; + std::list get(const std::string &key) const; protected: virtual void onReply(int statusCode, const ByteArray &data); diff --git a/libretroshare/src/tor/HiddenService.cpp b/libretroshare/src/tor/HiddenService.cpp index d65320067..488f7db89 100644 --- a/libretroshare/src/tor/HiddenService.cpp +++ b/libretroshare/src/tor/HiddenService.cpp @@ -34,9 +34,7 @@ #include "TorControl.h" #include "CryptoKey.h" #include "Useful.h" -#include -#include -#include +#include "util/rsdir.h" using namespace Tor; @@ -49,9 +47,10 @@ HiddenService::HiddenService(HiddenServiceClient *client,const std::string& path : m_dataPath(path), m_status(NotCreated), m_client(client) { /* Set the initial status and, if possible, load the hostname */ - if (QDir(m_dataPath).exists(QLatin1String("private_key"))) { + if(RsDirUtil::fileExists(m_dataPath + "/private_key")) + { loadPrivateKey(); - if (!m_hostname.isEmpty()) + if (!m_hostname.empty()) m_status = Offline; } } @@ -81,19 +80,19 @@ void HiddenService::setStatus(Status newStatus) void HiddenService::addTarget(const Target &target) { - m_targets.append(target); + m_targets.push_back(target); } void HiddenService::addTarget(quint16 servicePort, QHostAddress targetAddress, quint16 targetPort) { Target t = { targetAddress, servicePort, targetPort }; - m_targets.append(t); + m_targets.push_back(t); } void HiddenService::setServiceId(const ByteArray& sid) { m_service_id = sid; - m_hostname = sid + ".onion"; + m_hostname = sid.toString() + ".onion"; if(m_client) m_client->hiddenServiceHostnameChanged(); // emit hostnameChanged(); @@ -105,13 +104,6 @@ void HiddenService::setPrivateKey(const CryptoKey &key) return; } -#ifdef TO_REMOVE - if (!key.isPrivate()) { - BUG() << "Cannot create a hidden service with a public key"; - return; - } -#endif - m_privateKey = key; if(m_client) @@ -120,13 +112,13 @@ void HiddenService::setPrivateKey(const CryptoKey &key) void HiddenService::loadPrivateKey() { - if (m_privateKey.isLoaded() || m_dataPath.isEmpty()) + if (m_privateKey.isLoaded() || m_dataPath.empty()) return; - bool ok = m_privateKey.loadFromFile(m_dataPath + QLatin1String("/private_key")); + bool ok = m_privateKey.loadFromFile(m_dataPath + "/private_key"); if (!ok) { - qWarning() << "Failed to load hidden service key"; + RsWarn() << "Failed to load hidden service key"; return; } @@ -138,7 +130,7 @@ void HiddenService::servicePublished() { loadPrivateKey(); - if (m_hostname.isEmpty()) { + if (m_hostname.empty()) { std::cerr << "Failed to read hidden service hostname" << std::endl; return; } diff --git a/libretroshare/src/tor/HiddenService.h b/libretroshare/src/tor/HiddenService.h index 6c2fff4b8..b5c2b3281 100644 --- a/libretroshare/src/tor/HiddenService.h +++ b/libretroshare/src/tor/HiddenService.h @@ -35,9 +35,7 @@ #include #include -#include #include "CryptoKey.h" - #include "bytearray.h" namespace Tor @@ -78,7 +76,7 @@ public: HiddenService(HiddenServiceClient *client); HiddenService(HiddenServiceClient *client, const std::string &dataPath); - HiddenService(HiddenServiceClient *client, const CryptoKey &privateKey, const std::string &dataPath = QString()); + HiddenService(HiddenServiceClient *client, const CryptoKey &privateKey, const std::string &dataPath = std::string()); Status status() const { return m_status; } diff --git a/libretroshare/src/tor/PendingOperation.cpp b/libretroshare/src/tor/PendingOperation.cpp index 4a11f3e75..adc4792a5 100644 --- a/libretroshare/src/tor/PendingOperation.cpp +++ b/libretroshare/src/tor/PendingOperation.cpp @@ -44,23 +44,23 @@ bool PendingOperation::isFinished() const bool PendingOperation::isSuccess() const { - return m_finished && m_errorMessage.isNull(); + return m_finished && m_errorMessage.empty(); } bool PendingOperation::isError() const { - return m_finished && !m_errorMessage.isNull(); + return m_finished && !m_errorMessage.empty(); } -QString PendingOperation::errorMessage() const +std::string PendingOperation::errorMessage() const { return m_errorMessage; } -void PendingOperation::finishWithError(const QString &message) +void PendingOperation::finishWithError(const std::string &message) { - if (message.isEmpty()) - m_errorMessage = QStringLiteral("Unknown Error"); + if (message.empty()) + m_errorMessage = "Unknown Error"; m_errorMessage = message; if (!m_finished) { @@ -72,7 +72,7 @@ void PendingOperation::finishWithError(const QString &message) void PendingOperation::finishWithSuccess() { - Q_ASSERT(m_errorMessage.isNull()); + Q_ASSERT(m_errorMessage.empty()); if (!m_finished) { m_finished = true; diff --git a/libretroshare/src/tor/PendingOperation.h b/libretroshare/src/tor/PendingOperation.h index 8f776a8d7..e3a1716df 100644 --- a/libretroshare/src/tor/PendingOperation.h +++ b/libretroshare/src/tor/PendingOperation.h @@ -55,7 +55,7 @@ class PendingOperation : public QObject Q_PROPERTY(bool isFinished READ isFinished NOTIFY finished FINAL) Q_PROPERTY(bool isSuccess READ isSuccess NOTIFY success FINAL) Q_PROPERTY(bool isError READ isError NOTIFY error FINAL) - Q_PROPERTY(QString errorMessage READ errorMessage NOTIFY finished FINAL) + Q_PROPERTY(std::string errorMessage READ errorMessage NOTIFY finished FINAL) public: PendingOperation(QObject *parent = 0); @@ -63,23 +63,23 @@ public: bool isFinished() const; bool isSuccess() const; bool isError() const; - QString errorMessage() const; + std::string errorMessage() const; signals: // Always emitted once when finished, regardless of status void finished(); // One of error() or success() is emitted once - void error(const QString &errorMessage); + void error(const std::string &errorMessage); void success(); protected slots: - void finishWithError(const QString &errorMessage); + void finishWithError(const std::string &errorMessage); void finishWithSuccess(); private: bool m_finished; - QString m_errorMessage; + std::string m_errorMessage; }; Q_DECLARE_METATYPE(PendingOperation*) diff --git a/libretroshare/src/tor/ProtocolInfoCommand.cpp b/libretroshare/src/tor/ProtocolInfoCommand.cpp index 7d2cb519f..b1f773d96 100644 --- a/libretroshare/src/tor/ProtocolInfoCommand.cpp +++ b/libretroshare/src/tor/ProtocolInfoCommand.cpp @@ -33,7 +33,6 @@ #include "ProtocolInfoCommand.h" #include "TorControl.h" #include "StrUtil.h" -#include using namespace Tor; @@ -55,14 +54,15 @@ void ProtocolInfoCommand::onReply(int statusCode, const ByteArray &data) if (data.startsWith("AUTH ")) { - QList tokens = splitQuotedStrings(data.mid(5), ' '); + std::list tokens = splitQuotedStrings(data.mid(5), ' '); foreach (ByteArray token, tokens) { if (token.startsWith("METHODS=")) { - QList textMethods = unquotedString(token.mid(8)).split(','); - for (QList::Iterator it = textMethods.begin(); it != textMethods.end(); ++it) + std::list textMethods = unquotedString(token.mid(8)).split(','); + + for (std::list::iterator it = textMethods.begin(); it != textMethods.end(); ++it) { if (*it == "NULL") m_authMethods |= AuthNull; @@ -74,12 +74,12 @@ void ProtocolInfoCommand::onReply(int statusCode, const ByteArray &data) } else if (token.startsWith("COOKIEFILE=")) { - m_cookieFile = QString::fromLatin1(unquotedString(token.mid(11))); + m_cookieFile = unquotedString(token.mid(11)).toString(); } } } else if (data.startsWith("VERSION Tor=")) { - m_torVersion = std::string(unquotedString(data.mid(12, data.indexOf(' ', 12)))); + m_torVersion = unquotedString(data.mid(12, data.indexOf(' ', 12))).toString(); } } diff --git a/libretroshare/src/tor/ProtocolInfoCommand.h b/libretroshare/src/tor/ProtocolInfoCommand.h index c3d88182f..45a31351f 100644 --- a/libretroshare/src/tor/ProtocolInfoCommand.h +++ b/libretroshare/src/tor/ProtocolInfoCommand.h @@ -34,7 +34,6 @@ #define PROTOCOLINFOCOMMAND_H #include "TorControlCommand.h" -#include namespace Tor { @@ -60,8 +59,8 @@ public: ByteArray build(); AuthMethods authMethods() const { return m_authMethods; } - QString torVersion() const { return m_torVersion; } - QString cookieFile() const { return m_cookieFile; } + std::string torVersion() const { return m_torVersion; } + std::string cookieFile() const { return m_cookieFile; } protected: virtual void onReply(int statusCode, const ByteArray &data); @@ -69,8 +68,8 @@ protected: private: TorControl *manager; AuthMethods m_authMethods; - QString m_torVersion; - QString m_cookieFile; + std::string m_torVersion; + std::string m_cookieFile; }; } diff --git a/libretroshare/src/tor/SetConfCommand.cpp b/libretroshare/src/tor/SetConfCommand.cpp index 2134b9150..347b1d37a 100644 --- a/libretroshare/src/tor/SetConfCommand.cpp +++ b/libretroshare/src/tor/SetConfCommand.cpp @@ -50,9 +50,9 @@ bool SetConfCommand::isSuccessful() const return statusCode() == 250; } -ByteArray SetConfCommand::build(const ByteArray &key, const ByteArray &value) +ByteArray SetConfCommand::build(const std::string &key, const std::string &value) { - return build(std::list > { std::make_pair(key, value) } ); + return build(std::list > { std::make_pair(key, value) } ); } // ByteArray SetConfCommand::build(const std::list > &data) @@ -74,7 +74,7 @@ ByteArray SetConfCommand::build(const ByteArray &key, const ByteArray &value) // return build(out); // } -ByteArray SetConfCommand::build(const std::list >& data) +ByteArray SetConfCommand::build(const std::list >& data) { ByteArray out(m_resetMode ? "RESETCONF" : "SETCONF"); diff --git a/libretroshare/src/tor/SetConfCommand.h b/libretroshare/src/tor/SetConfCommand.h index f46d7ba9e..9d608794f 100644 --- a/libretroshare/src/tor/SetConfCommand.h +++ b/libretroshare/src/tor/SetConfCommand.h @@ -54,8 +54,8 @@ public: void setResetMode(bool resetMode); - ByteArray build(const ByteArray &key, const ByteArray &value); - ByteArray build(const std::list > &data); + ByteArray build(const std::string &key, const std::string &value); + ByteArray build(const std::list > &data); std::string errorMessage() const { return m_errorMessage; } bool isSuccessful() const; diff --git a/libretroshare/src/tor/Settings.cpp b/libretroshare/src/tor/Settings.cpp index 16b805a36..68de71249 100644 --- a/libretroshare/src/tor/Settings.cpp +++ b/libretroshare/src/tor/Settings.cpp @@ -115,7 +115,7 @@ QString SettingsFile::filePath() const return d->filePath; } -bool SettingsFile::setFilePath(const QString &filePath) +bool SettingsFile::setFilePath(const std::string& filePath) { if (d->filePath == filePath) return hasError(); @@ -125,8 +125,8 @@ bool SettingsFile::setFilePath(const QString &filePath) QFileInfo fileInfo(filePath); QDir dir(fileInfo.path()); - if (!dir.exists() && !dir.mkpath(QStringLiteral("."))) { - d->setError(QStringLiteral("Cannot create directory: %1").arg(dir.path())); + if (!dir.exists() && !dir.mkpath(".")) { + d->setError("Cannot create directory: " + dir.path())); return false; } d->checkDirPermissions(fileInfo.path()); @@ -137,7 +137,7 @@ bool SettingsFile::setFilePath(const QString &filePath) return true; } -QString SettingsFile::errorMessage() const +std::string SettingsFile::errorMessage() const { return d->errorMessage; } diff --git a/libretroshare/src/tor/Settings.h b/libretroshare/src/tor/Settings.h index e42cd684e..30377d429 100644 --- a/libretroshare/src/tor/Settings.h +++ b/libretroshare/src/tor/Settings.h @@ -66,9 +66,9 @@ public: virtual ~SettingsFile(); QString filePath() const; - bool setFilePath(const QString &filePath); + bool setFilePath(const std::string &filePath); - QString errorMessage() const; + std::string errorMessage() const; bool hasError() const; SettingsObject *root(); @@ -136,38 +136,38 @@ public: static SettingsFile *defaultFile(); static void setDefaultFile(SettingsFile *file); - QString path() const; - void setPath(const QString &path); + std::string path() const; + void setPath(const std::string &path); QJsonObject data() const; void setData(const QJsonObject &data); - Q_INVOKABLE QJsonValue read(const QString &key, const QJsonValue &defaultValue = QJsonValue::Undefined) const; - template T read(const QString &key) const; - Q_INVOKABLE void write(const QString &key, const QJsonValue &value); - template void write(const QString &key, const T &value); - Q_INVOKABLE void unset(const QString &key); + Q_INVOKABLE QJsonValue read(const std::string &key, const QJsonValue &defaultValue = QJsonValue::Undefined) const; + template T read(const std::string &key) const; + Q_INVOKABLE void write(const std::string &key, const QJsonValue &value); + template void write(const std::string &key, const T &value); + Q_INVOKABLE void unset(const std::string &key); // const char* key overloads QJsonValue read(const char *key, const QJsonValue &defaultValue = QJsonValue::Undefined) const { - return read(QString::fromLatin1(key), defaultValue); + return read(std::string(key), defaultValue); } template T read(const char *key) const { - return read(QString::fromLatin1(key)); + return read(std::string(key)); } void write(const char *key, const QJsonValue &value) { - write(QString::fromLatin1(key), value); + write(std::string(key), value); } template void write(const char *key, const T &value) { - write(QString::fromLatin1(key), value); + write(std::string(key), value); } void unset(const char *key) { - unset(QString::fromLatin1(key)); + unset(std::string(key)); } Q_INVOKABLE void undefine(); @@ -176,56 +176,56 @@ signals: void pathChanged(); void dataChanged(); - void modified(const QString &path, const QJsonValue &value); + void modified(const std::string &path, const QJsonValue &value); private: SettingsObjectPrivate *d; }; -template inline void SettingsObject::write(const QString &key, const T &value) +template inline void SettingsObject::write(const std::string &key, const T &value) { write(key, QJsonValue(value)); } -template<> inline QString SettingsObject::read(const QString &key) const +template<> inline std::string SettingsObject::read(const std::string &key) const { return read(key).toString(); } -template<> inline QJsonArray SettingsObject::read(const QString &key) const +template<> inline QJsonArray SettingsObject::read(const std::string &key) const { return read(key).toArray(); } -template<> inline QJsonObject SettingsObject::read(const QString &key) const +template<> inline QJsonObject SettingsObject::read(const std::string &key) const { return read(key).toObject(); } -template<> inline double SettingsObject::read(const QString &key) const +template<> inline double SettingsObject::read(const std::string &key) const { return read(key).toDouble(); } -template<> inline int SettingsObject::read(const QString &key) const +template<> inline int SettingsObject::read(const std::string &key) const { return read(key).toInt(); } -template<> inline bool SettingsObject::read(const QString &key) const +template<> inline bool SettingsObject::read(const std::string &key) const { return read(key).toBool(); } -template<> inline QDateTime SettingsObject::read(const QString &key) const +template<> inline QDateTime SettingsObject::read(const std::string &key) const { - QString value = read(key).toString(); + std::string value = read(key).toString(); if (value.isEmpty()) return QDateTime(); return QDateTime::fromString(value, Qt::ISODate).toLocalTime(); } -template<> inline void SettingsObject::write(const QString &key, const QDateTime &value) +template<> inline void SettingsObject::write(const std::string &key, const QDateTime &value) { write(key, QJsonValue(value.toUTC().toString(Qt::ISODate))); } @@ -242,14 +242,14 @@ private: QByteArray d; }; -template<> inline Base64Encode SettingsObject::read(const QString &key) const +template<> inline Base64Encode SettingsObject::read(const std::string &key) const { return Base64Encode(QByteArray::fromBase64(read(key).toString().toLatin1())); } -template<> inline void SettingsObject::write(const QString &key, const Base64Encode &value) +template<> inline void SettingsObject::write(const std::string &key, const Base64Encode &value) { - write(key, QJsonValue(QString::fromLatin1(value.encoded()))); + write(key, QJsonValue(std::string(value.encoded()))); } #endif diff --git a/libretroshare/src/tor/StrUtil.cpp b/libretroshare/src/tor/StrUtil.cpp index 1bbc95353..b0d035845 100644 --- a/libretroshare/src/tor/StrUtil.cpp +++ b/libretroshare/src/tor/StrUtil.cpp @@ -59,7 +59,7 @@ ByteArray quotedString(const ByteArray &string) return out; } -ByteArray unquotedString(const ByteArray &string) +ByteArray unquotedString(const ByteArray& string) { if (string.size() < 2 || string[0] != '"') return string; diff --git a/libretroshare/src/tor/TorControl.cpp b/libretroshare/src/tor/TorControl.cpp index d1c3e8b74..0add152c3 100644 --- a/libretroshare/src/tor/TorControl.cpp +++ b/libretroshare/src/tor/TorControl.cpp @@ -31,6 +31,8 @@ */ #include +#include +#include "util/rsdir.h" #include "retroshare/rstor.h" #include "TorControl.h" @@ -83,15 +85,15 @@ public: TorControlSocket *socket; QHostAddress torAddress; - QString errorMessage; - QString torVersion; + std::string errorMessage; + std::string torVersion; ByteArray authPassword; QHostAddress socksAddress; QList services; quint16 controlPort, socksPort; TorControl::Status status; TorControl::TorStatus torStatus; - QVariantMap bootstrapStatus; + std::map bootstrapStatus; bool hasOwnership; TorControlPrivate(TorControl *parent); @@ -110,10 +112,10 @@ public slots: void authenticateReply(); void protocolInfoReply(); void getTorInfoReply(); - void setError(const QString &message); + void setError(const std::string &message); void statusEvent(int code, const ByteArray &data); - void updateBootstrap(const QList &data); + void updateBootstrap(const std::list &data); }; } @@ -219,12 +221,12 @@ void TorControlPrivate::setTorStatus(TorControl::TorStatus n) } } -void TorControlPrivate::setError(const QString &message) +void TorControlPrivate::setError(const std::string &message) { errorMessage = message; setStatus(TorControl::Error); - qWarning() << "torctrl: Error:" << errorMessage; + RsWarn() << "torctrl: Error:" << errorMessage; socket->abort(); @@ -241,12 +243,12 @@ TorControl::TorStatus TorControl::torStatus() const return d->torStatus; } -QString TorControl::torVersion() const +std::string TorControl::torVersion() const { return d->torVersion; } -QString TorControl::errorMessage() const +std::string TorControl::errorMessage() const { return d->errorMessage; } @@ -271,7 +273,7 @@ QList TorControl::hiddenServices() const return d->services; } -QVariantMap TorControl::bootstrapStatus() const +std::map TorControl::bootstrapStatus() const { return d->bootstrapStatus; } @@ -369,7 +371,7 @@ void TorControlPrivate::socketDisconnected() void TorControlPrivate::socketError() { - setError(QStringLiteral("Connection failed: %1").arg(socket->errorString())); + setError("Connection failed: " + socket->errorString())); } void TorControlPrivate::protocolInfoReply() @@ -393,11 +395,11 @@ void TorControlPrivate::protocolInfoReply() torCtrlDebug() << "torctrl: Using null authentication" << std::endl; data = auth->build(); } - else if (methods.testFlag(ProtocolInfoCommand::AuthCookie) && !info->cookieFile().isEmpty()) + else if (methods.testFlag(ProtocolInfoCommand::AuthCookie) && !info->cookieFile().empty()) { - QString cookieFile = info->cookieFile(); - QString cookieError; - torCtrlDebug() << "torctrl: Using cookie authentication with file" << cookieFile.toStdString() << std::endl; + std::string cookieFile = info->cookieFile(); + std::string cookieError; + torCtrlDebug() << "torctrl: Using cookie authentication with file" << cookieFile << std::endl; QFile file(cookieFile); if (file.open(QIODevice::ReadOnly)) @@ -410,28 +412,28 @@ void TorControlPrivate::protocolInfoReply() if (cookie.size() == 32) data = auth->build(cookie); else - cookieError = QStringLiteral("Unexpected file size"); + cookieError = "Unexpected file size"; } else cookieError = file.errorString(); - if (!cookieError.isNull() || data.isNull()) + if (!cookieError.empty() || data.isNull()) { /* 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, * but it has happened. */ - if (methods.testFlag(ProtocolInfoCommand::AuthHashedPassword) && !authPassword.isEmpty()) + if (methods.testFlag(ProtocolInfoCommand::AuthHashedPassword) && !authPassword.empty()) { - torCtrlDebug() << "torctrl: Unable to read authentication cookie file:" << cookieError.toStdString() << std::endl; + torCtrlDebug() << "torctrl: Unable to read authentication cookie file:" << cookieError << std::endl; goto usePasswordAuth; } - setError(QStringLiteral("Unable to read authentication cookie file: %1").arg(cookieError)); + setError("Unable to read authentication cookie file: " + cookieError); delete auth; return; } } - else if (methods.testFlag(ProtocolInfoCommand::AuthHashedPassword) && !authPassword.isEmpty()) + else if (methods.testFlag(ProtocolInfoCommand::AuthHashedPassword) && !authPassword.empty()) { usePasswordAuth: torCtrlDebug() << "torctrl: Using hashed password authentication" << std::endl; @@ -440,9 +442,9 @@ void TorControlPrivate::protocolInfoReply() else { if (methods.testFlag(ProtocolInfoCommand::AuthHashedPassword)) - setError(QStringLiteral("Tor requires a control password to connect, but no password is configured.")); + setError("Tor requires a control password to connect, but no password is configured."); else - setError(QStringLiteral("Tor is not configured to accept any supported authentication methods.")); + setError("Tor is not configured to accept any supported authentication methods."); delete auth; return; } @@ -458,11 +460,10 @@ void TorControlPrivate::getTorInfo() GetConfCommand *command = new GetConfCommand(GetConfCommand::GetInfo); connect(command, &TorControlCommand::finished, this, &TorControlPrivate::getTorInfoReply); - QList keys; - keys << ByteArray("status/circuit-established") << ByteArray("status/bootstrap-phase"); + std::list keys{ "status/circuit-established","status/bootstrap-phase" }; /* If these are set in the config, they override the automatic behavior. */ - SettingsObject settings(QStringLiteral("tor")); + SettingsObject settings("tor"); QHostAddress forceAddress(settings.read("socksAddress").toString()); quint16 port = (quint16)settings.read("socksPort").toInt(); @@ -478,8 +479,9 @@ void TorControlPrivate::getTorInfo() ev->mTorManagerEventType = RsTorManagerEventCode::TOR_CONNECTIVITY_CHANGED; rsEvents->sendEvent(ev); } - } else - keys << ByteArray("net/listeners/socks"); + } + else + keys .push_back("net/listeners/socks"); socket->sendCommand(command, command->build(keys)); } @@ -490,11 +492,12 @@ void TorControlPrivate::getTorInfoReply() if (!command || !q->isConnected()) return; - QList listenAddresses = splitQuotedStrings(command->get(ByteArray("net/listeners/socks")).toString().toLatin1(), ' '); - for (QList::Iterator it = listenAddresses.begin(); it != listenAddresses.end(); ++it) { - ByteArray value = unquotedString(*it); + std::list listenAddresses = splitQuotedStrings(command->get("net/listeners/socks").front(), ' '); + + for (const auto& add:listenAddresses) { + ByteArray value = unquotedString(add); int sepp = value.indexOf(':'); - QHostAddress address(QString::fromLatin1(value.mid(0, sepp))); + QHostAddress address(value.mid(0, sepp)); quint16 port = (quint16)value.mid(sepp+1).toUInt(); /* Use the first address that matches the one used for this control connection. If none do, @@ -523,16 +526,16 @@ void TorControlPrivate::getTorInfoReply() } } - if (command->get(ByteArray("status/circuit-established")).toInt() == 1) { + if (command->get("status/circuit-established").toInt() == 1) { torCtrlDebug() << "torctrl: Tor indicates that circuits have been established; state is TorReady" << std::endl; setTorStatus(TorControl::TorReady); } else { setTorStatus(TorControl::TorOffline); } - ByteArray bootstrap = command->get(ByteArray("status/bootstrap-phase")).toString().toLatin1(); - if (!bootstrap.isEmpty()) - updateBootstrap(splitQuotedStrings(bootstrap, ' ')); + auto bootstrap = command->get("status/bootstrap-phase"); + if (!bootstrap.empty()) + updateBootstrap(splitQuotedStrings(bootstrap.front(), ' ')); } void TorControl::addHiddenService(HiddenService *service) @@ -555,7 +558,7 @@ void TorControlPrivate::publishServices() } std::cerr << std::endl; - SettingsObject settings(QStringLiteral("tor")); + SettingsObject settings("tor"); if (settings.read("neverPublishServices").toBool()) { torCtrlDebug() << "torctrl: Skipping service publication because neverPublishService is enabled" << std::endl; @@ -567,12 +570,12 @@ void TorControlPrivate::publishServices() return; } - if (q->torVersionAsNewAs(QStringLiteral("0.2.7"))) { + if (q->torVersionAsNewAs("0.2.7")) { foreach (HiddenService *service, services) { - if (service->hostname().isEmpty()) + if (service->hostname().empty()) torCtrlDebug() << "torctrl: Creating a new hidden service" << std::endl; else - torCtrlDebug() << "torctrl: Publishing hidden service: " << service->hostname().toStdString() << std::endl; + torCtrlDebug() << "torctrl: Publishing hidden service: " << service->hostname() << std::endl; AddOnionCommand *onionCommand = new AddOnionCommand(service); QObject::connect(onionCommand, &AddOnionCommand::succeeded, service, &HiddenService::servicePublished); socket->sendCommand(onionCommand, onionCommand->build()); @@ -580,37 +583,37 @@ void TorControlPrivate::publishServices() } else { torCtrlDebug() << "torctrl: Using legacy SETCONF hidden service configuration for tor" << torVersion.toStdString() << std::endl; SetConfCommand *command = new SetConfCommand; - QList > torConfig; + std::list > torConfig; foreach (HiddenService *service, services) { - if (service->dataPath().isEmpty()) + if (service->dataPath().empty()) continue; - if (service->privateKey().isLoaded() && !QFile::exists(service->dataPath() + QStringLiteral("/private_key"))) { + if (service->privateKey().isLoaded() && !RsDirUtil::fileExists(service->dataPath() + "/private_key")) { // This case can happen if tor is downgraded after the profile is created - qWarning() << "Cannot publish ephemeral hidden services with this version of tor; skipping"; + RsWarn() << "Cannot publish ephemeral hidden services with this version of tor; skipping"; continue; } - torCtrlDebug() << "torctrl: Configuring hidden service at" << service->dataPath().toStdString() << std::endl; + torCtrlDebug() << "torctrl: Configuring hidden service at" << service->dataPath() << std::endl; QDir dir(service->dataPath()); torConfig.append(qMakePair(ByteArray("HiddenServiceDir"), dir.absolutePath().toLocal8Bit())); - const QList &targets = service->targets(); - for (QList::ConstIterator tit = targets.begin(); tit != targets.end(); ++tit) + const std::list &targets = service->targets(); + for (auto tit:targets) { - QString target = QString::fromLatin1("%1 %2:%3").arg(tit->servicePort) - .arg(tit->targetAddress.toString()) - .arg(tit->targetPort); - torConfig.append(qMakePair(ByteArray("HiddenServicePort"), target.toLatin1())); + std::string target = RsUtil::NumberToString(tit.servicePort) + " " + +tit.targetAddress + ":" + +RsUtil::NumberToString(tit.targetPort); + torConfig.append(qMakePair(ByteArray("HiddenServicePort"), target)); } QObject::connect(command, &SetConfCommand::setConfSucceeded, service, &HiddenService::servicePublished); } - if (!torConfig.isEmpty()) + if (!torConfig.empty()) socket->sendCommand(command, command->build(torConfig)); } } @@ -644,34 +647,41 @@ void TorControlPrivate::statusEvent(int code, const ByteArray &data) { Q_UNUSED(code); - QList tokens = splitQuotedStrings(data.trimmed(), ' '); + std::list tokens = splitQuotedStrings(data.trimmed(), ' '); if (tokens.size() < 3) return; - torCtrlDebug() << "torctrl: status event:" << QString(data.trimmed()).toStdString() << std::endl; + torCtrlDebug() << "torctrl: status event:" << data.trimmed().toString() << std::endl; + const ByteArray& tok2 = *(++tokens.begin()); - if (tokens[2] == "CIRCUIT_ESTABLISHED") { + if (tok2 == "CIRCUIT_ESTABLISHED") { setTorStatus(TorControl::TorReady); - } else if (tokens[2] == "CIRCUIT_NOT_ESTABLISHED") { + } else if (tok2 == "CIRCUIT_NOT_ESTABLISHED") { setTorStatus(TorControl::TorOffline); - } else if (tokens[2] == "BOOTSTRAP") { - tokens.takeFirst(); + } else if (tok2 == "BOOTSTRAP") { + tokens.pop_front(); updateBootstrap(tokens); } } -void TorControlPrivate::updateBootstrap(const QList &data) +void TorControlPrivate::updateBootstrap(const std::list &data) { bootstrapStatus.clear(); // WARN or NOTICE - bootstrapStatus[QStringLiteral("severity")] = data.value(0); - for (int i = 1; i < data.size(); i++) { - int equals = data[i].indexOf('='); - QString key = QString::fromLatin1(data[i].mid(0, equals)); - QString value; + bootstrapStatus["severity"] = (*data.begin()).toString(); + + auto dat = data.begin(); + ++dat; + + for(;dat!=data.end();++dat) { // for(int i = 1; i < data.size(); i++) { + int equals = (*dat).indexOf('='); + ByteArray key = (*dat).mid(0, equals); + ByteArray value; + if (equals >= 0) - value = QString::fromLatin1(unquotedString(data[i].mid(equals + 1))); - bootstrapStatus[key.toLower()] = value; + value = unquotedString((*dat).mid(equals + 1)); + + bootstrapStatus[key.toLower().toString()] = value.toString(); } //torCtrlDebug() << bootstrapStatus << std::endl; @@ -685,16 +695,16 @@ void TorControlPrivate::updateBootstrap(const QList &data) } } -QObject *TorControl::getConfiguration(const QString &options) +QObject *TorControl::getConfiguration(const std::string& options) { GetConfCommand *command = new GetConfCommand(GetConfCommand::GetConf); - d->socket->sendCommand(command, command->build(options.toLatin1())); + d->socket->sendCommand(command, command->build(options)); //QQmlEngine::setObjectOwnership(command, QQmlEngine::CppOwnership); return command; } -QObject *TorControl::setConfiguration(const QVariantMap &options) +QObject *TorControl::setConfiguration(const std::list >& options) { SetConfCommand *command = new SetConfCommand; command->setResetMode(true); @@ -721,7 +731,8 @@ public: Q_ASSERT(!command); command = new GetConfCommand(GetConfCommand::GetInfo); QObject::connect(command, &TorControlCommand::finished, this, &SaveConfigOperation::configTextReply); - socket->sendCommand(command, command->build(QList() << "config-text" << "config-file")); + + socket->sendCommand(command, command->build(std::list { "config-text" , "config-file" } )); } private slots: @@ -731,23 +742,29 @@ private slots: if (!command) return; - QString path = QFile::decodeName(command->get("config-file").toByteArray()); - if (path.isEmpty()) { - finishWithError(QStringLiteral("Cannot write torrc without knowing its path")); + auto lpath = command->get("config-file"); + std::string path = (lpath.empty()?std::string():lpath.front()); + + if (path.empty()) { + finishWithError("Cannot write torrc without knowing its path"); return; } // Out of paranoia, refuse to write any file not named 'torrc', or if the // file doesn't exist - QFileInfo fileInfo(path); - if (fileInfo.fileName() != QStringLiteral("torrc") || !fileInfo.exists()) { - finishWithError(QStringLiteral("Refusing to write torrc to unacceptable path %1").arg(path)); + + auto filename = RsDirUtil::getFileName(path); + + if(filename != "torrc" || !RsDirUtil::fileExists(path)) + { + finishWithError("Refusing to write torrc to unacceptable path " + path); return; } - QSaveFile file(path); - if (!file.open(QIODevice::WriteOnly | QIODevice::Text)) { - finishWithError(QStringLiteral("Failed opening torrc file for writing: %1").arg(file.errorString())); + std::ofstream file(path); + + if (!file.is_open()) { + finishWithError("Failed opening torrc file for writing: permissions error?"); return; } @@ -761,9 +778,11 @@ private slots: 0 }; - QVariantList configText = command->get("config-text").toList(); - foreach (const QVariant &value, configText) { - ByteArray line = value.toByteArray(); + auto configText = command->get("config-text") ; + + for(const auto& value: configText) + { + ByteArray line(value); bool skip = false; for (const char **key = bannedKeys; *key; key++) { @@ -775,14 +794,10 @@ private slots: if (skip) continue; - file.write(line); - file.write("\n"); + file << line.toString() << std::endl; } - if (!file.commit()) { - finishWithError(QStringLiteral("Failed writing torrc: %1").arg(file.errorString())); - return; - } + file.close(); torCtrlDebug() << "torctrl: Wrote torrc file" << std::endl; finishWithSuccess(); @@ -820,12 +835,12 @@ void TorControl::takeOwnership() d->socket->sendCommand("TAKEOWNERSHIP\r\n"); // Reset PID-based polling - QVariantMap options; - options[QStringLiteral("__OwningControllerProcess")] = QVariant(); + std::list > options; + options.push_back(std::make_pair("__OwningControllerProcess",std::string())); setConfiguration(options); } -bool TorControl::torVersionAsNewAs(const QString &match) const +bool TorControl::torVersionAsNewAs(const std::string& match) const { QRegularExpression r(QStringLiteral("[.-]")); QStringList split = torVersion().split(r); diff --git a/libretroshare/src/tor/TorControl.h b/libretroshare/src/tor/TorControl.h index 5d208656e..d60b1430b 100644 --- a/libretroshare/src/tor/TorControl.h +++ b/libretroshare/src/tor/TorControl.h @@ -38,6 +38,7 @@ #include #include #include "PendingOperation.h" +#include "bytearray.h" class QNetworkProxy; @@ -86,9 +87,9 @@ public: /* Information */ Status status() const; TorStatus torStatus() const; - QString torVersion() const; - bool torVersionAsNewAs(const QString &version) const; - QString errorMessage() const; + std::string torVersion() const; + bool torVersionAsNewAs(const std::string &version) const; + std::string errorMessage() const; bool hasConnectivity() const; QHostAddress socksAddress() const; @@ -96,7 +97,7 @@ public: QNetworkProxy connectionProxy(); /* Authentication */ - void setAuthPassword(const QByteArray &password); + void setAuthPassword(const ByteArray& password); /* Connection */ bool isConnected() const { return status() == Connected; } @@ -111,9 +112,9 @@ public: QList hiddenServices() const; void addHiddenService(HiddenService *service); - QVariantMap bootstrapStatus() const; - Q_INVOKABLE QObject *getConfiguration(const QString &options); - Q_INVOKABLE QObject *setConfiguration(const QVariantMap &options); + std::map bootstrapStatus() const; + Q_INVOKABLE QObject *getConfiguration(const std::string &options); + Q_INVOKABLE QObject *setConfiguration(const std::list > &options); Q_INVOKABLE PendingOperation *saveConfiguration(); signals: diff --git a/libretroshare/src/tor/TorControlSocket.cpp b/libretroshare/src/tor/TorControlSocket.cpp index 3517907b6..966dd76c1 100644 --- a/libretroshare/src/tor/TorControlSocket.cpp +++ b/libretroshare/src/tor/TorControlSocket.cpp @@ -49,24 +49,27 @@ TorControlSocket::~TorControlSocket() clear(); } -void TorControlSocket::sendCommand(TorControlCommand *command, const QByteArray &data) +void TorControlSocket::sendCommand(TorControlCommand *command, const ByteArray &data) { - Q_ASSERT(data.endsWith("\r\n")); + assert(data.endsWith(ByteArray("\r\n"))); commandQueue.push_back(command); write(data); - std::cerr << "[TOR CTRL] Sent: \"" << QString(data.trimmed()).toStdString() << "\"" << std::endl; + std::cerr << "[TOR CTRL] Sent: \"" << data.trimmed().toString() << "\"" << std::endl; } -void TorControlSocket::registerEvent(const QByteArray &event, TorControlCommand *command) +void TorControlSocket::registerEvent(const ByteArray &event, TorControlCommand *command) { - eventCommands.insert(event, command); + eventCommands.insert(std::make_pair(event, command)); - QByteArray data("SETEVENTS"); - foreach (const QByteArray &key, eventCommands.keys()) { + ByteArray data("SETEVENTS"); + for(auto it:eventCommands) + { + //const ByteArray &key, eventCommands.keys()) { + //data += key; data += ' '; - data += key; + data += it.first; } data += "\r\n"; @@ -96,9 +99,9 @@ void TorControlSocket::process() if (!canReadLine()) return; - QByteArray line = readLine(5120); - if (!line.endsWith("\r\n")) { - setError(QStringLiteral("Invalid control message syntax")); + ByteArray line = readLine(5120); + if (!line.endsWith(ByteArray("\r\n"))) { + setError("Invalid control message syntax"); return; } line.chop(2); @@ -117,7 +120,7 @@ void TorControlSocket::process() } if (line.size() < 4) { - setError(QStringLiteral("Invalid control message syntax")); + setError("Invalid control message syntax"); return; } @@ -130,7 +133,7 @@ void TorControlSocket::process() line = line.mid(4); if (!isFinalReply && !inDataReply && type != '-') { - setError(QStringLiteral("Invalid control message syntax")); + setError("Invalid control message syntax"); return; } @@ -142,7 +145,7 @@ void TorControlSocket::process() currentCommand = eventCommands.value(line.mid(0, space)); if (!currentCommand) { - qWarning() << "torctrl: Ignoring unknown event"; + RsWarn() << "torctrl: Ignoring unknown event"; continue; } } @@ -155,19 +158,19 @@ void TorControlSocket::process() continue; } - if (commandQueue.isEmpty()) { - qWarning() << "torctrl: Received unexpected data"; + if (commandQueue.empty()) { + RsWarn() << "torctrl: Received unexpected data"; continue; } - TorControlCommand *command = commandQueue.first(); + TorControlCommand *command = commandQueue.front(); if (command) command->onReply(statusCode, line); if (inDataReply) { currentCommand = command; } else if (isFinalReply) { - commandQueue.takeFirst(); + commandQueue.pop_front(); if (command) { command->onFinished(statusCode); command->deleteLater(); diff --git a/libretroshare/src/tor/TorControlSocket.h b/libretroshare/src/tor/TorControlSocket.h index e5c1c17e8..7fff9a043 100644 --- a/libretroshare/src/tor/TorControlSocket.h +++ b/libretroshare/src/tor/TorControlSocket.h @@ -33,6 +33,7 @@ #pragma once #include "pqi/rstcpsocket.h" +#include "bytearray.h" namespace Tor { @@ -47,10 +48,10 @@ public: std::string errorMessage() const { return m_errorMessage; } - void registerEvent(const QByteArray &event, TorControlCommand *handler); + void registerEvent(const ByteArray &event, TorControlCommand *handler); void sendCommand(const std::string& data) { sendCommand(0, data); } - void sendCommand(TorControlCommand *command, const QByteArray &data); + void sendCommand(TorControlCommand *command, const ByteArray &data); signals: void error(const QString &message); @@ -61,7 +62,7 @@ private slots: private: std::list commandQueue; - QHash eventCommands; + std::map eventCommands; std::string m_errorMessage; TorControlCommand *currentCommand; bool inDataReply; @@ -70,5 +71,3 @@ private: }; } - -#endif // TORCONTROLSOCKET_H diff --git a/libretroshare/src/tor/TorManager.cpp b/libretroshare/src/tor/TorManager.cpp index f825bbfc7..d60a7775e 100644 --- a/libretroshare/src/tor/TorManager.cpp +++ b/libretroshare/src/tor/TorManager.cpp @@ -31,6 +31,7 @@ */ #include +#include // This works on linux only. I have no clue how to do that on windows. Anyway, this // is only needed for an assert that should normaly never be triggered. @@ -67,25 +68,25 @@ public: TorManager *q; TorProcess *process; TorControl *control; - QString dataDir; - QString hiddenServiceDir; - QStringList logMessages; - QString errorMessage; + std::string dataDir; + std::string hiddenServiceDir; + std::list logMessages; + std::string errorMessage; bool configNeeded; HiddenService *hiddenService ; explicit TorManagerPrivate(TorManager *parent = 0); - QString torExecutablePath() const; - bool createDataDir(const QString &path); - bool createDefaultTorrc(const QString &path); + std::string torExecutablePath() const; + bool createDataDir(const std::string &path); + bool createDefaultTorrc(const std::string &path); - void setError(const QString &errorMessage); + void setError(const std::string &errorMessage); virtual void processStateChanged(int state) override; - virtual void processErrorChanged(const QString &errorMessage) override; - virtual void processLogMessage(const QString &message) override; + virtual void processErrorChanged(const std::string &errorMessage) override; + virtual void processLogMessage(const std::string &message) override; public slots: void controlStatusChanged(int status); @@ -128,12 +129,12 @@ TorProcess *TorManager::process() return d->process; } -QString TorManager::torDataDirectory() const +std::string TorManager::torDataDirectory() const { return d->dataDir; } -void TorManager::setTorDataDirectory(const QString &path) +void TorManager::setTorDataDirectory(const std::string &path) { d->dataDir = QDir::fromNativeSeparators(path); @@ -141,16 +142,16 @@ void TorManager::setTorDataDirectory(const QString &path) d->dataDir.append(QLatin1Char('/')); } -QString TorManager::hiddenServiceDirectory() const +std::string TorManager::hiddenServiceDirectory() const { return d->hiddenServiceDir; } -void TorManager::setHiddenServiceDirectory(const QString &path) +void TorManager::setHiddenServiceDirectory(const std::string &path) { d->hiddenServiceDir = QDir::fromNativeSeparators(path); - if (!d->hiddenServiceDir.isEmpty() && !d->hiddenServiceDir.endsWith(QLatin1Char('/'))) - d->hiddenServiceDir.append(QLatin1Char('/')); + if (!d->hiddenServiceDir.empty() && !(d->hiddenServiceDir.back() == '/')) + d->hiddenServiceDir += '/'; } bool TorManager::setupHiddenService() @@ -161,34 +162,34 @@ bool TorManager::setupHiddenService() return true ; } - QString keyData ;//= m_settings->read("serviceKey").toString(); - QString legacyDir = d->hiddenServiceDir; + std::string keyData ;//= m_settings->read("serviceKey").toString(); + std::string legacyDir = d->hiddenServiceDir; std::cerr << "TorManager: setting up hidden service." << std::endl; - if(legacyDir.isNull()) + if(legacyDir.empty()) { std::cerr << "legacy dir not set! Cannot proceed." << std::endl; return false ; } - std::cerr << "Using legacy dir: " << legacyDir.toStdString() << std::endl; + std::cerr << "Using legacy dir: " << legacyDir << std::endl; - if (!legacyDir.isEmpty() && QFile::exists(legacyDir + QLatin1String("/private_key"))) + if (!legacyDir.empty() && QFile::exists(legacyDir.c_str() + QLatin1String("/private_key"))) { - std::cerr << "Attempting to load key from legacy filesystem format in " << legacyDir.toStdString() << std::endl; + std::cerr << "Attempting to load key from legacy filesystem format in " << legacyDir << std::endl; CryptoKey key; - if (!key.loadFromFile(legacyDir + QLatin1String("/private_key"))) + if (!key.loadFromFile(legacyDir + "/private_key")) { - qWarning() << "Cannot load legacy format key from" << legacyDir << "for conversion"; + RsWarn() << "Cannot load legacy format key from" << legacyDir << "for conversion"; return false; } d->hiddenService = new Tor::HiddenService(this,key, legacyDir); std::cerr << "Got key from legacy dir: " << std::endl; - std::cerr << key.bytes().toStdString() << std::endl; + std::cerr << key.bytes().toHex().toString() << std::endl; } else { @@ -239,11 +240,9 @@ void TorManager::hiddenServicePrivateKeyChanged() if(!d->hiddenService) return ; - QString key = QString::fromLatin1(d->hiddenService->privateKey().bytes()); + std::string key = d->hiddenService->privateKey().bytes().toString(); - QFile outfile(d->hiddenServiceDir + QLatin1String("/private_key")) ; - outfile.open( QIODevice::WriteOnly | QIODevice::Text ); - QTextStream s(&outfile); + std::ofstream s(d->hiddenServiceDir + "/private_key"); #ifdef TO_REMOVE s << "-----BEGIN RSA PRIVATE KEY-----" << endl; @@ -255,10 +254,10 @@ void TorManager::hiddenServicePrivateKeyChanged() #endif s << key ; - outfile.close(); + s.close(); std::cerr << "Hidden service private key changed!" << std::endl; - std::cerr << key.toStdString() << std::endl; + std::cerr << key << std::endl; } void TorManager::hiddenServiceHostnameChanged() @@ -270,7 +269,7 @@ void TorManager::hiddenServiceHostnameChanged() outfile2.open( QIODevice::WriteOnly | QIODevice::Text ); QTextStream t(&outfile2); - QString hostname(d->hiddenService->hostname()); + std::string hostname(d->hiddenService->hostname()); t << hostname << endl; outfile2.close(); @@ -283,7 +282,7 @@ bool TorManager::configurationNeeded() const return d->configNeeded; } -QStringList TorManager::logMessages() const +std::string TorManager::logMessages() const { return d->logMessages; } @@ -293,7 +292,7 @@ bool TorManager::hasError() const return !d->errorMessage.isEmpty(); } -QString TorManager::errorMessage() const +std::string TorManager::errorMessage() const { return d->errorMessage; } @@ -306,7 +305,7 @@ bool TorManager::start() //emit errorChanged(); // not needed because there's no error to handle } - SettingsObject settings(QStringLiteral("tor")); + SettingsObject settings("tor"); // If a control port is defined by config or environment, skip launching tor if (!settings.read("controlPort").isUndefined() || @@ -317,7 +316,7 @@ bool TorManager::start() QByteArray password = settings.read("controlPassword").toString().toLatin1(); if (!qEnvironmentVariableIsEmpty("TOR_CONTROL_HOST")) - address = QHostAddress(QString::fromLatin1(qgetenv("TOR_CONTROL_HOST"))); + address = QHostAddress(qgetenv("TOR_CONTROL_HOST")); if (!qEnvironmentVariableIsEmpty("TOR_CONTROL_PORT")) { bool ok = false; @@ -330,7 +329,7 @@ bool TorManager::start() password = qgetenv("TOR_CONTROL_PASSWD"); if (!port) { - d->setError(QStringLiteral("Invalid control port settings from environment or configuration")); + d->setError("Invalid control port settings from environment or configuration"); return false; } @@ -341,12 +340,12 @@ bool TorManager::start() d->control->connect(address, port); } else { // Launch a bundled Tor instance - QString executable = d->torExecutablePath(); + std::string executable = d->torExecutablePath(); std::cerr << "Executable path: " << executable.toStdString() << std::endl; if (executable.isEmpty()) { - d->setError(QStringLiteral("Cannot find tor executable")); + d->setError("Cannot find tor executable"); return false; } @@ -354,22 +353,23 @@ bool TorManager::start() d->process = new TorProcess(d); // QObject::connect(d->process, SIGNAL(stateChanged(int)), d, SLOT(processStateChanged(int))); - // QObject::connect(d->process, SIGNAL(errorMessageChanged(QString)), d, SLOT(processErrorChanged(QString))); - // QObject::connect(d->process, SIGNAL(logMessage(QString)), d, SLOT(processLogMessage(QString))); + // QObject::connect(d->process, SIGNAL(errorMessageChanged(std::string)), d, SLOT(processErrorChanged(std::string))); + // QObject::connect(d->process, SIGNAL(logMessage(std::string)), d, SLOT(processLogMessage(std::string))); } if (!QFile::exists(d->dataDir) && !d->createDataDir(d->dataDir)) { - d->setError(QStringLiteral("Cannot write data location: %1").arg(d->dataDir)); + d->setError(std::string("Cannot write data location: ") + d->dataDir); return false; } - QString defaultTorrc = d->dataDir + QStringLiteral("default_torrc"); - if (!QFile::exists(defaultTorrc) && !d->createDefaultTorrc(defaultTorrc)) { - d->setError(QStringLiteral("Cannot write data files: %1").arg(defaultTorrc)); + std::string defaultTorrc = d->dataDir + "default_torrc"; + if (!QFile::exists(defaultTorrc) && !d->createDefaultTorrc(defaultTorrc)) + { + d->setError("Cannot write data files: ")+defaultTorrc); return false; } - QFile torrc(d->dataDir + QStringLiteral("torrc")); + QFile torrc(d->dataDir + "torrc"); if (!torrc.exists() || torrc.size() == 0) { d->configNeeded = true; @@ -403,7 +403,7 @@ bool TorManager::getProxyServerInfo(QHostAddress& proxy_server_adress,uint16_t& return proxy_server_port > 1023 ; } -bool TorManager::getHiddenServiceInfo(QString& service_id,QString& 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, QHostAddress& service_target_address,uint16_t& target_port) { QList hidden_services = control()->hiddenServices(); @@ -431,7 +431,7 @@ bool TorManager::getHiddenServiceInfo(QString& service_id,QString& service_onion void TorManagerPrivate::processStateChanged(int state) { - std::cerr << Q_FUNC_INFO << "state: " << state << " passwd=\"" << QString(process->controlPassword()).toStdString() << "\" " << process->controlHost().toString().toStdString() + std::cerr << Q_FUNC_INFO << "state: " << state << " passwd=\"" << std::string(process->controlPassword()).toStdString() << "\" " << process->controlHost().toString().toStdString() << ":" << process->controlPort() << std::endl; if (state == TorProcess::Ready) { control->setAuthPassword(process->controlPassword()); @@ -439,18 +439,18 @@ void TorManagerPrivate::processStateChanged(int state) } } -void TorManagerPrivate::processErrorChanged(const QString &errorMessage) +void TorManagerPrivate::processErrorChanged(const std::string &errorMessage) { - std::cerr << "tor error:" << errorMessage.toStdString() << std::endl; + std::cerr << "tor error:" << errorMessage << std::endl; setError(errorMessage); } -void TorManagerPrivate::processLogMessage(const QString &message) +void TorManagerPrivate::processLogMessage(const std::string &message) { - std::cerr << "tor:" << message.toStdString() << std::endl; + std::cerr << "tor:" << message << std::endl; if (logMessages.size() >= 50) - logMessages.takeFirst(); - logMessages.append(message); + logMessages.pop_front(); + logMessages.push_back(message); } void TorManagerPrivate::controlStatusChanged(int status) @@ -458,7 +458,7 @@ void TorManagerPrivate::controlStatusChanged(int status) if (status == TorControl::Connected) { if (!configNeeded) { // If DisableNetwork is 1, trigger configurationNeeded - connect(control->getConfiguration(QStringLiteral("DisableNetwork")), + connect(control->getConfiguration("DisableNetwork"), SIGNAL(finished()), SLOT(getConfFinished())); } @@ -488,18 +488,18 @@ void TorManagerPrivate::getConfFinished() } } -QString TorManagerPrivate::torExecutablePath() const +std::string TorManagerPrivate::torExecutablePath() const { - SettingsObject settings(QStringLiteral("tor")); - QString path = settings.read("executablePath").toString(); + SettingsObject settings("tor"); + std::string path = settings.read("executablePath").toString(); if (!path.isEmpty() && QFile::exists(path)) return path; #ifdef Q_OS_WIN - QString filename(QStringLiteral("/tor/tor.exe")); + std::string filename("/tor/tor.exe"); #else - QString filename(QStringLiteral("/tor")); + std::string filename("/tor"); #endif path = qApp->applicationDirPath(); @@ -508,7 +508,7 @@ QString TorManagerPrivate::torExecutablePath() const return path + filename; #ifdef BUNDLED_TOR_PATH - path = QStringLiteral(BUNDLED_TOR_PATH); + path = BUNDLED_TOR_PATH; if (QFile::exists(path + filename)) return path + filename; #endif @@ -516,7 +516,7 @@ QString TorManagerPrivate::torExecutablePath() const #ifdef __APPLE__ // on MacOS, try traditional brew installation path - path = QStringLiteral("/usr/local/opt/tor/bin") ; + path = "/usr/local/opt/tor/bin" ; if (QFile::exists(path + filename)) return path + filename; @@ -526,13 +526,13 @@ QString TorManagerPrivate::torExecutablePath() const return filename.mid(1); } -bool TorManagerPrivate::createDataDir(const QString &path) +bool TorManagerPrivate::createDataDir(const std::string &path) { QDir dir(path); - return dir.mkpath(QStringLiteral(".")); + return dir.mkpath("."); } -bool TorManagerPrivate::createDefaultTorrc(const QString &path) +bool TorManagerPrivate::createDefaultTorrc(const std::string &path) { static const char defaultTorrcContent[] = "SocksPort auto\n" @@ -548,7 +548,7 @@ bool TorManagerPrivate::createDefaultTorrc(const QString &path) return true; } -void TorManagerPrivate::setError(const QString &message) +void TorManagerPrivate::setError(const std::string &message) { errorMessage = message; @@ -557,7 +557,7 @@ void TorManagerPrivate::setError(const QString &message) auto ev = std::make_shared(); ev->mTorManagerEventType = RsTorManagerEventCode::TOR_MANAGER_ERROR; - ev->mErrorMessage = message.toStdString(); + ev->mErrorMessage = message; rsEvents->sendEvent(ev); } //emit q->errorChanged(); @@ -567,7 +567,7 @@ void TorManagerPrivate::setError(const QString &message) bool RsTor::isTorAvailable() { - return !instance()->d->torExecutablePath().isNull(); + return !instance()->d->torExecutablePath().empty(); } bool RsTor::getHiddenServiceInfo(std::string& service_id, @@ -576,15 +576,15 @@ bool RsTor::getHiddenServiceInfo(std::string& service_id, std::string& service_target_address, uint16_t& target_port) { - QString sid; - QString soa; + std::string sid; + std::string soa; QHostAddress sta; if(!instance()->getHiddenServiceInfo(sid,soa,service_port,sta,target_port)) return false; - service_id = sid.toStdString(); - service_onion_address = soa.toStdString(); + service_id = sid; + service_onion_address = soa; service_target_address = sta.toString().toStdString(); return true; @@ -592,13 +592,7 @@ bool RsTor::getHiddenServiceInfo(std::string& service_id, std::list RsTor::logMessages() { - QStringList qs = instance()->logMessages(); - - std::list s; - for(auto& ss:qs) - s.push_back(ss.toStdString()); - - return s; + return instance()->logMessages(); } std::string RsTor::socksAddress() @@ -652,7 +646,7 @@ RsTorHiddenServiceStatus RsTor::getHiddenServiceStatus(std::string& service_id) if(list.empty()) return RsTorHiddenServiceStatus::NOT_CREATED; - service_id = (*list.begin())->serviceId().toStdString(); + service_id = (*list.begin())->serviceId(); switch((*list.begin())->status()) { @@ -680,7 +674,7 @@ bool RsTor::hasError() } std::string RsTor::errorMessage() { - return instance()->errorMessage().toStdString(); + return instance()->errorMessage(); } void RsTor::getProxyServerInfo(std::string& server_address, uint16_t& server_port) @@ -698,11 +692,11 @@ bool RsTor::start() void RsTor::setTorDataDirectory(const std::string& dir) { - instance()->setTorDataDirectory(QString::fromStdString(dir)); + instance()->setTorDataDirectory(dir); } void RsTor::setHiddenServiceDirectory(const std::string& dir) { - instance()->setHiddenServiceDirectory(QString::fromStdString(dir)); + instance()->setHiddenServiceDirectory(dir); } TorManager *RsTor::instance() diff --git a/libretroshare/src/tor/TorManager.h b/libretroshare/src/tor/TorManager.h index e0a24ae15..e70ca14b5 100644 --- a/libretroshare/src/tor/TorManager.h +++ b/libretroshare/src/tor/TorManager.h @@ -38,7 +38,6 @@ #include "retroshare/rstor.h" #include "HiddenService.h" -#include #include namespace Tor @@ -70,11 +69,11 @@ public: TorControl *control(); - QString torDataDirectory() const; - void setTorDataDirectory(const QString &path); + std::string torDataDirectory() const; + void setTorDataDirectory(const std::string &path); - QString hiddenServiceDirectory() const; - void setHiddenServiceDirectory(const QString &path); + std::string hiddenServiceDirectory() const; + void setHiddenServiceDirectory(const std::string &path); // Starts a hidden service, loading it from the config directory that has been set earlier. bool setupHiddenService() ; @@ -82,12 +81,12 @@ public: // True on first run or when the Tor configuration wizard needs to be shown bool configurationNeeded() const; - QStringList logMessages() const; + std::list logMessages() const; bool hasError() const; - QString errorMessage() const; + std::string errorMessage() const; - bool getHiddenServiceInfo(QString& service_id,QString& 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, QHostAddress& service_target_address,uint16_t& target_port); bool getProxyServerInfo(QHostAddress& proxy_server_adress,uint16_t& proxy_server_port); //public slots: diff --git a/libretroshare/src/tor/TorProcess.cpp b/libretroshare/src/tor/TorProcess.cpp index 1ad48db2d..81bd7b929 100644 --- a/libretroshare/src/tor/TorProcess.cpp +++ b/libretroshare/src/tor/TorProcess.cpp @@ -30,6 +30,12 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ +#include +#include +#include + +#include "util/rsdir.h" + #include "TorProcess_p.h" #include "CryptoKey.h" #include "SecureRNG.h" @@ -64,42 +70,42 @@ TorProcessPrivate::TorProcessPrivate(TorProcess *q) connect(&controlPortTimer, &QTimer::timeout, this, &TorProcessPrivate::tryReadControlPort); } -QString TorProcess::executable() const +std::string TorProcess::executable() const { return d->executable; } -void TorProcess::setExecutable(const QString &path) +void TorProcess::setExecutable(const std::string &path) { d->executable = path; } -QString TorProcess::dataDir() const +std::string TorProcess::dataDir() const { return d->dataDir; } -void TorProcess::setDataDir(const QString &path) +void TorProcess::setDataDir(const std::string &path) { d->dataDir = path; } -QString TorProcess::defaultTorrc() const +std::string TorProcess::defaultTorrc() const { return d->defaultTorrc; } -void TorProcess::setDefaultTorrc(const QString &path) +void TorProcess::setDefaultTorrc(const std::string &path) { d->defaultTorrc = path; } -QStringList TorProcess::extraSettings() const +std::list TorProcess::extraSettings() const { return d->extraSettings; } -void TorProcess::setExtraSettings(const QStringList &settings) +void TorProcess::setExtraSettings(const std::list &settings) { d->extraSettings = settings; } @@ -109,7 +115,7 @@ TorProcess::State TorProcess::state() const return d->state; } -QString TorProcess::errorMessage() const +std::string TorProcess::errorMessage() const { return d->errorMessage; } @@ -121,8 +127,8 @@ void TorProcess::start() d->errorMessage.clear(); - if (d->executable.isEmpty() || d->dataDir.isEmpty()) { - d->errorMessage = QStringLiteral("Tor executable and data directory not specified"); + if (d->executable.empty() || d->dataDir.empty()) { + d->errorMessage = "Tor executable and data directory not specified"; d->state = Failed; if(m_client) m_client->processStateChanged(d->state); // emit stateChanged(d->state); @@ -137,32 +143,50 @@ void TorProcess::start() return; } - QByteArray password = controlPassword(); - QByteArray hashedPassword = torControlHashedPassword(password); - if (password.isEmpty() || hashedPassword.isEmpty()) { - d->errorMessage = QStringLiteral("Random password generation failed"); + ByteArray password = controlPassword(); + ByteArray hashedPassword = torControlHashedPassword(password); + if (password.empty() || hashedPassword.empty()) { + d->errorMessage = "Random password generation failed"; d->state = Failed; if(m_client) m_client->processErrorChanged(d->errorMessage);// emit errorMessageChanged(d->errorMessage); if(m_client) m_client->processStateChanged(d->state); // emit stateChanged(d->state); } - QStringList args; - if (!d->defaultTorrc.isEmpty()) - args << QStringLiteral("--defaults-torrc") << d->defaultTorrc; - args << QStringLiteral("-f") << d->torrcPath(); - args << QStringLiteral("DataDirectory") << d->dataDir; - args << QStringLiteral("HashedControlPassword") << QString::fromLatin1(hashedPassword); - args << QStringLiteral("ControlPort") << QStringLiteral("auto"); - args << QStringLiteral("ControlPortWriteToFile") << d->controlPortFilePath(); - args << QStringLiteral("__OwningControllerProcess") << QString::number(qApp->applicationPid()); - args << d->extraSettings; + std::list args; + if (!d->defaultTorrc.empty()) + { + args.push_back("--defaults-torrc"); + args.push_back(d->defaultTorrc); + } + + args.push_back("-f"); + args.push_back(d->torrcPath()); + + args.push_back("DataDirectory") ; + args.push_back(d->dataDir); + + args.push_back("HashedControlPassword") ; + args.push_back(hashedPassword.toString()); + + args.push_back("ControlPort") ; + args.push_back("auto"); + + args.push_back("ControlPortWriteToFile"); + args.push_back(d->controlPortFilePath()); + + args.push_back("__OwningControllerProcess") ; + args.push_back(RsUtil::NumberToString(getpid())); + + for(auto s:d->extraSettings) + args.push_back(s); d->state = Starting; if(m_client) m_client->processStateChanged(d->state);// emit stateChanged(d->state); - if (QFile::exists(d->controlPortFilePath())) - QFile::remove(d->controlPortFilePath()); + if (RsDirUtil::fileExists(d->controlPortFilePath())) + RsDirUtil::removeFile(d->controlPortFilePath()); + d->controlPort = 0; d->controlHost.clear(); @@ -204,21 +228,22 @@ void TorProcess::stateChanged(int newState) if(m_client) m_client->processStateChanged(newState); } -void TorProcess::errorMessageChanged(const QString &errorMessage) +void TorProcess::errorMessageChanged(const std::string& errorMessage) { if(m_client) m_client->processErrorChanged(errorMessage); } -void TorProcess::logMessage(const QString &message) +void TorProcess::logMessage(const std::string& message) { if(m_client) m_client->processLogMessage(message); } -QByteArray TorProcess::controlPassword() +ByteArray TorProcess::controlPassword() { - if (d->controlPassword.isEmpty()) - d->controlPassword = SecureRNG::randomPrintable(16); + if (d->controlPassword.empty()) + d->controlPassword = RsRandom::printable(16); + return d->controlPassword; } @@ -234,29 +259,34 @@ quint16 TorProcess::controlPort() bool TorProcessPrivate::ensureFilesExist() { - QFile torrc(torrcPath()); - if (!torrc.exists()) { - QDir dir(dataDir); - if (!dir.exists() && !dir.mkpath(QStringLiteral("."))) { - errorMessage = QStringLiteral("Cannot create Tor data directory: %1").arg(dataDir); - return false; - } + if(!RsDirUtil::checkCreateDirectory(dataDir)) + { + errorMessage = "Cannot create Tor data directory: " + dataDir; + return false; + } - if (!torrc.open(QIODevice::ReadWrite)) { - errorMessage = QStringLiteral("Cannot create Tor configuration file: %1").arg(torrcPath()); + if (!RsDirUtil::fileExists(torrcPath())) + { + FILE *f = RsDirUtil::rs_fopen(torrcPath().c_str(),"w"); + + if(!f) + { + errorMessage = "Cannot create Tor configuration file: " + torrcPath(); return false; } + else + fclose(f); } return true; } -QString TorProcessPrivate::torrcPath() const +std::string TorProcessPrivate::torrcPath() const { return QDir::toNativeSeparators(dataDir) + QDir::separator() + QStringLiteral("torrc"); } -QString TorProcessPrivate::controlPortFilePath() const +std::string TorProcessPrivate::controlPortFilePath() const { return QDir::toNativeSeparators(dataDir) + QDir::separator() + QStringLiteral("control-port"); } @@ -278,9 +308,11 @@ void TorProcessPrivate::processFinished() return; controlPortTimer.stop(); - errorMessage = process.errorString(); - if (errorMessage.isEmpty()) - errorMessage = QStringLiteral("Process exited unexpectedly (code %1)").arg(process.exitCode()); + errorMessage = process.errorString().toStdString(); + + if (errorMessage.empty()) + errorMessage = "Process exited unexpectedly (code " + RsUtil::NumberToString(process.exitCode()) + ")"; + state = TorProcess::Failed; /*emit*/ q->errorMessageChanged(errorMessage); /*emit*/ q->stateChanged(state); @@ -294,22 +326,30 @@ void TorProcessPrivate::processError(QProcess::ProcessError error) void TorProcessPrivate::processReadable() { - while (process.bytesAvailable() > 0) { - QByteArray line = process.readLine(2048).trimmed(); - if (!line.isEmpty()) - /*emit*/ q->logMessage(QString::fromLatin1(line)); + while (process.bytesAvailable() > 0) + { + ByteArray line = process.readLine(2048).trimmed(); + + if (!line.empty()) + /*emit*/ q->logMessage(line.toString())); } } void TorProcessPrivate::tryReadControlPort() { - QFile file(controlPortFilePath()); - if (file.open(QIODevice::ReadOnly)) { - QByteArray data = file.readLine().trimmed(); + FILE *file = RsDirUtil::rs_fopen(controlPortFilePath().c_str(),"r"); + + if(file) + { + char *line = nullptr; + + size_t size = getline(&line,0,file); + ByteArray data = ByteArray((unsigned char*)line,size).trimmed(); + free(line); int p; if (data.startsWith("PORT=") && (p = data.lastIndexOf(':')) > 0) { - controlHost = QHostAddress(QString::fromLatin1(data.mid(5, p - 5))); + controlHost = QHostAddress(data.mid(5, p - 5)); controlPort = data.mid(p+1).toUShort(); if (!controlHost.isNull() && controlPort > 0) { @@ -322,7 +362,7 @@ void TorProcessPrivate::tryReadControlPort() } if (++controlPortAttempts * controlPortTimer.interval() > 10000) { - errorMessage = QStringLiteral("No control port available after launching process"); + errorMessage = "No control port available after launching process"; state = TorProcess::Failed; /*emit*/ q->errorMessageChanged(errorMessage); /*emit*/ q->stateChanged(state); diff --git a/libretroshare/src/tor/TorProcess.h b/libretroshare/src/tor/TorProcess.h index 9a2511f09..588da29f7 100644 --- a/libretroshare/src/tor/TorProcess.h +++ b/libretroshare/src/tor/TorProcess.h @@ -36,6 +36,8 @@ #include #include +#include "bytearray.h" + namespace Tor { @@ -47,8 +49,8 @@ class TorProcessClient { public: virtual void processStateChanged(int) = 0; - virtual void processErrorChanged(const QString&) = 0; - virtual void processLogMessage(const QString&) = 0; + virtual void processErrorChanged(const std::string&) = 0; + virtual void processLogMessage(const std::string&) = 0; }; /* Launches and controls a Tor instance with behavior suitable for bundling @@ -59,7 +61,7 @@ class TorProcess //Q_ENUMS(State) //Q_PROPERTY(State state READ state NOTIFY stateChanged) - //Q_PROPERTY(QString errorMessage READ errorMessage NOTIFY errorMessageChanged) + //Q_PROPERTY(std::string errorMessage READ errorMessage NOTIFY errorMessageChanged) public: enum State { @@ -73,28 +75,28 @@ public: explicit TorProcess(TorProcessClient *client,QObject *parent = 0); virtual ~TorProcess(); - QString executable() const; - void setExecutable(const QString &path); + std::string executable() const; + void setExecutable(const std::string &path); - QString dataDir() const; - void setDataDir(const QString &path); + std::string dataDir() const; + void setDataDir(const std::string &path); - QString defaultTorrc() const; - void setDefaultTorrc(const QString &path); + std::string defaultTorrc() const; + void setDefaultTorrc(const std::string &path); - QStringList extraSettings() const; - void setExtraSettings(const QStringList &settings); + std::list extraSettings() const; + void setExtraSettings(const std::list &settings); State state() const; - QString errorMessage() const; + std::string errorMessage() const; QHostAddress controlHost(); quint16 controlPort(); - QByteArray controlPassword(); + ByteArray controlPassword(); //signals: void stateChanged(int newState); - void errorMessageChanged(const QString &errorMessage); - void logMessage(const QString &message); + void errorMessageChanged(const std::string &errorMessage); + void logMessage(const std::string &message); //public slots: void start(); diff --git a/libretroshare/src/tor/TorProcess_p.h b/libretroshare/src/tor/TorProcess_p.h index 9aa2585e3..a95b0b24e 100644 --- a/libretroshare/src/tor/TorProcess_p.h +++ b/libretroshare/src/tor/TorProcess_p.h @@ -46,23 +46,23 @@ class TorProcessPrivate : public QObject public: TorProcess *q; QProcess process; - QString executable; - QString dataDir; - QString defaultTorrc; - QStringList extraSettings; + std::string executable; + std::string dataDir; + std::string defaultTorrc; + std::list extraSettings; TorProcess::State state; - QString errorMessage; + std::string errorMessage; QHostAddress controlHost; quint16 controlPort; - QByteArray controlPassword; + ByteArray controlPassword; QTimer controlPortTimer; int controlPortAttempts; TorProcessPrivate(TorProcess *q); - QString torrcPath() const; - QString controlPortFilePath() const; + std::string torrcPath() const; + std::string controlPortFilePath() const; bool ensureFilesExist(); public slots: diff --git a/libretroshare/src/tor/bytearray.h b/libretroshare/src/tor/bytearray.h index 05badb23e..8b3cde15b 100644 --- a/libretroshare/src/tor/bytearray.h +++ b/libretroshare/src/tor/bytearray.h @@ -1,8 +1,11 @@ +#pragma once + #include #include #include #include +#include #include "util/rsprint.h" #include "util/rsdebug.h" @@ -32,8 +35,10 @@ public: ByteArray& operator+=(const char *b) { for(uint32_t n=0;b[n]!=0;++n) push_back(b[n]); return *this;} ByteArray left(uint32_t l) const { auto res = *this; res.resize(std::min((uint32_t)size(),l)); return res; } - ByteArray toUpper() const { auto res = *this; for(uint32_t i=0;i='a') res[i] += 'A'-'a'; return res; } + ByteArray toUpper() const { auto res = *this; for(uint32_t i=0;i='a') res[i] += int('A')-int('a'); return res; } + ByteArray toLower() const { auto res = *this; for(uint32_t i=0;i='A') res[i] += int('a')-int('A'); return res; } + bool endsWidth(const ByteArray& b) const { return size() >= b.size() && !memcmp(&data()[size()-b.size()],b.data(),b.size()); } bool startsWith(const char *b) const { for(uint32_t n=0;b[n]!=0;++n) @@ -88,4 +93,59 @@ public: return res; } + + std::list split(unsigned char sep) + { + std::list res; + ByteArray current_block; + + for(uint32_t i=0;i=0;--i) + if(operator[](i) == s) + return i; + + return -1; + } }; diff --git a/libretroshare/src/util/rsdir.cc b/libretroshare/src/util/rsdir.cc index aa7e59299..e29ee50df 100644 --- a/libretroshare/src/util/rsdir.cc +++ b/libretroshare/src/util/rsdir.cc @@ -84,6 +84,25 @@ bool std::filesystem::create_directories(const std::string& path) # include #endif // __cplusplus < 201703L +bool RsDirUtil::fileExists(const std::string& file_path) +{ + FILE *f = fopen(file_path.c_str(),"r"); + + if(!f) + return false; + + fclose(f); + return true; +} +std::string RsDirUtil::getFileName(const std::string& full_file_path) +{ + size_t n = full_file_path.find_last_of('/'); + + if(n == std::string::npos) + return full_file_path; + else + return full_file_path.substr(n+1); +} std::string RsDirUtil::getTopDir(const std::string& dir) { std::string top; diff --git a/libretroshare/src/util/rsdir.h b/libretroshare/src/util/rsdir.h index 9f4b2e6b5..62b939cbb 100644 --- a/libretroshare/src/util/rsdir.h +++ b/libretroshare/src/util/rsdir.h @@ -63,12 +63,15 @@ std::string getRootDir(const std::string&); std::string removeRootDir(const std::string& path); void removeTopDir(const std::string& dir, std::string &path); std::string removeRootDirs(const std::string& path, const std::string& root); +std::string getFileName(const std::string& full_file_path); // Renames file from to file to. Files should be on the same file system. // returns true if succeed, false otherwise. bool renameFile(const std::string& from,const std::string& to) ; //bool createBackup (const std::string& sFilename, unsigned int nCount = 5); +bool fileExists(const std::string& file_path); + // returns the CRC32 of the data of length len // uint32_t rs_CRC32(const unsigned char *data,uint32_t len) ; @@ -107,6 +110,12 @@ rstime_t lastWriteTime( std::error_condition& errc = RS_DEFAULT_STORAGE_PARAM(std::error_condition) ); bool checkDirectory(const std::string& dir); + +/*! + * \brief checkCreateDirectory + * \param dir + * \return false when the directory does not exist and could not be created. + */ bool checkCreateDirectory(const std::string& dir); // Removes all symbolic links along the path and computes the actual location of the file/dir passed as argument. From d7afbea1dd958a1f71d21ac019dfe239c44ff90d Mon Sep 17 00:00:00 2001 From: csoler Date: Wed, 1 Dec 2021 23:05:16 +0100 Subject: [PATCH 18/65] progress in using ByteArray+std::string --- libretroshare/src/libretroshare.pro | 2 - libretroshare/src/pqi/pqifdbin.cc | 12 + libretroshare/src/pqi/pqifdbin.h | 4 + libretroshare/src/tor/Settings.cpp | 553 --------------------- libretroshare/src/tor/Settings.h | 256 ---------- libretroshare/src/tor/TorControl.cpp | 4 + libretroshare/src/tor/TorControlSocket.cpp | 49 +- libretroshare/src/tor/TorControlSocket.h | 18 +- libretroshare/src/tor/TorManager.cpp | 31 +- libretroshare/src/tor/TorProcess.cpp | 67 ++- libretroshare/src/tor/TorProcess.h | 6 +- libretroshare/src/tor/TorProcess_p.h | 4 +- libretroshare/src/tor/bytearray.h | 11 +- libretroshare/src/util/rsdir.cc | 10 - libretroshare/src/util/rsdir.h | 2 - 15 files changed, 171 insertions(+), 858 deletions(-) delete mode 100644 libretroshare/src/tor/Settings.cpp delete mode 100644 libretroshare/src/tor/Settings.h diff --git a/libretroshare/src/libretroshare.pro b/libretroshare/src/libretroshare.pro index be1187dcb..b72154c77 100644 --- a/libretroshare/src/libretroshare.pro +++ b/libretroshare/src/libretroshare.pro @@ -735,7 +735,6 @@ HEADERS += tor/AddOnionCommand.h \ tor/SecureRNG.h \ tor/TorTypes.h \ tor/SetConfCommand.h \ - tor/Settings.h \ tor/StrUtil.h \ tor/bytearray.h \ tor/TorControl.h \ @@ -760,7 +759,6 @@ SOURCES += tor/AddOnionCommand.cpp \ tor/CryptoKey.cpp \ tor/PendingOperation.cpp \ tor/SecureRNG.cpp \ - tor/Settings.cpp \ tor/StrUtil.cpp # gxs tunnels diff --git a/libretroshare/src/pqi/pqifdbin.cc b/libretroshare/src/pqi/pqifdbin.cc index 68798bf3d..96eaed5da 100644 --- a/libretroshare/src/pqi/pqifdbin.cc +++ b/libretroshare/src/pqi/pqifdbin.cc @@ -173,6 +173,18 @@ void RsFdBinInterface::clean() in_buffer.clear(); out_buffer.clear(); } + +int RsFdBinInterface::readline(void *data, int len) +{ + int n=0; + + for(auto p:in_buffer) + for(int i=0;i(p.first)[i] == '\n') + return readdata(data,n+1); + + return 0; +} int RsFdBinInterface::readdata(void *data, int len) { // read incoming bytes in the buffer diff --git a/libretroshare/src/pqi/pqifdbin.h b/libretroshare/src/pqi/pqifdbin.h index 4c532b436..d88a470fa 100644 --- a/libretroshare/src/pqi/pqifdbin.h +++ b/libretroshare/src/pqi/pqifdbin.h @@ -41,6 +41,10 @@ public: // int readdata(void *data, int len) override; + // Read at most len bytes only if \n is encountered within that range. Otherwise, nothing is changed. + // + int readline(void *data, int len) ; + int netstatus() override; int isactive() override; bool moretoread(uint32_t usec) override; diff --git a/libretroshare/src/tor/Settings.cpp b/libretroshare/src/tor/Settings.cpp deleted file mode 100644 index 68de71249..000000000 --- a/libretroshare/src/tor/Settings.cpp +++ /dev/null @@ -1,553 +0,0 @@ -/* Ricochet - https://ricochet.im/ - * Copyright (C) 2014, John Brooks - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * * Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following disclaimer - * in the documentation and/or other materials provided with the - * distribution. - * - * * Neither the names of the copyright owners nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include "Settings.h" -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -class SettingsFilePrivate : public QObject -{ - Q_OBJECT - -public: - SettingsFile *q; - std::string filePath; - std::string errorMessage; - QTimer syncTimer; - QJsonObject jsonRoot; - SettingsObject *rootObject; - - SettingsFilePrivate(SettingsFile *qp); - virtual ~SettingsFilePrivate(); - - void reset(); - void setError(const std::string &message); - bool checkDirPermissions(const std::string &path); - bool readFile(); - bool writeFile(); - - static std::list splitPath(const std::string& input, bool &ok); - QJsonValue read(const QJsonObject &base, const std::list &path); - bool write(const std::list &path, const QJsonValue &value); - -signals: - void modified(const std::list &path, const QJsonValue &value); - -private slots: - void sync(); -}; - -SettingsFile::SettingsFile(QObject *parent) - : QObject(parent), d(new SettingsFilePrivate(this)) -{ - d->rootObject = new SettingsObject(this, QString()); -} - -SettingsFile::~SettingsFile() -{ -} - -SettingsFilePrivate::SettingsFilePrivate(SettingsFile *qp) - : QObject(qp) - , q(qp) - , rootObject(0) -{ - syncTimer.setInterval(0); - syncTimer.setSingleShot(true); - connect(&syncTimer, &QTimer::timeout, this, &SettingsFilePrivate::sync); -} - -SettingsFilePrivate::~SettingsFilePrivate() -{ - if (syncTimer.isActive()) - sync(); - delete rootObject; -} - -void SettingsFilePrivate::reset() -{ - filePath.clear(); - errorMessage.clear(); - - jsonRoot = QJsonObject(); - emit modified(QStringList(), jsonRoot); -} - -QString SettingsFile::filePath() const -{ - return d->filePath; -} - -bool SettingsFile::setFilePath(const std::string& filePath) -{ - if (d->filePath == filePath) - return hasError(); - - d->reset(); - d->filePath = filePath; - - QFileInfo fileInfo(filePath); - QDir dir(fileInfo.path()); - if (!dir.exists() && !dir.mkpath(".")) { - d->setError("Cannot create directory: " + dir.path())); - return false; - } - d->checkDirPermissions(fileInfo.path()); - - if (!d->readFile()) - return false; - - return true; -} - -std::string SettingsFile::errorMessage() const -{ - return d->errorMessage; -} - -bool SettingsFile::hasError() const -{ - return !d->errorMessage.isEmpty(); -} - -void SettingsFilePrivate::setError(const QString &message) -{ - errorMessage = message; - emit q->error(); -} - -bool SettingsFilePrivate::checkDirPermissions(const QString &path) -{ - static QFile::Permissions desired = QFileDevice::ReadUser | QFileDevice::WriteUser | QFileDevice::ExeUser; - static QFile::Permissions ignored = QFileDevice::ReadOwner | QFileDevice::WriteOwner | QFileDevice::ExeOwner; - - QFile file(path); - if ((file.permissions() & ~ignored) != desired) { - qDebug() << "Correcting permissions on configuration directory"; - if (!file.setPermissions(desired)) { - qWarning() << "Correcting permissions on configuration directory failed"; - return false; - } - } - - return true; -} - -SettingsObject *SettingsFile::root() -{ - return d->rootObject; -} - -const SettingsObject *SettingsFile::root() const -{ - return d->rootObject; -} - -void SettingsFilePrivate::sync() -{ - if (filePath.isEmpty()) - return; - - syncTimer.stop(); - writeFile(); -} - -bool SettingsFilePrivate::readFile() -{ - QFile file(filePath); - if (!file.open(QIODevice::ReadWrite)) { - setError(file.errorString()); - return false; - } - - QByteArray data = file.readAll(); - if (data.isEmpty() && (file.error() != QFileDevice::NoError || file.size() > 0)) { - setError(file.errorString()); - return false; - } - - if (data.isEmpty()) { - jsonRoot = QJsonObject(); - return true; - } - - QJsonParseError parseError; - QJsonDocument document = QJsonDocument::fromJson(data, &parseError); - if (document.isNull()) { - setError(parseError.errorString()); - return false; - } - - if (!document.isObject()) { - setError(QStringLiteral("Invalid configuration file (expected object)")); - return false; - } - - jsonRoot = document.object(); - - emit modified(QStringList(), jsonRoot); - return true; -} - -bool SettingsFilePrivate::writeFile() -{ - QSaveFile file(filePath); - if (!file.open(QIODevice::WriteOnly | QIODevice::Truncate)) { - setError(file.errorString()); - return false; - } - - QJsonDocument document(jsonRoot); - QByteArray data = document.toJson(); - if (data.isEmpty() && !document.isEmpty()) { - setError(QStringLiteral("Encoding failure")); - return false; - } - - if (file.write(data) < data.size() || !file.commit()) { - setError(file.errorString()); - return false; - } - - return true; -} - -QStringList SettingsFilePrivate::splitPath(const QString &input, bool &ok) -{ - QStringList components = input.split(QLatin1Char('.')); - - // Allow a leading '.' to simplify concatenation - if (!components.isEmpty() && components.first().isEmpty()) - components.takeFirst(); - - // No other empty components, including a trailing . - foreach (const QString &word, components) { - if (word.isEmpty()) { - ok = false; - return QStringList(); - } - } - - ok = true; - return components; -} - -QJsonValue SettingsFilePrivate::read(const QJsonObject &base, const QStringList &path) -{ - QJsonValue current = base; - - foreach (const QString &key, path) { - QJsonObject object = current.toObject(); - if (object.isEmpty() || (current = object.value(key)).isUndefined()) - return QJsonValue::Undefined; - } - - return current; -} - -// Compare two QJsonValue to find keys that have changed, -// recursing into objects and building paths as necessary. -typedef QList > ModifiedList; -static void findModifiedRecursive(ModifiedList &modified, const QStringList &path, const QJsonValue &oldValue, const QJsonValue &newValue) -{ - if (oldValue.isObject() || newValue.isObject()) { - // If either is a non-object type, this returns an empty object - QJsonObject oldObject = oldValue.toObject(); - QJsonObject newObject = newValue.toObject(); - - // Iterate keys of the original object and compare to new - for (QJsonObject::iterator it = oldObject.begin(); it != oldObject.end(); it++) { - QJsonValue newSubValue = newObject.value(it.key()); - if (*it == newSubValue) - continue; - - if ((*it).isObject() || newSubValue.isObject()) - findModifiedRecursive(modified, QStringList() << path << it.key(), *it, newSubValue); - else - modified.append(qMakePair(QStringList() << path << it.key(), newSubValue)); - } - - // Iterate keys of the new object that may not be in original - for (QJsonObject::iterator it = newObject.begin(); it != newObject.end(); it++) { - if (oldObject.contains(it.key())) - continue; - - if ((*it).isObject()) - findModifiedRecursive(modified, QStringList() << path << it.key(), QJsonValue::Undefined, it.value()); - else - modified.append(qMakePair(QStringList() << path << it.key(), it.value())); - } - } else - modified.append(qMakePair(path, newValue)); -} - -bool SettingsFilePrivate::write(const QStringList &path, const QJsonValue &value) -{ - typedef QVarLengthArray > ObjectStack; - ObjectStack stack; - QJsonValue current = jsonRoot; - QJsonValue originalValue; - QString currentKey; - - foreach (const QString &key, path) { - const QJsonObject &parent = current.toObject(); - stack.append(qMakePair(currentKey, parent)); - current = parent.value(key); - currentKey = key; - } - - // Stack now contains parent objects starting with the root, and current - // is the old value. Write back changes in reverse. - if (current == value) - return false; - originalValue = current; - current = value; - - ObjectStack::const_iterator it = stack.end(), begin = stack.begin(); - while (it != begin) { - --it; - QJsonObject update = it->second; - update.insert(currentKey, current); - current = update; - currentKey = it->first; - } - - // current is now the updated jsonRoot - jsonRoot = current.toObject(); - syncTimer.start(); - - ModifiedList modified; - findModifiedRecursive(modified, path, originalValue, value); - - for (ModifiedList::iterator it = modified.begin(); it != modified.end(); it++) - emit this->modified(it->first, it->second); - - return true; -} - -class SettingsObjectPrivate : public QObject -{ - Q_OBJECT - -public: - explicit SettingsObjectPrivate(SettingsObject *q); - - SettingsObject *q; - SettingsFile *file; - QStringList path; - QJsonObject object; - bool invalid; - - void setFile(SettingsFile *file); - -public slots: - void modified(const QStringList &absolutePath, const QJsonValue &value); -}; - -SettingsObject::SettingsObject(QObject *parent) - : QObject(parent) - , d(new SettingsObjectPrivate(this)) -{ - d->setFile(defaultFile()); - if (d->file) - setPath(QString()); -} - -SettingsObject::SettingsObject(const QString &path, QObject *parent) - : QObject(parent) - , d(new SettingsObjectPrivate(this)) -{ - d->setFile(defaultFile()); - setPath(path); -} - -SettingsObject::SettingsObject(SettingsFile *file, const QString &path, QObject *parent) - : QObject(parent) - , d(new SettingsObjectPrivate(this)) -{ - d->setFile(file); - setPath(path); -} - -SettingsObject::SettingsObject(SettingsObject *base, const QString &path, QObject *parent) - : QObject(parent) - , d(new SettingsObjectPrivate(this)) -{ - d->setFile(base->d->file); - setPath(base->path() + QLatin1Char('.') + path); -} - -SettingsObjectPrivate::SettingsObjectPrivate(SettingsObject *qp) - : QObject(qp) - , q(qp) - , file(0) - , invalid(true) -{ -} - -void SettingsObjectPrivate::setFile(SettingsFile *value) -{ - if (file == value) - return; - - if (file) - disconnect(file, 0, this, 0); - file = value; - if (file) - connect(file->d, &SettingsFilePrivate::modified, this, &SettingsObjectPrivate::modified); -} - -// Emit SettingsObject::modified with a relative path if path is matched -void SettingsObjectPrivate::modified(const QStringList &key, const QJsonValue &value) -{ - if (key.size() < path.size()) - return; - - for (int i = 0; i < path.size(); i++) { - if (path[i] != key[i]) - return; - } - - object = file->d->read(file->d->jsonRoot, path).toObject(); - emit q->modified(QStringList(key.mid(path.size())).join(QLatin1Char('.')), value); - emit q->dataChanged(); -} - -static QPointer defaultObjectFile; - -SettingsFile *SettingsObject::defaultFile() -{ - return defaultObjectFile; -} - -void SettingsObject::setDefaultFile(SettingsFile *file) -{ - defaultObjectFile = file; -} - -QString SettingsObject::path() const -{ - return d->path.join(QLatin1Char('.')); -} - -void SettingsObject::setPath(const QString &input) -{ - bool ok = false; - QStringList newPath = SettingsFilePrivate::splitPath(input, ok); - if (!ok) { - d->invalid = true; - d->path.clear(); - d->object = QJsonObject(); - - emit pathChanged(); - emit dataChanged(); - return; - } - - if (!d->invalid && d->path == newPath) - return; - - d->path = newPath; - if (d->file) { - d->invalid = false; - d->object = d->file->d->read(d->file->d->jsonRoot, d->path).toObject(); - emit dataChanged(); - } - - emit pathChanged(); -} - -QJsonObject SettingsObject::data() const -{ - return d->object; -} - -void SettingsObject::setData(const QJsonObject &input) -{ - if (d->invalid || d->object == input) - return; - - d->object = input; - d->file->d->write(d->path, d->object); -} - -QJsonValue SettingsObject::read(const QString &key, const QJsonValue &defaultValue) const -{ - bool ok = false; - QStringList splitKey = SettingsFilePrivate::splitPath(key, ok); - if (d->invalid || !ok || splitKey.isEmpty()) { - qDebug() << "Invalid settings read of path" << key; - return defaultValue; - } - - QJsonValue ret = d->file->d->read(d->object, splitKey); - if (ret.isUndefined()) - ret = defaultValue; - return ret; -} - -void SettingsObject::write(const QString &key, const QJsonValue &value) -{ - bool ok = false; - QStringList splitKey = SettingsFilePrivate::splitPath(key, ok); - if (d->invalid || !ok || splitKey.isEmpty()) { - qDebug() << "Invalid settings write of path" << key; - return; - } - - splitKey = d->path + splitKey; - d->file->d->write(splitKey, value); -} - -void SettingsObject::unset(const QString &key) -{ - write(key, QJsonValue()); -} - -void SettingsObject::undefine() -{ - if (d->invalid) - return; - - d->object = QJsonObject(); - d->file->d->write(d->path, QJsonValue::Undefined); -} - -#include "Settings.moc" diff --git a/libretroshare/src/tor/Settings.h b/libretroshare/src/tor/Settings.h deleted file mode 100644 index 30377d429..000000000 --- a/libretroshare/src/tor/Settings.h +++ /dev/null @@ -1,256 +0,0 @@ -/* Ricochet - https://ricochet.im/ - * Copyright (C) 2014, John Brooks - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * * Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following disclaimer - * in the documentation and/or other materials provided with the - * distribution. - * - * * Neither the names of the copyright owners nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef SETTINGS_H -#define SETTINGS_H - -#include -#include -#include -#include -#include - -class SettingsObject; -class SettingsFilePrivate; -class SettingsObjectPrivate; - -/* SettingsFile represents a JSON-encoded configuration file. - * - * SettingsFile is an API for reading, writing, and change notification - * on JSON-encoded settings files. - * - * Data is accessed via SettingsObject, either using the root property - * or by creating a SettingsObject, optionally using a base path. - */ -class SettingsFile : public QObject -{ - Q_OBJECT - Q_DISABLE_COPY(SettingsFile) - - Q_PROPERTY(SettingsObject *root READ root CONSTANT) - Q_PROPERTY(QString filePath READ filePath WRITE setFilePath NOTIFY filePathChanged) - Q_PROPERTY(QString errorMessage READ errorMessage NOTIFY error) - Q_PROPERTY(bool hasError READ hasError NOTIFY error) - -public: - explicit SettingsFile(QObject *parent = 0); - virtual ~SettingsFile(); - - QString filePath() const; - bool setFilePath(const std::string &filePath); - - std::string errorMessage() const; - bool hasError() const; - - SettingsObject *root(); - const SettingsObject *root() const; - -signals: - void filePathChanged(); - void error(); - -private: - SettingsFilePrivate *d; - - friend class SettingsObject; - friend class SettingsObjectPrivate; -}; - -/* SettingsObject reads and writes data within a SettingsFile - * - * A SettingsObject is associated with a SettingsFile and represents an object - * tree within that file. It refers to the JSON object tree using a path - * notation with keys separated by '.'. For example: - * - * { - * "one": { - * "two": { - * "three": "value" - * } - * } - * } - * - * With this data, a SettingsObject with an empty path can read with the path - * "one.two.three", and a SettingsObject with a path of "one.two" can simply - * read or write on "three". - * - * Multiple SettingsObjects may be created for the same path, and will be kept - * synchronized with changes. The modified signal is emitted for all changes - * affecting keys within a path, including writes of object trees and from other - * instances. - */ -class SettingsObject : public QObject -{ - Q_OBJECT - Q_DISABLE_COPY(SettingsObject) - - Q_PROPERTY(QString path READ path WRITE setPath NOTIFY pathChanged) - Q_PROPERTY(QJsonObject data READ data WRITE setData NOTIFY dataChanged) - -public: - explicit SettingsObject(QObject *parent = 0); - explicit SettingsObject(const QString &path, QObject *parent = 0); - explicit SettingsObject(SettingsFile *file, const QString &path, QObject *parent = 0); - explicit SettingsObject(SettingsObject *base, const QString &path, QObject *parent = 0); - - /* Specify a SettingsFile to use by default on SettingsObject instances. - * - * After calling setDefaultFile, a SettingsObject created without any file, e.g.: - * - * SettingsObject settings; - * SettingsObject animals(QStringLiteral("animals")); - * - * Will use the specified SettingsFile instance by default. This is a convenience - * over passing around instances of SettingsFile in application use cases, and is - * particularly useful for QML. - */ - static SettingsFile *defaultFile(); - static void setDefaultFile(SettingsFile *file); - - std::string path() const; - void setPath(const std::string &path); - - QJsonObject data() const; - void setData(const QJsonObject &data); - - Q_INVOKABLE QJsonValue read(const std::string &key, const QJsonValue &defaultValue = QJsonValue::Undefined) const; - template T read(const std::string &key) const; - Q_INVOKABLE void write(const std::string &key, const QJsonValue &value); - template void write(const std::string &key, const T &value); - Q_INVOKABLE void unset(const std::string &key); - - // const char* key overloads - QJsonValue read(const char *key, const QJsonValue &defaultValue = QJsonValue::Undefined) const - { - return read(std::string(key), defaultValue); - } - template T read(const char *key) const - { - return read(std::string(key)); - } - void write(const char *key, const QJsonValue &value) - { - write(std::string(key), value); - } - template void write(const char *key, const T &value) - { - write(std::string(key), value); - } - void unset(const char *key) - { - unset(std::string(key)); - } - - Q_INVOKABLE void undefine(); - -signals: - void pathChanged(); - void dataChanged(); - - void modified(const std::string &path, const QJsonValue &value); - -private: - SettingsObjectPrivate *d; -}; - -template inline void SettingsObject::write(const std::string &key, const T &value) -{ - write(key, QJsonValue(value)); -} - -template<> inline std::string SettingsObject::read(const std::string &key) const -{ - return read(key).toString(); -} - -template<> inline QJsonArray SettingsObject::read(const std::string &key) const -{ - return read(key).toArray(); -} - -template<> inline QJsonObject SettingsObject::read(const std::string &key) const -{ - return read(key).toObject(); -} - -template<> inline double SettingsObject::read(const std::string &key) const -{ - return read(key).toDouble(); -} - -template<> inline int SettingsObject::read(const std::string &key) const -{ - return read(key).toInt(); -} - -template<> inline bool SettingsObject::read(const std::string &key) const -{ - return read(key).toBool(); -} - -template<> inline QDateTime SettingsObject::read(const std::string &key) const -{ - std::string value = read(key).toString(); - if (value.isEmpty()) - return QDateTime(); - return QDateTime::fromString(value, Qt::ISODate).toLocalTime(); -} - -template<> inline void SettingsObject::write(const std::string &key, const QDateTime &value) -{ - write(key, QJsonValue(value.toUTC().toString(Qt::ISODate))); -} - -// Explicitly store value encoded as base64. Decodes and casts implicitly to QByteArray for reads. -class Base64Encode -{ -public: - explicit Base64Encode(const QByteArray &value) : d(value) { } - operator QByteArray() { return d; } - QByteArray encoded() const { return d.toBase64(); } - -private: - QByteArray d; -}; - -template<> inline Base64Encode SettingsObject::read(const std::string &key) const -{ - return Base64Encode(QByteArray::fromBase64(read(key).toString().toLatin1())); -} - -template<> inline void SettingsObject::write(const std::string &key, const Base64Encode &value) -{ - write(key, QJsonValue(std::string(value.encoded()))); -} - -#endif - diff --git a/libretroshare/src/tor/TorControl.cpp b/libretroshare/src/tor/TorControl.cpp index 0add152c3..dec0ddf86 100644 --- a/libretroshare/src/tor/TorControl.cpp +++ b/libretroshare/src/tor/TorControl.cpp @@ -462,6 +462,7 @@ void TorControlPrivate::getTorInfo() std::list keys{ "status/circuit-established","status/bootstrap-phase" }; +#ifdef TODO /* If these are set in the config, they override the automatic behavior. */ SettingsObject settings("tor"); QHostAddress forceAddress(settings.read("socksAddress").toString()); @@ -481,6 +482,7 @@ void TorControlPrivate::getTorInfo() } } else +#endif keys .push_back("net/listeners/socks"); socket->sendCommand(command, command->build(keys)); @@ -558,6 +560,7 @@ void TorControlPrivate::publishServices() } std::cerr << std::endl; +#ifdef TODO SettingsObject settings("tor"); if (settings.read("neverPublishServices").toBool()) { @@ -569,6 +572,7 @@ void TorControlPrivate::publishServices() return; } +#endif if (q->torVersionAsNewAs("0.2.7")) { foreach (HiddenService *service, services) { diff --git a/libretroshare/src/tor/TorControlSocket.cpp b/libretroshare/src/tor/TorControlSocket.cpp index 966dd76c1..f92ba861b 100644 --- a/libretroshare/src/tor/TorControlSocket.cpp +++ b/libretroshare/src/tor/TorControlSocket.cpp @@ -37,11 +37,11 @@ using namespace Tor; -TorControlSocket::TorControlSocket() - : currentCommand(0), inDataReply(false) +TorControlSocket::TorControlSocket(const std::string& tcp_address,uint16_t tcp_port) + : RsThreadedTcpSocket(tcp_address,tcp_port),currentCommand(0), inDataReply(false) { - connect(this, SIGNAL(readyRead()), this, SLOT(process())); - connect(this, SIGNAL(disconnected()), this, SLOT(clear())); + //connect(this, SIGNAL(readyRead()), this, SLOT(process())); + //connect(this, SIGNAL(disconnected()), this, SLOT(clear())); } TorControlSocket::~TorControlSocket() @@ -49,12 +49,12 @@ TorControlSocket::~TorControlSocket() clear(); } -void TorControlSocket::sendCommand(TorControlCommand *command, const ByteArray &data) +void TorControlSocket::sendCommand(TorControlCommand *command, const ByteArray& data) { assert(data.endsWith(ByteArray("\r\n"))); commandQueue.push_back(command); - write(data); + senddata((void*)data.data(),data.size()); std::cerr << "[TOR CTRL] Sent: \"" << data.trimmed().toString() << "\"" << std::endl; } @@ -93,13 +93,28 @@ void TorControlSocket::setError(const std::string &message) abort(); } +ByteArray TorControlSocket::readline(int s) +{ + ByteArray b(s); + int real_size; + + if(! (real_size = RsTcpSocket::readline(b.data(),s))) + return ByteArray(); + else + { + b.resize(real_size); + return b; + } +} + void TorControlSocket::process() { for (;;) { - if (!canReadLine()) + if (!moretoread(0)) return; - ByteArray line = readLine(5120); + ByteArray line = readline(5120); + if (!line.endsWith(ByteArray("\r\n"))) { setError("Invalid control message syntax"); return; @@ -142,7 +157,12 @@ void TorControlSocket::process() if (!currentCommand) { int space = line.indexOf(' '); if (space > 0) - currentCommand = eventCommands.value(line.mid(0, space)); + { + auto it = eventCommands.find(line.mid(0, space).toString()); + + if(it != eventCommands.end()) + currentCommand = it->second; + } if (!currentCommand) { RsWarn() << "torctrl: Ignoring unknown event"; @@ -178,3 +198,14 @@ void TorControlSocket::process() } } } + +int TorControlSocket::tick() +{ + bool rw = RsTcpSocket::tick(); + + if(moretoread(0)) + process(); + + if(!rw) + std::this_thread::sleep_for(std::chrono::milliseconds(1000)); // temporisation when nothing happens +} diff --git a/libretroshare/src/tor/TorControlSocket.h b/libretroshare/src/tor/TorControlSocket.h index 7fff9a043..f988cf2b3 100644 --- a/libretroshare/src/tor/TorControlSocket.h +++ b/libretroshare/src/tor/TorControlSocket.h @@ -40,23 +40,29 @@ namespace Tor class TorControlCommand; -class TorControlSocket : public RsTcpSocket +class TorControlSocket : public RsThreadedTcpSocket { public: - explicit TorControlSocket(); + explicit TorControlSocket(const std::string& tcp_address,uint16_t tcp_port); virtual ~TorControlSocket(); std::string errorMessage() const { return m_errorMessage; } void registerEvent(const ByteArray &event, TorControlCommand *handler); - void sendCommand(const std::string& data) { sendCommand(0, data); } + void sendCommand(const ByteArray& data) { sendCommand(0, data); } void sendCommand(TorControlCommand *command, const ByteArray &data); -signals: - void error(const QString &message); + ByteArray readline(int s); -private slots: + // threaded TcpSocket + + virtual int tick() override; + +//signals: + void error(const std::string& message); + +//private slots: void process(); void clear(); diff --git a/libretroshare/src/tor/TorManager.cpp b/libretroshare/src/tor/TorManager.cpp index d60a7775e..dea22e3ae 100644 --- a/libretroshare/src/tor/TorManager.cpp +++ b/libretroshare/src/tor/TorManager.cpp @@ -32,6 +32,7 @@ #include #include +#include // This works on linux only. I have no clue how to do that on windows. Anyway, this // is only needed for an assert that should normaly never be triggered. @@ -305,6 +306,7 @@ bool TorManager::start() //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 @@ -338,7 +340,10 @@ bool TorManager::start() d->control->setAuthPassword(password); d->control->connect(address, port); - } else { + } + else +#endif + { // Launch a bundled Tor instance std::string executable = d->torExecutablePath(); @@ -490,11 +495,14 @@ void TorManagerPrivate::getConfFinished() std::string TorManagerPrivate::torExecutablePath() const { + std::string path; +#ifdef TODO SettingsObject settings("tor"); - std::string path = settings.read("executablePath").toString(); + path = settings.read("executablePath").toString(); if (!path.isEmpty() && QFile::exists(path)) return path; +#endif #ifdef Q_OS_WIN std::string filename("/tor/tor.exe"); @@ -540,11 +548,14 @@ bool TorManagerPrivate::createDefaultTorrc(const std::string &path) // "DisableNetwork 1\n" // (cyril) I removed this because it prevents Tor to bootstrap. "__ReloadTorrcOnSIGHUP 0\n"; - QFile file(path); - if (!file.open(QIODevice::WriteOnly)) - return false; - if (file.write(defaultTorrcContent) < 0) + FILE *f = fopen(path,"w"); + + if (!f) return false; + + fprintf(f,"%s",defaultTorrcContent); + + fclose(f); return true; } @@ -659,13 +670,7 @@ RsTorHiddenServiceStatus RsTor::getHiddenServiceStatus(std::string& service_id) std::map RsTor::bootstrapStatus() { - QVariantMap m = instance()->control()->bootstrapStatus(); - std::map res; - - for(auto it(m.begin());it!=m.end();++it) - res.insert(std::make_pair(it.key().toStdString(),it.value().toString().toStdString())); - - return res; + return instance()->control()->bootstrapStatus(); } bool RsTor::hasError() diff --git a/libretroshare/src/tor/TorProcess.cpp b/libretroshare/src/tor/TorProcess.cpp index 81bd7b929..1c3646eca 100644 --- a/libretroshare/src/tor/TorProcess.cpp +++ b/libretroshare/src/tor/TorProcess.cpp @@ -120,6 +120,63 @@ std::string TorProcess::errorMessage() const return d->errorMessage; } +// Does a fopen, but dup all file descriptors (STDIN STDOUT and STDERR) to the +// FDs supplied by the parent process + +int popen3(int fd[3],const char **const cmd) +{ + int i, e; + int p[3][2]; + pid_t pid; + // set all the FDs to invalid + for(i=0; i<3; i++) + p[i][0] = p[i][1] = -1; + // create the pipes + for(int i=0; i<3; i++) + if(pipe(p[i])) + goto error; + // and fork + pid = fork(); + if(-1 == pid) + goto error; + // in the parent? + if(pid) { + // parent + fd[STDIN_FILENO] = p[STDIN_FILENO][1]; + close(p[STDIN_FILENO][0]); + fd[STDOUT_FILENO] = p[STDOUT_FILENO][0]; + close(p[STDOUT_FILENO][1]); + fd[STDERR_FILENO] = p[STDERR_FILENO][0]; + close(p[STDERR_FILENO][1]); + // success + return 0; + } else { + // child + dup2(p[STDIN_FILENO][0],STDIN_FILENO); + close(p[STDIN_FILENO][1]); + dup2(p[STDOUT_FILENO][1],STDOUT_FILENO); + close(p[STDOUT_FILENO][0]); + dup2(p[STDERR_FILENO][1],STDERR_FILENO); + close(p[STDERR_FILENO][0]); + // here we try and run it + execv(*cmd,const_cast(cmd)); + // if we are there, then we failed to launch our program + perror("Could not launch"); + fprintf(stderr," \"%s\"\n",*cmd); + _exit(EXIT_FAILURE); + } + +error: + // preserve original error + e = errno; + for(i=0; i<3; i++) { + close(p[i][0]); + close(p[i][1]); + } + errno = e; + return -1; +} + void TorProcess::start() { if (state() > NotStarted) @@ -283,12 +340,14 @@ bool TorProcessPrivate::ensureFilesExist() std::string TorProcessPrivate::torrcPath() const { - return QDir::toNativeSeparators(dataDir) + QDir::separator() + QStringLiteral("torrc"); + //return QDir::toNativeSeparators(dataDir) + QDir::separator() + QStringLiteral("torrc"); + return dataDir + "/" + "torrc"; } std::string TorProcessPrivate::controlPortFilePath() const { - return QDir::toNativeSeparators(dataDir) + QDir::separator() + QStringLiteral("control-port"); + //return QDir::toNativeSeparators(dataDir) + QDir::separator() + QStringLiteral("control-port"); + return dataDir + "/" + "control-port"; } void TorProcessPrivate::processStarted() @@ -369,3 +428,7 @@ void TorProcessPrivate::tryReadControlPort() } } +void TorProcess::run() +{ + // +} diff --git a/libretroshare/src/tor/TorProcess.h b/libretroshare/src/tor/TorProcess.h index 588da29f7..153ad8c4e 100644 --- a/libretroshare/src/tor/TorProcess.h +++ b/libretroshare/src/tor/TorProcess.h @@ -37,6 +37,7 @@ #include #include "bytearray.h" +#include "util/rsthreads.h" namespace Tor { @@ -55,7 +56,7 @@ public: /* Launches and controls a Tor instance with behavior suitable for bundling * an instance with the application. */ -class TorProcess +class TorProcess: public RsTickingThread { //Q_OBJECT //Q_ENUMS(State) @@ -102,6 +103,9 @@ public: void start(); void stop(); + // implements RsThread / RsTickingThread + virtual void run() override; + private: TorProcessPrivate *d; TorProcessClient *m_client; diff --git a/libretroshare/src/tor/TorProcess_p.h b/libretroshare/src/tor/TorProcess_p.h index a95b0b24e..9c5ba1c9e 100644 --- a/libretroshare/src/tor/TorProcess_p.h +++ b/libretroshare/src/tor/TorProcess_p.h @@ -34,12 +34,10 @@ #define TORPROCESS_P_H #include "TorProcess.h" -#include -#include namespace Tor { -class TorProcessPrivate : public QObject +class TorProcessPrivate : public RsTickingThread { Q_OBJECT diff --git a/libretroshare/src/tor/bytearray.h b/libretroshare/src/tor/bytearray.h index 8b3cde15b..44727bce5 100644 --- a/libretroshare/src/tor/bytearray.h +++ b/libretroshare/src/tor/bytearray.h @@ -38,7 +38,16 @@ public: ByteArray toUpper() const { auto res = *this; for(uint32_t i=0;i='a') res[i] += int('A')-int('a'); return res; } ByteArray toLower() const { auto res = *this; for(uint32_t i=0;i='A') res[i] += int('a')-int('A'); return res; } - bool endsWidth(const ByteArray& b) const { return size() >= b.size() && !memcmp(&data()[size()-b.size()],b.data(),b.size()); } + int toInt() const + { + std::istringstream is(toString().c_str()); + + int res = 0; + is >> res ; + + return res; + } + bool endsWith(const ByteArray& b) const { return size() >= b.size() && !memcmp(&data()[size()-b.size()],b.data(),b.size()); } bool startsWith(const char *b) const { for(uint32_t n=0;b[n]!=0;++n) diff --git a/libretroshare/src/util/rsdir.cc b/libretroshare/src/util/rsdir.cc index e29ee50df..7e5f7dfab 100644 --- a/libretroshare/src/util/rsdir.cc +++ b/libretroshare/src/util/rsdir.cc @@ -84,16 +84,6 @@ bool std::filesystem::create_directories(const std::string& path) # include #endif // __cplusplus < 201703L -bool RsDirUtil::fileExists(const std::string& file_path) -{ - FILE *f = fopen(file_path.c_str(),"r"); - - if(!f) - return false; - - fclose(f); - return true; -} std::string RsDirUtil::getFileName(const std::string& full_file_path) { size_t n = full_file_path.find_last_of('/'); diff --git a/libretroshare/src/util/rsdir.h b/libretroshare/src/util/rsdir.h index 62b939cbb..7ad06a711 100644 --- a/libretroshare/src/util/rsdir.h +++ b/libretroshare/src/util/rsdir.h @@ -70,8 +70,6 @@ std::string getFileName(const std::string& full_file_path); bool renameFile(const std::string& from,const std::string& to) ; //bool createBackup (const std::string& sFilename, unsigned int nCount = 5); -bool fileExists(const std::string& file_path); - // returns the CRC32 of the data of length len // uint32_t rs_CRC32(const unsigned char *data,uint32_t len) ; From b03802fa1b2f52cd6916945ac0d196c5b2228b9c Mon Sep 17 00:00:00 2001 From: csoler Date: Thu, 2 Dec 2021 23:15:06 +0100 Subject: [PATCH 19/65] turned TorProcess into a non-Qt object, using built-in popen3 system --- libretroshare/src/libretroshare.pro | 1 - libretroshare/src/pqi/pqifdbin.cc | 4 +- libretroshare/src/tor/TorControl.cpp | 1 - libretroshare/src/tor/TorControlSocket.cpp | 2 + libretroshare/src/tor/TorManager.cpp | 1 - libretroshare/src/tor/TorProcess.cpp | 239 ++++++++++++--------- libretroshare/src/tor/TorProcess.h | 36 +++- libretroshare/src/tor/TorProcess_p.h | 77 ------- 8 files changed, 174 insertions(+), 187 deletions(-) delete mode 100644 libretroshare/src/tor/TorProcess_p.h diff --git a/libretroshare/src/libretroshare.pro b/libretroshare/src/libretroshare.pro index b72154c77..559c77354 100644 --- a/libretroshare/src/libretroshare.pro +++ b/libretroshare/src/libretroshare.pro @@ -742,7 +742,6 @@ HEADERS += tor/AddOnionCommand.h \ tor/TorControlSocket.h \ tor/TorManager.h \ tor/TorProcess.h \ - tor/TorProcess_p.h \ tor/Useful.h SOURCES += tor/AddOnionCommand.cpp \ diff --git a/libretroshare/src/pqi/pqifdbin.cc b/libretroshare/src/pqi/pqifdbin.cc index 96eaed5da..68b192c2b 100644 --- a/libretroshare/src/pqi/pqifdbin.cc +++ b/libretroshare/src/pqi/pqifdbin.cc @@ -179,8 +179,8 @@ int RsFdBinInterface::readline(void *data, int len) int n=0; for(auto p:in_buffer) - for(int i=0;i(p.first)[i] == '\n') + for(int i=0;i(p.first)[i] == '\n') return readdata(data,n+1); return 0; diff --git a/libretroshare/src/tor/TorControl.cpp b/libretroshare/src/tor/TorControl.cpp index dec0ddf86..650232ab1 100644 --- a/libretroshare/src/tor/TorControl.cpp +++ b/libretroshare/src/tor/TorControl.cpp @@ -44,7 +44,6 @@ #include "GetConfCommand.h" #include "AddOnionCommand.h" #include "StrUtil.h" -#include "Settings.h" #include "PendingOperation.h" #include #include diff --git a/libretroshare/src/tor/TorControlSocket.cpp b/libretroshare/src/tor/TorControlSocket.cpp index f92ba861b..0311b7061 100644 --- a/libretroshare/src/tor/TorControlSocket.cpp +++ b/libretroshare/src/tor/TorControlSocket.cpp @@ -208,4 +208,6 @@ int TorControlSocket::tick() if(!rw) std::this_thread::sleep_for(std::chrono::milliseconds(1000)); // temporisation when nothing happens + + return 0; // not sure about what we should return here. } diff --git a/libretroshare/src/tor/TorManager.cpp b/libretroshare/src/tor/TorManager.cpp index dea22e3ae..7fb367960 100644 --- a/libretroshare/src/tor/TorManager.cpp +++ b/libretroshare/src/tor/TorManager.cpp @@ -49,7 +49,6 @@ #include "CryptoKey.h" #include "HiddenService.h" #include "GetConfCommand.h" -#include "Settings.h" #include #include #include diff --git a/libretroshare/src/tor/TorProcess.cpp b/libretroshare/src/tor/TorProcess.cpp index 1c3646eca..4d6806f29 100644 --- a/libretroshare/src/tor/TorProcess.cpp +++ b/libretroshare/src/tor/TorProcess.cpp @@ -31,22 +31,21 @@ */ #include +#include #include #include #include "util/rsdir.h" +#include "pqi/pqifdbin.h" #include "TorProcess_p.h" #include "CryptoKey.h" #include "SecureRNG.h" -#include -#include -#include using namespace Tor; -TorProcess::TorProcess(TorProcessClient *client,QObject *parent) - : d(new TorProcessPrivate(this)),m_client(client) +TorProcess::TorProcess(TorProcessClient *client) + : m_client(client) { } @@ -56,78 +55,63 @@ TorProcess::~TorProcess() stop(); } -TorProcessPrivate::TorProcessPrivate(TorProcess *q) - : q(q), state(TorProcess::NotStarted), controlPort(0), controlPortAttempts(0) -{ - connect(&process, &QProcess::started, this, &TorProcessPrivate::processStarted); - connect(&process, (void (QProcess::*)(int, QProcess::ExitStatus))&QProcess::finished, - this, &TorProcessPrivate::processFinished); - connect(&process, (void (QProcess::*)(QProcess::ProcessError))&QProcess::error, - this, &TorProcessPrivate::processError); - connect(&process, &QProcess::readyRead, this, &TorProcessPrivate::processReadable); - - controlPortTimer.setInterval(500); - connect(&controlPortTimer, &QTimer::timeout, this, &TorProcessPrivate::tryReadControlPort); -} - std::string TorProcess::executable() const { - return d->executable; + return mExecutable; } void TorProcess::setExecutable(const std::string &path) { - d->executable = path; + mExecutable = path; } std::string TorProcess::dataDir() const { - return d->dataDir; + return mDataDir; } void TorProcess::setDataDir(const std::string &path) { - d->dataDir = path; + mDataDir = path; } std::string TorProcess::defaultTorrc() const { - return d->defaultTorrc; + return mDefaultTorrc; } void TorProcess::setDefaultTorrc(const std::string &path) { - d->defaultTorrc = path; + mDefaultTorrc = path; } std::list TorProcess::extraSettings() const { - return d->extraSettings; + return mExtraSettings; } void TorProcess::setExtraSettings(const std::list &settings) { - d->extraSettings = settings; + mExtraSettings = settings; } TorProcess::State TorProcess::state() const { - return d->state; + return mState; } std::string TorProcess::errorMessage() const { - return d->errorMessage; + return mErrorMessage; } // Does a fopen, but dup all file descriptors (STDIN STDOUT and STDERR) to the // FDs supplied by the parent process -int popen3(int fd[3],const char **const cmd) +int popen3(int fd[3],const char **const cmd,pid_t& pid) { int i, e; int p[3][2]; - pid_t pid; // set all the FDs to invalid for(i=0; i<3; i++) p[i][0] = p[i][1] = -1; @@ -140,7 +124,8 @@ int popen3(int fd[3],const char **const cmd) if(-1 == pid) goto error; // in the parent? - if(pid) { + if(pid) + { // parent fd[STDIN_FILENO] = p[STDIN_FILENO][1]; close(p[STDIN_FILENO][0]); @@ -150,7 +135,9 @@ int popen3(int fd[3],const char **const cmd) close(p[STDERR_FILENO][1]); // success return 0; - } else { + } + else + { // child dup2(p[STDIN_FILENO][0],STDIN_FILENO); close(p[STDIN_FILENO][1]); @@ -163,7 +150,6 @@ int popen3(int fd[3],const char **const cmd) // if we are there, then we failed to launch our program perror("Could not launch"); fprintf(stderr," \"%s\"\n",*cmd); - _exit(EXIT_FAILURE); } error: @@ -182,73 +168,130 @@ void TorProcess::start() if (state() > NotStarted) return; - d->errorMessage.clear(); + mErrorMessage.clear(); - if (d->executable.empty() || d->dataDir.empty()) { - d->errorMessage = "Tor executable and data directory not specified"; - d->state = Failed; + if (mExecutable.empty() || mDataDir.empty()) { + mErrorMessage = "Tor executable and data directory not specified"; + mState = Failed; - if(m_client) m_client->processStateChanged(d->state); // emit stateChanged(d->state); - if(m_client) m_client->processErrorChanged(d->errorMessage); // emit errorMessageChanged(d->errorMessage); + if(m_client) m_client->processStateChanged(mState); // emit stateChanged(d->state); + if(m_client) m_client->processErrorChanged(mErrorMessage); // emit errorMessageChanged(d->errorMessage); return; } - if (!d->ensureFilesExist()) { - d->state = Failed; - if(m_client) m_client->processErrorChanged(d->errorMessage);// emit errorMessageChanged(d->errorMessage); - if(m_client) m_client->processStateChanged(d->state);// emit stateChanged(d->state); + if (!ensureFilesExist()) { + mState = Failed; + if(m_client) m_client->processErrorChanged(mErrorMessage);// emit errorMessageChanged(d->errorMessage); + if(m_client) m_client->processStateChanged(mState);// emit stateChanged(d->state); return; } ByteArray password = controlPassword(); ByteArray hashedPassword = torControlHashedPassword(password); + if (password.empty() || hashedPassword.empty()) { - d->errorMessage = "Random password generation failed"; - d->state = Failed; - if(m_client) m_client->processErrorChanged(d->errorMessage);// emit errorMessageChanged(d->errorMessage); - if(m_client) m_client->processStateChanged(d->state); // emit stateChanged(d->state); + mErrorMessage = "Random password generation failed"; + mState = Failed; + if(m_client) m_client->processErrorChanged(mErrorMessage);// emit errorMessageChanged(d->errorMessage); + if(m_client) m_client->processStateChanged(mState); // emit stateChanged(d->state); } - std::list args; - if (!d->defaultTorrc.empty()) + mState = Starting; + + if(m_client) m_client->processStateChanged(mState);// emit stateChanged(d->state); + + if (RsDirUtil::fileExists(controlPortFilePath())) + RsDirUtil::removeFile(controlPortFilePath()); + + mControlPort = 0; + mControlHost.clear(); + + RsThread::start("TorControl"); +} + +void TorProcess::run() +{ + // We're inside the process control thread: launch the process, + + std::vector args; + + args.push_back(mExecutable); + + if (!mDefaultTorrc.empty()) { args.push_back("--defaults-torrc"); - args.push_back(d->defaultTorrc); + args.push_back(mDefaultTorrc); } args.push_back("-f"); - args.push_back(d->torrcPath()); + args.push_back(torrcPath()); args.push_back("DataDirectory") ; - args.push_back(d->dataDir); + args.push_back(mDataDir); args.push_back("HashedControlPassword") ; - args.push_back(hashedPassword.toString()); + args.push_back(torControlHashedPassword(mControlPassword).toString()); args.push_back("ControlPort") ; args.push_back("auto"); args.push_back("ControlPortWriteToFile"); - args.push_back(d->controlPortFilePath()); + args.push_back(controlPortFilePath()); args.push_back("__OwningControllerProcess") ; args.push_back(RsUtil::NumberToString(getpid())); - for(auto s:d->extraSettings) + for(auto s:mExtraSettings) args.push_back(s); - d->state = Starting; + const char *arguments[args.size()+1]; + int n=0; - if(m_client) m_client->processStateChanged(d->state);// emit stateChanged(d->state); + // We first pushed everything into a vector of strings to save the pointers obtained from string returning methods + // by the time the process is launched. - if (RsDirUtil::fileExists(d->controlPortFilePath())) - RsDirUtil::removeFile(d->controlPortFilePath()); + for(auto s:args) + arguments[n++]= s.c_str(); - d->controlPort = 0; - d->controlHost.clear(); + arguments[n] = nullptr; - d->process.setProcessChannelMode(QProcess::MergedChannels); - d->process.start(d->executable, args, QIODevice::ReadOnly); + int fd[3]; // File descriptors array + + if(popen3(fd,arguments,mTorProcessId)) + { + RsErr() << "Could not start Tor process. errno=" << errno ; + mState = Failed; + return; // stop the control thread + } + + RsFdBinInterface stdout_FD(fd[STDOUT_FILENO]); + RsFdBinInterface stderr_FD(fd[STDERR_FILENO]); + + unsigned char buff[1024]; + + while(!shouldStop()) + { + stdout_FD.tick(); + stderr_FD.tick(); + int s; + + if((s=stdout_FD.readline(buff,1024))) logMessage(std::string((char*)buff,s)); + if((s=stderr_FD.readline(buff,1024))) logMessage(std::string((char*)buff,s)); + + if(!stdout_FD.isactive() || !stderr_FD.isactive()) + { + RsErr() << "Tor process died. Exiting TorControl process." ; + return; + } + } + + // Kill the Tor process since we've been asked to stop. + + kill(mTorProcessId,SIGTERM); + int status=0; + wait(&status); + + RsInfo() << "Tor process has been normally terminated. Exiting."; } void TorProcess::stop() @@ -256,28 +299,14 @@ void TorProcess::stop() if (state() < Starting) return; - d->controlPortTimer.stop(); + while(mState == Starting) + std::this_thread::sleep_for(std::chrono::milliseconds(100)); - if (d->process.state() == QProcess::Starting) - d->process.waitForStarted(2000); + fullstop(); - d->state = NotStarted; + mState = NotStarted; - // Windows can't terminate the process well, but Tor will clean itself up -#ifndef Q_OS_WIN - if (d->process.state() == QProcess::Running) { - d->process.terminate(); - if (!d->process.waitForFinished(5000)) { - qWarning() << "Tor process" << d->process.pid() << "did not respond to terminate, killing..."; - d->process.kill(); - if (!d->process.waitForFinished(2000)) { - qCritical() << "Tor process" << d->process.pid() << "did not respond to kill!"; - } - } - } -#endif - - if(m_client) m_client->processStateChanged(d->state);// emit stateChanged(d->state); + if(m_client) m_client->processStateChanged(mState);// emit stateChanged(d->state); } void TorProcess::stateChanged(int newState) @@ -298,27 +327,27 @@ void TorProcess::logMessage(const std::string& message) ByteArray TorProcess::controlPassword() { - if (d->controlPassword.empty()) - d->controlPassword = RsRandom::printable(16); + if (mControlPassword.empty()) + mControlPassword = RsRandom::printable(16); - return d->controlPassword; + return mControlPassword; } QHostAddress TorProcess::controlHost() { - return d->controlHost; + return mControlHost; } quint16 TorProcess::controlPort() { - return d->controlPort; + return mControlPort; } -bool TorProcessPrivate::ensureFilesExist() +bool TorProcess::ensureFilesExist() { - if(!RsDirUtil::checkCreateDirectory(dataDir)) + if(!RsDirUtil::checkCreateDirectory(mDataDir)) { - errorMessage = "Cannot create Tor data directory: " + dataDir; + mErrorMessage = "Cannot create Tor data directory: " + mDataDir; return false; } @@ -328,7 +357,7 @@ bool TorProcessPrivate::ensureFilesExist() if(!f) { - errorMessage = "Cannot create Tor configuration file: " + torrcPath(); + mErrorMessage = "Cannot create Tor configuration file: " + torrcPath(); return false; } else @@ -338,18 +367,19 @@ bool TorProcessPrivate::ensureFilesExist() return true; } -std::string TorProcessPrivate::torrcPath() const +std::string TorProcess::torrcPath() const { //return QDir::toNativeSeparators(dataDir) + QDir::separator() + QStringLiteral("torrc"); - return dataDir + "/" + "torrc"; + return mDataDir + "/" + "torrc"; } -std::string TorProcessPrivate::controlPortFilePath() const +std::string TorProcess::controlPortFilePath() const { //return QDir::toNativeSeparators(dataDir) + QDir::separator() + QStringLiteral("control-port"); - return dataDir + "/" + "control-port"; + return mDataDir + "/" + "control-port"; } +#ifdef TO_REMOVE void TorProcessPrivate::processStarted() { state = TorProcess::Connecting; @@ -427,8 +457,19 @@ void TorProcessPrivate::tryReadControlPort() /*emit*/ q->stateChanged(state); } } - -void TorProcess::run() +TorProcessPrivate::TorProcessPrivate(TorProcess *q) + : q(q), state(TorProcess::NotStarted), controlPort(0), controlPortAttempts(0) { - // + connect(&process, &QProcess::started, this, &TorProcessPrivate::processStarted); + connect(&process, (void (QProcess::*)(int, QProcess::ExitStatus))&QProcess::finished, + this, &TorProcessPrivate::processFinished); + connect(&process, (void (QProcess::*)(QProcess::ProcessError))&QProcess::error, + this, &TorProcessPrivate::processError); + connect(&process, &QProcess::readyRead, this, &TorProcessPrivate::processReadable); + + controlPortTimer.setInterval(500); + connect(&controlPortTimer, &QTimer::timeout, this, &TorProcessPrivate::tryReadControlPort); } + + +#endif diff --git a/libretroshare/src/tor/TorProcess.h b/libretroshare/src/tor/TorProcess.h index 153ad8c4e..68649aa90 100644 --- a/libretroshare/src/tor/TorProcess.h +++ b/libretroshare/src/tor/TorProcess.h @@ -33,7 +33,6 @@ #ifndef TORPROCESS_H #define TORPROCESS_H -#include #include #include "bytearray.h" @@ -56,7 +55,7 @@ public: /* Launches and controls a Tor instance with behavior suitable for bundling * an instance with the application. */ -class TorProcess: public RsTickingThread +class TorProcess: public RsThread { //Q_OBJECT //Q_ENUMS(State) @@ -73,7 +72,7 @@ public: Ready }; - explicit TorProcess(TorProcessClient *client,QObject *parent = 0); + explicit TorProcess(TorProcessClient *client); virtual ~TorProcess(); std::string executable() const; @@ -103,12 +102,37 @@ public: void start(); void stop(); - // implements RsThread / RsTickingThread - virtual void run() override; + // Implements RsThread + void run() override ; + // Keeps reading the output of the tor process and so on. + void threadTick(); private: - TorProcessPrivate *d; TorProcessClient *m_client; + + std::string mExecutable; + std::string mDataDir; + std::string mDefaultTorrc; + std::list mExtraSettings; + TorProcess::State mState; + std::string mErrorMessage; + QHostAddress mControlHost; + quint16 mControlPort; + ByteArray mControlPassword; + + int controlPortAttempts; + + std::string torrcPath() const; + std::string controlPortFilePath() const; + bool ensureFilesExist(); + + pid_t mTorProcessId; +public slots: + void processStarted(); + void processFinished(); + void processError(std::string error); + void processReadable(); + void tryReadControlPort(); }; } diff --git a/libretroshare/src/tor/TorProcess_p.h b/libretroshare/src/tor/TorProcess_p.h deleted file mode 100644 index 9c5ba1c9e..000000000 --- a/libretroshare/src/tor/TorProcess_p.h +++ /dev/null @@ -1,77 +0,0 @@ -/* Ricochet - https://ricochet.im/ - * Copyright (C) 2014, John Brooks - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * * Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following disclaimer - * in the documentation and/or other materials provided with the - * distribution. - * - * * Neither the names of the copyright owners nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef TORPROCESS_P_H -#define TORPROCESS_P_H - -#include "TorProcess.h" - -namespace Tor { - -class TorProcessPrivate : public RsTickingThread -{ - Q_OBJECT - -public: - TorProcess *q; - QProcess process; - std::string executable; - std::string dataDir; - std::string defaultTorrc; - std::list extraSettings; - TorProcess::State state; - std::string errorMessage; - QHostAddress controlHost; - quint16 controlPort; - ByteArray controlPassword; - - QTimer controlPortTimer; - int controlPortAttempts; - - TorProcessPrivate(TorProcess *q); - - std::string torrcPath() const; - std::string controlPortFilePath() const; - bool ensureFilesExist(); - -public slots: - void processStarted(); - void processFinished(); - void processError(QProcess::ProcessError error); - void processReadable(); - void tryReadControlPort(); -}; - -} - -#endif - From bb37e2692b8b003635f4a964e0069412df7c8e17 Mon Sep 17 00:00:00 2001 From: csoler Date: Sun, 5 Dec 2021 00:02:12 +0100 Subject: [PATCH 20/65] removed more QString, QHostAddress, QFile, QDir,... --- libretroshare/src/pqi/pqifdbin.h | 1 + libretroshare/src/retroshare/rsinit.h | 1 + libretroshare/src/rsserver/rsinit.cc | 6 ++ libretroshare/src/tor/AddOnionCommand.cpp | 2 +- libretroshare/src/tor/HiddenService.cpp | 2 +- libretroshare/src/tor/HiddenService.h | 5 +- libretroshare/src/tor/TorControl.cpp | 61 ++++++------ libretroshare/src/tor/TorControl.h | 2 +- libretroshare/src/tor/TorControlSocket.cpp | 13 ++- libretroshare/src/tor/TorControlSocket.h | 2 + libretroshare/src/tor/TorManager.cpp | 105 ++++++++++++--------- libretroshare/src/tor/TorManager.h | 2 +- libretroshare/src/tor/TorProcess.cpp | 4 +- libretroshare/src/util/rsdir.cc | 10 ++ libretroshare/src/util/rsdir.h | 7 ++ libretroshare/src/util/rsprint.cc | 8 ++ libretroshare/src/util/rsprint.h | 4 + 17 files changed, 151 insertions(+), 84 deletions(-) diff --git a/libretroshare/src/pqi/pqifdbin.h b/libretroshare/src/pqi/pqifdbin.h index d88a470fa..5fa82df8e 100644 --- a/libretroshare/src/pqi/pqifdbin.h +++ b/libretroshare/src/pqi/pqifdbin.h @@ -48,6 +48,7 @@ public: int netstatus() override; int isactive() override; bool moretoread(uint32_t usec) override; + bool moretowrite(uint32_t usec) { return mTotalOutBufferBytes > 0 ; } bool cansend(uint32_t usec) override; int close() override; diff --git a/libretroshare/src/retroshare/rsinit.h b/libretroshare/src/retroshare/rsinit.h index c421755cc..ba2c33765 100644 --- a/libretroshare/src/retroshare/rsinit.h +++ b/libretroshare/src/retroshare/rsinit.h @@ -220,6 +220,7 @@ public: static void setAutoLogin(bool autoLogin); static bool RsClearAutoLogin() ; + static std::string executablePath() ; private: /** @brief Lock profile directory * param[in] accountDir account directory to lock diff --git a/libretroshare/src/rsserver/rsinit.cc b/libretroshare/src/rsserver/rsinit.cc index a49111021..cad6d3ae7 100644 --- a/libretroshare/src/rsserver/rsinit.cc +++ b/libretroshare/src/rsserver/rsinit.cc @@ -146,6 +146,7 @@ struct RsInitConfig {} RsFileHash main_executable_hash; + std::string mainExecutablePath; #ifdef WINDOWS_SYS bool portable; @@ -307,6 +308,7 @@ int RsInit::InitRetroShare(const RsConfigOptions& conf) rsInitConfig->optBaseDir = conf.optBaseDir; rsInitConfig->jsonApiPort = conf.jsonApiPort; rsInitConfig->jsonApiBindAddress = conf.jsonApiBindAddress; + rsInitConfig->mainExecutablePath = conf.main_executable_path; #ifdef PTW32_STATIC_LIB // for static PThreads under windows... we need to init the library... @@ -1932,6 +1934,10 @@ int RsServer::StartupRetroShare() return 1; } +std::string RsInit::executablePath() +{ + return rsInitConfig->mainExecutablePath; +} bool RsInit::startAutoTor() { std::cerr << "(II) node is an automated Tor node => launching Tor auto-configuration." << std::endl; diff --git a/libretroshare/src/tor/AddOnionCommand.cpp b/libretroshare/src/tor/AddOnionCommand.cpp index 9e8238c14..393f72541 100644 --- a/libretroshare/src/tor/AddOnionCommand.cpp +++ b/libretroshare/src/tor/AddOnionCommand.cpp @@ -65,7 +65,7 @@ ByteArray AddOnionCommand::build() out += " Port="; out += QByteArray::number(target.servicePort); out += ","; - out += target.targetAddress.toString().toLatin1(); + out += target.targetAddress; out += ":"; out += QByteArray::number(target.targetPort); } diff --git a/libretroshare/src/tor/HiddenService.cpp b/libretroshare/src/tor/HiddenService.cpp index 488f7db89..cb9adfa8a 100644 --- a/libretroshare/src/tor/HiddenService.cpp +++ b/libretroshare/src/tor/HiddenService.cpp @@ -83,7 +83,7 @@ void HiddenService::addTarget(const Target &target) m_targets.push_back(target); } -void HiddenService::addTarget(quint16 servicePort, QHostAddress targetAddress, quint16 targetPort) +void HiddenService::addTarget(quint16 servicePort, std::string targetAddress, quint16 targetPort) { Target t = { targetAddress, servicePort, targetPort }; m_targets.push_back(t); diff --git a/libretroshare/src/tor/HiddenService.h b/libretroshare/src/tor/HiddenService.h index b5c2b3281..2b69915f6 100644 --- a/libretroshare/src/tor/HiddenService.h +++ b/libretroshare/src/tor/HiddenService.h @@ -34,7 +34,6 @@ #define HIDDENSERVICE_H #include -#include #include "CryptoKey.h" #include "bytearray.h" @@ -63,7 +62,7 @@ class HiddenService : public QObject public: struct Target { - QHostAddress targetAddress; + std::string targetAddress; quint16 servicePort, targetPort; }; @@ -90,7 +89,7 @@ public: const std::list &targets() const { return m_targets; } void addTarget(const Target &target); - void addTarget(quint16 servicePort, QHostAddress targetAddress, quint16 targetPort); + void addTarget(quint16 servicePort, std::string targetAddress, quint16 targetPort); private slots: void servicePublished(); diff --git a/libretroshare/src/tor/TorControl.cpp b/libretroshare/src/tor/TorControl.cpp index 650232ab1..74fe41138 100644 --- a/libretroshare/src/tor/TorControl.cpp +++ b/libretroshare/src/tor/TorControl.cpp @@ -83,11 +83,11 @@ public: TorControl *q; TorControlSocket *socket; - QHostAddress torAddress; + std::string torAddress; std::string errorMessage; std::string torVersion; ByteArray authPassword; - QHostAddress socksAddress; + std::string socksAddress; QList services; quint16 controlPort, socksPort; TorControl::Status status; @@ -282,7 +282,7 @@ void TorControl::setAuthPassword(const ByteArray &password) d->authPassword = password; } -void TorControl::connect(const QHostAddress &address, quint16 port) +void TorControl::connect(const std::string &address, quint16 port) { if (status() > Connecting) { @@ -294,9 +294,9 @@ void TorControl::connect(const QHostAddress &address, quint16 port) d->controlPort = port; d->setTorStatus(TorUnknown); - bool b = d->socket->blockSignals(true); - d->socket->abort(); - d->socket->blockSignals(b); + //bool b = d->socket->blockSignals(true); + d->socket->fullstop(); + //d->socket->blockSignals(b); d->setStatus(Connecting); d->socket->connectToHost(address, port); @@ -304,8 +304,9 @@ void TorControl::connect(const QHostAddress &address, quint16 port) void TorControl::reconnect() { - Q_ASSERT(!d->torAddress.isNull() && d->controlPort); - if (d->torAddress.isNull() || !d->controlPort || status() >= Connecting) + assert(!d->torAddress.empty() && d->controlPort); + + if (d->torAddress.empty() || !d->controlPort || status() >= Connecting) return; d->setStatus(Connecting); @@ -332,7 +333,7 @@ void TorControlPrivate::authenticateReply() TorControlCommand *clientEvents = new TorControlCommand; connect(clientEvents, &TorControlCommand::replyLine, this, &TorControlPrivate::statusEvent); - socket->registerEvent("STATUS_CLIENT", clientEvents); + socket->registerEvent(ByteArray("STATUS_CLIENT"), clientEvents); getTorInfo(); publishServices(); @@ -400,11 +401,15 @@ void TorControlPrivate::protocolInfoReply() std::string cookieError; torCtrlDebug() << "torctrl: Using cookie authentication with file" << cookieFile << std::endl; - QFile file(cookieFile); - if (file.open(QIODevice::ReadOnly)) + FILE *f = fopen(cookieFile.c_str(),"r"); + + if(f) { - ByteArray cookie = file.readAll(); - file.close(); + std::string cookie; + char c; + while((c=getc(f))!=EOF) + cookie += c; + fclose(f); /* Simple test to avoid a vulnerability where any process listening on what we think is * the control port could trick us into sending the contents of an arbitrary file */ @@ -414,7 +419,7 @@ void TorControlPrivate::protocolInfoReply() cookieError = "Unexpected file size"; } else - cookieError = file.errorString(); + cookieError = "Cannot open file " + cookieFile + ". errno=" + RsUtil::NumberToString(errno); if (!cookieError.empty() || data.isNull()) { @@ -498,13 +503,13 @@ void TorControlPrivate::getTorInfoReply() for (const auto& add:listenAddresses) { ByteArray value = unquotedString(add); int sepp = value.indexOf(':'); - QHostAddress address(value.mid(0, sepp)); - quint16 port = (quint16)value.mid(sepp+1).toUInt(); + std::string address(value.mid(0, sepp).toString()); + quint16 port = (quint16)value.mid(sepp+1).toInt(); /* 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; * their setup is already very customized) */ - if (socksAddress.isNull() || address == socket->peerAddress()) { + if (socksAddress.empty() || address == socket->peerAddress()) { socksAddress = address; socksPort = port; if (address == socket->peerAddress()) @@ -515,8 +520,8 @@ void TorControlPrivate::getTorInfoReply() /* 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 * is reached. */ - if (!socksAddress.isNull()) { - torCtrlDebug() << "torctrl: SOCKS address is " << socksAddress.toString().toStdString() << ":" << socksPort << std::endl; + if (!socksAddress.empty()) { + torCtrlDebug() << "torctrl: SOCKS address is " << socksAddress << ":" << socksPort << std::endl; if(rsEvents) { @@ -601,8 +606,7 @@ void TorControlPrivate::publishServices() torCtrlDebug() << "torctrl: Configuring hidden service at" << service->dataPath() << std::endl; - QDir dir(service->dataPath()); - torConfig.append(qMakePair(ByteArray("HiddenServiceDir"), dir.absolutePath().toLocal8Bit())); + torConfig.push_back(std::make_pair("HiddenServiceDir", service->dataPath())); const std::list &targets = service->targets(); for (auto tit:targets) @@ -610,7 +614,7 @@ void TorControlPrivate::publishServices() std::string target = RsUtil::NumberToString(tit.servicePort) + " " +tit.targetAddress + ":" +RsUtil::NumberToString(tit.targetPort); - torConfig.append(qMakePair(ByteArray("HiddenServicePort"), target)); + torConfig.push_back(std::make_pair("HiddenServicePort", target)); } QObject::connect(command, &SetConfCommand::setConfSucceeded, service, &HiddenService::servicePublished); @@ -628,7 +632,7 @@ void TorControl::shutdown() return; } - d->socket->sendCommand("SIGNAL SHUTDOWN\r\n"); + d->socket->sendCommand(ByteArray("SIGNAL SHUTDOWN\r\n")); } void TorControl::shutdownSync() @@ -639,11 +643,10 @@ void TorControl::shutdownSync() } shutdown(); - while (d->socket->bytesToWrite()) - { - if (!d->socket->waitForBytesWritten(5000)) - return; - } + while (d->socket->moretowrite()) + std::this_thread::sleep_for(std::chrono::milliseconds(100)); + + d->socket->close(); } void TorControlPrivate::statusEvent(int code, const ByteArray &data) @@ -835,7 +838,7 @@ bool TorControl::hasOwnership() const void TorControl::takeOwnership() { d->hasOwnership = true; - d->socket->sendCommand("TAKEOWNERSHIP\r\n"); + d->socket->sendCommand(ByteArray("TAKEOWNERSHIP\r\n")); // Reset PID-based polling std::list > options; diff --git a/libretroshare/src/tor/TorControl.h b/libretroshare/src/tor/TorControl.h index d60b1430b..7380e240f 100644 --- a/libretroshare/src/tor/TorControl.h +++ b/libretroshare/src/tor/TorControl.h @@ -101,7 +101,7 @@ public: /* Connection */ bool isConnected() const { return status() == Connected; } - void connect(const QHostAddress &address, quint16 port); + void connect(const std::string &address, quint16 port); /* Ownership means that tor is managed by this socket, and we * can shut it down, own its configuration, etc. */ diff --git a/libretroshare/src/tor/TorControlSocket.cpp b/libretroshare/src/tor/TorControlSocket.cpp index 0311b7061..a3d465acc 100644 --- a/libretroshare/src/tor/TorControlSocket.cpp +++ b/libretroshare/src/tor/TorControlSocket.cpp @@ -49,6 +49,13 @@ TorControlSocket::~TorControlSocket() clear(); } +std::string TorControlSocket::peerAddress() const +{ + if(connectionState() == State::CONNECTED) + return connectAddress(); + else + return std::string(); +} void TorControlSocket::sendCommand(TorControlCommand *command, const ByteArray& data) { assert(data.endsWith(ByteArray("\r\n"))); @@ -78,10 +85,12 @@ void TorControlSocket::registerEvent(const ByteArray &event, TorControlCommand * void TorControlSocket::clear() { - qDeleteAll(commandQueue); + for(auto cmd:commandQueue) delete cmd; commandQueue.clear(); - qDeleteAll(eventCommands); + + for(auto cmd:eventCommands) delete cmd.second; eventCommands.clear(); + inDataReply = false; currentCommand = 0; } diff --git a/libretroshare/src/tor/TorControlSocket.h b/libretroshare/src/tor/TorControlSocket.h index f988cf2b3..a62feedf2 100644 --- a/libretroshare/src/tor/TorControlSocket.h +++ b/libretroshare/src/tor/TorControlSocket.h @@ -48,6 +48,7 @@ public: std::string errorMessage() const { return m_errorMessage; } + void connectToHost(const std::string& tcp_address,uint16_t tcp_port); void registerEvent(const ByteArray &event, TorControlCommand *handler); void sendCommand(const ByteArray& data) { sendCommand(0, data); } @@ -59,6 +60,7 @@ public: virtual int tick() override; + std::string peerAddress() const; //signals: void error(const std::string& message); diff --git a/libretroshare/src/tor/TorManager.cpp b/libretroshare/src/tor/TorManager.cpp index 7fb367960..a1aeb4bde 100644 --- a/libretroshare/src/tor/TorManager.cpp +++ b/libretroshare/src/tor/TorManager.cpp @@ -41,6 +41,9 @@ #include #endif +#include "util/rsdir.h" +#include "retroshare/rsinit.h" + #include #include "TorManager.h" @@ -136,10 +139,10 @@ std::string TorManager::torDataDirectory() const void TorManager::setTorDataDirectory(const std::string &path) { - d->dataDir = QDir::fromNativeSeparators(path); + d->dataDir = path; - if (!d->dataDir.isEmpty() && !d->dataDir.endsWith(QLatin1Char('/'))) - d->dataDir.append(QLatin1Char('/')); + if (!d->dataDir.empty() && !ByteArray(d->dataDir).endsWith('/')) + d->dataDir += '/'; } std::string TorManager::hiddenServiceDirectory() const @@ -148,7 +151,7 @@ std::string TorManager::hiddenServiceDirectory() const } void TorManager::setHiddenServiceDirectory(const std::string &path) { - d->hiddenServiceDir = QDir::fromNativeSeparators(path); + d->hiddenServiceDir = path; if (!d->hiddenServiceDir.empty() && !(d->hiddenServiceDir.back() == '/')) d->hiddenServiceDir += '/'; @@ -265,16 +268,15 @@ void TorManager::hiddenServiceHostnameChanged() if(!d->hiddenService) return ; - QFile outfile2(d->hiddenServiceDir + QLatin1String("/hostname")) ; - outfile2.open( QIODevice::WriteOnly | QIODevice::Text ); - QTextStream t(&outfile2); + std::string outfile2_name = RsDirUtil::makePath(d->hiddenServiceDir,"/hostname") ; + std::ofstream of(outfile2_name); std::string hostname(d->hiddenService->hostname()); - t << hostname << endl; - outfile2.close(); + of << hostname << std::endl; + of.close(); - std::cerr << "Hidden service hostname changed: " << hostname.toStdString() << std::endl; + std::cerr << "Hidden service hostname changed: " << hostname << std::endl; } bool TorManager::configurationNeeded() const @@ -282,14 +284,14 @@ bool TorManager::configurationNeeded() const return d->configNeeded; } -std::string TorManager::logMessages() const +const std::list& TorManager::logMessages() const { return d->logMessages; } bool TorManager::hasError() const { - return !d->errorMessage.isEmpty(); + return !d->errorMessage.empty(); } std::string TorManager::errorMessage() const @@ -299,7 +301,7 @@ std::string TorManager::errorMessage() const bool TorManager::start() { - if (!d->errorMessage.isEmpty()) { + if (!d->errorMessage.empty()) { d->errorMessage.clear(); //emit errorChanged(); // not needed because there's no error to handle @@ -346,9 +348,9 @@ bool TorManager::start() // Launch a bundled Tor instance std::string executable = d->torExecutablePath(); - std::cerr << "Executable path: " << executable.toStdString() << std::endl; + std::cerr << "Executable path: " << executable << std::endl; - if (executable.isEmpty()) { + if (executable.empty()) { d->setError("Cannot find tor executable"); return false; } @@ -361,20 +363,27 @@ bool TorManager::start() // QObject::connect(d->process, SIGNAL(logMessage(std::string)), d, SLOT(processLogMessage(std::string))); } - if (!QFile::exists(d->dataDir) && !d->createDataDir(d->dataDir)) { + if (!RsDirUtil::checkCreateDirectory(d->dataDir)) + { d->setError(std::string("Cannot write data location: ") + d->dataDir); return false; } - std::string defaultTorrc = d->dataDir + "default_torrc"; - if (!QFile::exists(defaultTorrc) && !d->createDefaultTorrc(defaultTorrc)) + std::string defaultTorrc = RsDirUtil::makePath(d->dataDir,"default_torrc"); + + if (!RsDirUtil::fileExists(defaultTorrc) && !d->createDefaultTorrc(defaultTorrc)) { - d->setError("Cannot write data files: ")+defaultTorrc); + d->setError("Cannot write data files: "+defaultTorrc); return false; } - QFile torrc(d->dataDir + "torrc"); - if (!torrc.exists() || torrc.size() == 0) { + std::string torrc = RsDirUtil::makePath(d->dataDir,"torrc"); + uint64_t file_size; + + bool torrc_exists = RsDirUtil::checkFile(torrc,file_size); + + if(!torrc_exists || torrc.size() == 0) + { d->configNeeded = true; if(rsEvents) @@ -387,9 +396,9 @@ bool TorManager::start() } std::cerr << "Starting Tor process:" << std::endl; - std::cerr << " Tor executable path: " << executable.toStdString() << std::endl; - std::cerr << " Tor data directory : " << d->dataDir.toStdString() << std::endl; - std::cerr << " Tor default torrc : " << defaultTorrc.toStdString() << std::endl; + std::cerr << " Tor executable path: " << executable << std::endl; + std::cerr << " Tor data directory : " << d->dataDir << std::endl; + std::cerr << " Tor default torrc : " << defaultTorrc << std::endl; d->process->setExecutable(executable); d->process->setDataDir(d->dataDir); @@ -435,8 +444,9 @@ bool TorManager::getHiddenServiceInfo(std::string& service_id,std::string& servi void TorManagerPrivate::processStateChanged(int state) { - std::cerr << Q_FUNC_INFO << "state: " << state << " passwd=\"" << std::string(process->controlPassword()).toStdString() << "\" " << process->controlHost().toString().toStdString() + RsInfo() << "state: " << state << " passwd=\"" << process->controlPassword().toString() << "\" " << process->controlHost().toString().toStdString() << ":" << process->controlPort() << std::endl; + if (state == TorProcess::Ready) { control->setAuthPassword(process->controlPassword()); control->connect(process->controlHost(), process->controlPort()); @@ -479,17 +489,21 @@ void TorManagerPrivate::getConfFinished() if (!command) return; - if (command->get("DisableNetwork").toInt() == 1 && !configNeeded) { - configNeeded = true; - //emit q->configurationNeededChanged(); + int n; - if(rsEvents) + for(auto str:command->get("DisableNetwork")) + if(RsUtil::StringToInt(str,n) && n==1 && !configNeeded) { - auto ev = std::make_shared(); - ev->mTorManagerEventType = RsTorManagerEventCode::CONFIGURATION_NEEDED; - rsEvents->sendEvent(ev); + configNeeded = true; + //emit q->configurationNeededChanged(); + + if(rsEvents) + { + auto ev = std::make_shared(); + ev->mTorManagerEventType = RsTorManagerEventCode::CONFIGURATION_NEEDED; + rsEvents->sendEvent(ev); + } } - } } std::string TorManagerPrivate::torExecutablePath() const @@ -509,34 +523,37 @@ std::string TorManagerPrivate::torExecutablePath() const std::string filename("/tor"); #endif - path = qApp->applicationDirPath(); + path = RsDirUtil::getDirectory(RsInit::executablePath()); + std::string tor_exe_path = RsDirUtil::makePath(path,filename); - if (QFile::exists(path + filename)) - return path + filename; + if (RsDirUtil::fileExists(tor_exe_path)) + return tor_exe_path; #ifdef BUNDLED_TOR_PATH path = BUNDLED_TOR_PATH; - if (QFile::exists(path + filename)) - return path + filename; + tor_exe_path = RsDirUtil::makePath(path,filename); + + if (RsDirUtil::fileExists(tor_exe_path)) + return tor_exe_path; #endif #ifdef __APPLE__ // on MacOS, try traditional brew installation path path = "/usr/local/opt/tor/bin" ; + tor_exe_path = RsDirUtil::makePath(path,filename); - if (QFile::exists(path + filename)) - return path + filename; + if (RsDirUtil::fileExists(tor_exe_path)) + return tor_exe_path; #endif // Try $PATH - return filename.mid(1); + return filename.substr(1); } bool TorManagerPrivate::createDataDir(const std::string &path) { - QDir dir(path); - return dir.mkpath("."); + return RsDirUtil::checkCreateDirectory(path); } bool TorManagerPrivate::createDefaultTorrc(const std::string &path) @@ -547,7 +564,7 @@ bool TorManagerPrivate::createDefaultTorrc(const std::string &path) // "DisableNetwork 1\n" // (cyril) I removed this because it prevents Tor to bootstrap. "__ReloadTorrcOnSIGHUP 0\n"; - FILE *f = fopen(path,"w"); + FILE *f = fopen(path.c_str(),"w"); if (!f) return false; diff --git a/libretroshare/src/tor/TorManager.h b/libretroshare/src/tor/TorManager.h index e70ca14b5..c396c2e5b 100644 --- a/libretroshare/src/tor/TorManager.h +++ b/libretroshare/src/tor/TorManager.h @@ -81,7 +81,7 @@ public: // True on first run or when the Tor configuration wizard needs to be shown bool configurationNeeded() const; - std::list logMessages() const; + const std::list& logMessages() const; bool hasError() const; std::string errorMessage() const; diff --git a/libretroshare/src/tor/TorProcess.cpp b/libretroshare/src/tor/TorProcess.cpp index 4d6806f29..907b9b78b 100644 --- a/libretroshare/src/tor/TorProcess.cpp +++ b/libretroshare/src/tor/TorProcess.cpp @@ -38,7 +38,7 @@ #include "util/rsdir.h" #include "pqi/pqifdbin.h" -#include "TorProcess_p.h" +#include "TorProcess.h" #include "CryptoKey.h" #include "SecureRNG.h" @@ -105,7 +105,7 @@ std::string TorProcess::errorMessage() const return mErrorMessage; } -// Does a fopen, but dup all file descriptors (STDIN STDOUT and STDERR) to the +// Does a popen, but dup all file descriptors (STDIN STDOUT and STDERR) to the // FDs supplied by the parent process int popen3(int fd[3],const char **const cmd,pid_t& pid) diff --git a/libretroshare/src/util/rsdir.cc b/libretroshare/src/util/rsdir.cc index 7e5f7dfab..897a481ee 100644 --- a/libretroshare/src/util/rsdir.cc +++ b/libretroshare/src/util/rsdir.cc @@ -93,6 +93,16 @@ std::string RsDirUtil::getFileName(const std::string& full_file_path) else return full_file_path.substr(n+1); } + +std::string RsDirUtil::getDirectory(const std::string& full_file_path) +{ + size_t n = full_file_path.find_last_of('/'); + + if(n == std::string::npos) + return std::string(); + else + return full_file_path.substr(0,n); +} std::string RsDirUtil::getTopDir(const std::string& dir) { std::string top; diff --git a/libretroshare/src/util/rsdir.h b/libretroshare/src/util/rsdir.h index 7ad06a711..457f4c26e 100644 --- a/libretroshare/src/util/rsdir.h +++ b/libretroshare/src/util/rsdir.h @@ -58,13 +58,20 @@ class RsStackFileLock namespace RsDirUtil { +// Returns the name of the directory on top of the given path (as opposed to the full path to that directory) std::string getTopDir(const std::string&); std::string getRootDir(const std::string&); std::string removeRootDir(const std::string& path); void removeTopDir(const std::string& dir, std::string &path); std::string removeRootDirs(const std::string& path, const std::string& root); + +// Returns the filename at the end of the path. An empty string is returned if the path is a directory path. std::string getFileName(const std::string& full_file_path); +// Returns the directory (full path) that contains the given path (filename or directory). +// If a directory is supplied, the same path is returned. +std::string getDirectory(const std::string& full_file_path); + // Renames file from to file to. Files should be on the same file system. // returns true if succeed, false otherwise. bool renameFile(const std::string& from,const std::string& to) ; diff --git a/libretroshare/src/util/rsprint.cc b/libretroshare/src/util/rsprint.cc index 4e547736a..5410ab0d0 100644 --- a/libretroshare/src/util/rsprint.cc +++ b/libretroshare/src/util/rsprint.cc @@ -22,6 +22,7 @@ #include "util/rsprint.h" #include "util/rsstring.h" +#include #include #include #include @@ -45,6 +46,13 @@ std::string RsUtil::NumberToString(uint64_t n,bool hex) return os.str(); } +bool RsUtil::StringToInt(const std::string& s,int& n) +{ + if(sscanf(s.c_str(),"%d",&n) == 1) + return true; + else + return false; +} std::string RsUtil::BinToHex(const std::string &bin) { return BinToHex(bin.c_str(), bin.length()); diff --git a/libretroshare/src/util/rsprint.h b/libretroshare/src/util/rsprint.h index dcaab6311..bdfcb942b 100644 --- a/libretroshare/src/util/rsprint.h +++ b/libretroshare/src/util/rsprint.h @@ -36,6 +36,10 @@ std::string BinToHex(const char *arr, const uint32_t len); std::string BinToHex(const unsigned char *arr, const uint32_t len, uint32_t max_len=0); bool HexToBin(const std::string& input,unsigned char *data, const uint32_t len); std::string NumberToString(uint64_t n, bool hex=false); + +// Returns in n the int that can be read in the string. Returns false when no int is fond. +bool StringToInt(const std::string& s,int& n); + std::string HashId(const std::string &id, bool reverse = false); std::vector BinToSha256(const std::vector &in); From e75d312724426be8c861d838cb0f3b095c503743 Mon Sep 17 00:00:00 2001 From: csoler Date: Sun, 5 Dec 2021 22:14:19 +0100 Subject: [PATCH 21/65] removed lots of signals/slots --- libretroshare/src/pqi/rstcpsocket.cc | 20 +- libretroshare/src/pqi/rstcpsocket.h | 5 + libretroshare/src/tor/AddOnionCommand.cpp | 4 +- libretroshare/src/tor/AddOnionCommand.h | 19 +- libretroshare/src/tor/AuthenticateCommand.h | 7 +- libretroshare/src/tor/GetConfCommand.h | 8 +- libretroshare/src/tor/ProtocolInfoCommand.h | 25 +- libretroshare/src/tor/SetConfCommand.cpp | 4 +- libretroshare/src/tor/SetConfCommand.h | 25 +- libretroshare/src/tor/TorControl.cpp | 380 ++++++++++---------- libretroshare/src/tor/TorControl.h | 92 +++-- libretroshare/src/tor/TorControlCommand.cpp | 10 +- libretroshare/src/tor/TorControlCommand.h | 31 +- libretroshare/src/tor/TorControlSocket.cpp | 8 +- libretroshare/src/tor/TorControlSocket.h | 15 +- libretroshare/src/tor/TorManager.cpp | 37 +- libretroshare/src/tor/TorManager.h | 6 +- libretroshare/src/tor/TorProcess.cpp | 4 +- libretroshare/src/tor/TorProcess.h | 12 +- libretroshare/src/tor/bytearray.h | 24 +- 20 files changed, 401 insertions(+), 335 deletions(-) diff --git a/libretroshare/src/pqi/rstcpsocket.cc b/libretroshare/src/pqi/rstcpsocket.cc index 25f830914..89350d8bd 100644 --- a/libretroshare/src/pqi/rstcpsocket.cc +++ b/libretroshare/src/pqi/rstcpsocket.cc @@ -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) { } + +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 CreateSocket = 0; @@ -42,6 +57,7 @@ int RsTcpSocket::connect() int RsTcpSocket::close() { RsFdBinInterface::close(); + mState = DISCONNECTED; return !::close(mSocket); } @@ -50,7 +66,9 @@ RsThreadedTcpSocket::RsThreadedTcpSocket(const std::string& tcp_address,uint16_t : RsTcpSocket(tcp_address,tcp_port) { } - +RsThreadedTcpSocket::RsThreadedTcpSocket() : RsTcpSocket() +{ +} void RsThreadedTcpSocket::run() { if(!connect()) diff --git a/libretroshare/src/pqi/rstcpsocket.h b/libretroshare/src/pqi/rstcpsocket.h index bdc127f91..b268d685c 100644 --- a/libretroshare/src/pqi/rstcpsocket.h +++ b/libretroshare/src/pqi/rstcpsocket.h @@ -6,6 +6,8 @@ class RsTcpSocket: public RsFdBinInterface { public: RsTcpSocket(const std::string& tcp_address,uint16_t tcp_port); + RsTcpSocket(); + virtual ~RsTcpSocket(); enum State: uint8_t { UNKNOWN = 0x00, @@ -16,6 +18,8 @@ public: // Return 1 when OK, 0 otherwise. int connect(); + int connect(const std::string& tcp_address,uint16_t tcp_port); + // Returns 1 when OK, 0 otherwise. int close(); @@ -34,6 +38,7 @@ class RsThreadedTcpSocket: public RsTcpSocket, public RsThread { public: RsThreadedTcpSocket(const std::string& tcp_address,uint16_t tcp_port); + RsThreadedTcpSocket(); virtual ~RsThreadedTcpSocket(); virtual void run() override; diff --git a/libretroshare/src/tor/AddOnionCommand.cpp b/libretroshare/src/tor/AddOnionCommand.cpp index 393f72541..667dfd57b 100644 --- a/libretroshare/src/tor/AddOnionCommand.cpp +++ b/libretroshare/src/tor/AddOnionCommand.cpp @@ -108,9 +108,9 @@ void AddOnionCommand::onFinished(int statusCode) { TorControlCommand::onFinished(statusCode); if (isSuccessful()) - emit succeeded(); + mSucceeded(); else - emit failed(statusCode); + mFailed(statusCode); } diff --git a/libretroshare/src/tor/AddOnionCommand.h b/libretroshare/src/tor/AddOnionCommand.h index 2edbc44a6..1e8389cde 100644 --- a/libretroshare/src/tor/AddOnionCommand.h +++ b/libretroshare/src/tor/AddOnionCommand.h @@ -34,9 +34,6 @@ #define ADDONIONCOMMAND_H #include "TorControlCommand.h" -#include -#include -#include namespace Tor { @@ -45,11 +42,8 @@ class HiddenService; class AddOnionCommand : public TorControlCommand { - Q_OBJECT - Q_DISABLE_COPY(AddOnionCommand) - - Q_PROPERTY(std::string errorMessage READ errorMessage CONSTANT) - Q_PROPERTY(bool successful READ isSuccessful CONSTANT) + // Q_PROPERTY(std::string errorMessage READ errorMessage CONSTANT) + // Q_PROPERTY(bool successful READ isSuccessful CONSTANT) public: AddOnionCommand(HiddenService *service); @@ -59,14 +53,17 @@ public: std::string errorMessage() const { return m_errorMessage; } bool isSuccessful() const; -signals: - void succeeded(); - void failed(int code); +// signals: + void set_succeeded_callback(const std::function& f) { mSucceeded=f;} + void set_failed_callback(const std::function& f) { mFailed=f;} protected: HiddenService *m_service; std::string m_errorMessage; + std::function mSucceeded; + std::function mFailed; + virtual void onReply(int statusCode, const ByteArray &data); virtual void onFinished(int statusCode); }; diff --git a/libretroshare/src/tor/AuthenticateCommand.h b/libretroshare/src/tor/AuthenticateCommand.h index 86c1b7f56..1d520ea22 100644 --- a/libretroshare/src/tor/AuthenticateCommand.h +++ b/libretroshare/src/tor/AuthenticateCommand.h @@ -30,8 +30,7 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#ifndef AUTHENTICATECOMMAND_H -#define AUTHENTICATECOMMAND_H +#pragma once #include "bytearray.h" #include "TorControlCommand.h" @@ -41,8 +40,6 @@ namespace Tor class AuthenticateCommand : public TorControlCommand { - Q_OBJECT - public: AuthenticateCommand(); @@ -60,5 +57,3 @@ private: }; } - -#endif // AUTHENTICATECOMMAND_H diff --git a/libretroshare/src/tor/GetConfCommand.h b/libretroshare/src/tor/GetConfCommand.h index 387a722c6..b6595fbf3 100644 --- a/libretroshare/src/tor/GetConfCommand.h +++ b/libretroshare/src/tor/GetConfCommand.h @@ -33,19 +33,15 @@ #ifndef GETCONFCOMMAND_H #define GETCONFCOMMAND_H +#include #include "TorControlCommand.h" -#include -#include namespace Tor { class GetConfCommand : public TorControlCommand { - Q_OBJECT - Q_DISABLE_COPY(GetConfCommand) - - Q_PROPERTY(QVariantMap results READ results CONSTANT) + // Q_PROPERTY(QVariantMap results READ results CONSTANT) public: enum Type { diff --git a/libretroshare/src/tor/ProtocolInfoCommand.h b/libretroshare/src/tor/ProtocolInfoCommand.h index 45a31351f..3d4f8baf2 100644 --- a/libretroshare/src/tor/ProtocolInfoCommand.h +++ b/libretroshare/src/tor/ProtocolInfoCommand.h @@ -30,10 +30,10 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#ifndef PROTOCOLINFOCOMMAND_H -#define PROTOCOLINFOCOMMAND_H +#pragma once #include "TorControlCommand.h" +#include "retroshare/rsflags.h" namespace Tor { @@ -42,23 +42,22 @@ class TorControl; class ProtocolInfoCommand : public TorControlCommand { - Q_OBJECT - Q_DISABLE_COPY(ProtocolInfoCommand) - public: - enum AuthMethod + enum { - AuthUnknown = 0, - AuthNull = 0x1, + AuthUnknown = 0x0, + AuthNull = 0x1, 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); ByteArray build(); - AuthMethods authMethods() const { return m_authMethods; } + AuthMethod authMethods() const { return m_authMethods; } std::string torVersion() const { return m_torVersion; } std::string cookieFile() const { return m_cookieFile; } @@ -67,11 +66,9 @@ protected: private: TorControl *manager; - AuthMethods m_authMethods; + AuthMethod m_authMethods; std::string m_torVersion; std::string m_cookieFile; }; } - -#endif // PROTOCOLINFOCOMMAND_H diff --git a/libretroshare/src/tor/SetConfCommand.cpp b/libretroshare/src/tor/SetConfCommand.cpp index 347b1d37a..f4660d2c5 100644 --- a/libretroshare/src/tor/SetConfCommand.cpp +++ b/libretroshare/src/tor/SetConfCommand.cpp @@ -105,8 +105,8 @@ void SetConfCommand::onFinished(int statusCode) { TorControlCommand::onFinished(statusCode); if (isSuccessful()) - emit setConfSucceeded(); + mConfSucceeded(); else - emit setConfFailed(statusCode); + mConfFailed(statusCode); } diff --git a/libretroshare/src/tor/SetConfCommand.h b/libretroshare/src/tor/SetConfCommand.h index 9d608794f..8fb247e84 100644 --- a/libretroshare/src/tor/SetConfCommand.h +++ b/libretroshare/src/tor/SetConfCommand.h @@ -30,24 +30,18 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#ifndef SETCONFCOMMAND_H -#define SETCONFCOMMAND_H +#pragma once +#include #include "TorControlCommand.h" -#include -#include -#include namespace Tor { class SetConfCommand : public TorControlCommand { - Q_OBJECT - Q_DISABLE_COPY(SetConfCommand) - - Q_PROPERTY(QString errorMessage READ errorMessage CONSTANT) - Q_PROPERTY(bool successful READ isSuccessful CONSTANT) + //Q_PROPERTY(QString errorMessage READ errorMessage CONSTANT) + //Q_PROPERTY(bool successful READ isSuccessful CONSTANT) public: SetConfCommand(); @@ -60,18 +54,19 @@ public: std::string errorMessage() const { return m_errorMessage; } bool isSuccessful() const; -signals: - void setConfSucceeded(); - void setConfFailed(int code); +//signals: + void set_ConfSucceeded_callback(const std::function& f) { mConfSucceeded=f; } + void set_ConfFailed_callback (const std::function& f){ mConfFailed=f; } protected: std::string m_errorMessage; bool m_resetMode; + std::function mConfSucceeded; + std::function mConfFailed; + virtual void onReply(int statusCode, const ByteArray &data); virtual void onFinished(int statusCode); }; } - -#endif // SETCONFCOMMAND_H diff --git a/libretroshare/src/tor/TorControl.cpp b/libretroshare/src/tor/TorControl.cpp index 74fe41138..d9aeddc8e 100644 --- a/libretroshare/src/tor/TorControl.cpp +++ b/libretroshare/src/tor/TorControl.cpp @@ -45,14 +45,6 @@ #include "AddOnionCommand.h" #include "StrUtil.h" #include "PendingOperation.h" -#include -#include -#include -//#include -#include -#include -#include -#include Tor::TorControl *torControl = 0; @@ -75,71 +67,72 @@ using namespace Tor; namespace Tor { -class TorControlPrivate : public QObject -{ - Q_OBJECT - -public: - TorControl *q; - - TorControlSocket *socket; - std::string torAddress; - std::string errorMessage; - std::string torVersion; - ByteArray authPassword; - std::string socksAddress; - QList services; - quint16 controlPort, socksPort; - TorControl::Status status; - TorControl::TorStatus torStatus; - std::map bootstrapStatus; - bool hasOwnership; - - TorControlPrivate(TorControl *parent); - - void setStatus(TorControl::Status status); - void setTorStatus(TorControl::TorStatus status); - - void getTorInfo(); - void publishServices(); - -public slots: - void socketConnected(); - void socketDisconnected(); - void socketError(); - - void authenticateReply(); - void protocolInfoReply(); - void getTorInfoReply(); - void setError(const std::string &message); - - void statusEvent(int code, const ByteArray &data); - void updateBootstrap(const std::list &data); -}; +// class TorControlPrivate : public QObject +// { +// Q_OBJECT +// +// public: +// TorControl *q; +// +// TorControlSocket *socket; +// std::string torAddress; +// std::string errorMessage; +// std::string torVersion; +// ByteArray authPassword; +// std::string socksAddress; +// QList services; +// quint16 controlPort, socksPort; +// TorControl::Status status; +// TorControl::TorStatus torStatus; +// std::map bootstrapStatus; +// bool hasOwnership; +// +// TorControlPrivate(TorControl *parent); +// +// void setStatus(TorControl::Status status); +// void setTorStatus(TorControl::TorStatus status); +// +// void getTorInfo(); +// void publishServices(); +// +// public slots: +// void socketConnected(); +// void socketDisconnected(); +// void socketError(); +// +// void authenticateReply(); +// void protocolInfoReply(); +// void getTorInfoReply(); +// void setError(const std::string &message); +// +// void statusEvent(int code, const ByteArray &data); +// void updateBootstrap(const std::list &data); +// }; } -TorControl::TorControl(QObject *parent) - : QObject(parent), d(new TorControlPrivate(this)) +TorControl::TorControl() { + mSocket = new TorControlSocket(this); } -TorControlPrivate::TorControlPrivate(TorControl *parent) - : QObject(parent), q(parent), controlPort(0), socksPort(0), - status(TorControl::NotConnected), torStatus(TorControl::TorUnknown), - hasOwnership(false) -{ - socket = new TorControlSocket(this); - QObject::connect(socket, SIGNAL(connected()), this, SLOT(socketConnected())); - QObject::connect(socket, SIGNAL(disconnected()), this, SLOT(socketDisconnected())); - QObject::connect(socket, SIGNAL(error(QAbstractSocket::SocketError)), this, SLOT(socketError())); - QObject::connect(socket, SIGNAL(error(QString)), this, SLOT(setError(QString))); -} +// TorControlPrivate::TorControlPrivate(TorControl *parent) +// : QObject(parent), q(parent), controlPort(0), socksPort(0), +// status(TorControl::NotConnected), torStatus(TorControl::TorUnknown), +// hasOwnership(false) +// { +// socket = new TorControlSocket(); +// +// // QObject::connect(socket, SIGNAL(connected()), this, SLOT(socketConnected())); +// // QObject::connect(socket, SIGNAL(disconnected()), this, SLOT(socketDisconnected())); +// // QObject::connect(socket, SIGNAL(error(QAbstractSocket::SocketError)), this, SLOT(socketError())); +// // QObject::connect(socket, SIGNAL(error(QString)), this, SLOT(setError(QString))); +// } -QNetworkProxy TorControl::connectionProxy() -{ - return QNetworkProxy(QNetworkProxy::Socks5Proxy, d->socksAddress.toString(), d->socksPort); -} +// QNetworkProxy TorControl::connectionProxy() +// { +// return QNetworkProxy(QNetworkProxy::Socks5Proxy, d->socksAddress.toString(), d->socksPort); +// } 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; - TorControl::Status old = status; - status = n; + TorControl::Status old = mStatus; + mStatus = n; if (old == TorControl::Error) - errorMessage.clear(); + mErrorMessage.clear(); if(rsEvents) { auto ev = std::make_shared(); ev->mTorManagerEventType = RsTorManagerEventCode::TOR_STATUS_CHANGED; - ev->mTorConnectivityStatus = torConnectivityStatus(status); + ev->mTorConnectivityStatus = torConnectivityStatus(mStatus); rsEvents->sendEvent(ev); } #ifdef TO_REMOVE - emit q->statusChanged(status, old); + emit statusChanged(status, old); if (status == TorControl::Connected && old < TorControl::Connected) - emit q->connected(); + emit connected(); else if (status < TorControl::Connected && old >= TorControl::Connected) - emit q->disconnected(); + emit disconnected(); #endif } -void TorControlPrivate::setTorStatus(TorControl::TorStatus n) +void TorControl::setTorStatus(TorControl::TorStatus n) { - if (n == torStatus) + if (n == mTorStatus) return; - TorControl::TorStatus old = torStatus; - torStatus = n; + TorControl::TorStatus old = mTorStatus; + mTorStatus = n; #ifdef TO_REMOVE - emit q->torStatusChanged(torStatus, old); - emit q->connectivityChanged(); + emit torStatusChanged(torStatus, old); + emit connectivityChanged(); #endif if(rsEvents) @@ -211,75 +204,75 @@ void TorControlPrivate::setTorStatus(TorControl::TorStatus n) auto ev = std::make_shared(); ev->mTorManagerEventType = RsTorManagerEventCode::TOR_STATUS_CHANGED; - ev->mTorStatus = ::torStatus(torStatus); + ev->mTorStatus = ::torStatus(mTorStatus); rsEvents->sendEvent(ev); } - if (torStatus == TorControl::TorReady && socksAddress.isNull()) { + if (mTorStatus == TorControl::TorReady && mSocksAddress.empty()) { // Request info again to read the SOCKS port getTorInfo(); } } -void TorControlPrivate::setError(const std::string &message) +void TorControl::setError(const std::string &message) { - errorMessage = message; + mErrorMessage = message; 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 { - return d->status; + return mStatus; } TorControl::TorStatus TorControl::torStatus() const { - return d->torStatus; + return mTorStatus; } std::string TorControl::torVersion() const { - return d->torVersion; + return mTorVersion; } std::string TorControl::errorMessage() const { - return d->errorMessage; + return mErrorMessage; } 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 { - return d->socksPort; + return mSocksPort; } -QList TorControl::hiddenServices() const +std::list TorControl::hiddenServices() const { - return d->services; + return mServices; } std::map TorControl::bootstrapStatus() const { - return d->bootstrapStatus; + return mBootstrapStatus; } void TorControl::setAuthPassword(const ByteArray &password) { - d->authPassword = password; + mAuthPassword = password; } void TorControl::connect(const std::string &address, quint16 port) @@ -290,34 +283,34 @@ void TorControl::connect(const std::string &address, quint16 port) return; } - d->torAddress = address; - d->controlPort = port; - d->setTorStatus(TorUnknown); + mTorAddress = address; + mControlPort = port; + setTorStatus(TorUnknown); //bool b = d->socket->blockSignals(true); - d->socket->fullstop(); + mSocket->fullstop(); //d->socket->blockSignals(b); - d->setStatus(Connecting); - d->socket->connectToHost(address, port); + setStatus(Connecting); + mSocket->connectToHost(address, port); } 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; - d->setStatus(Connecting); - d->socket->connectToHost(d->torAddress, d->controlPort); + setStatus(Connecting); + mSocket->connectToHost(mTorAddress, mControlPort); } -void TorControlPrivate::authenticateReply() +void TorControl::authenticateReply() { AuthenticateCommand *command = qobject_cast(sender()); - Q_ASSERT(command); - Q_ASSERT(status == TorControl::Authenticating); + assert(command); + assert(mStatus == TorControl::Authenticating); if (!command) return; @@ -332,63 +325,69 @@ void TorControlPrivate::authenticateReply() setTorStatus(TorControl::TorUnknown); TorControlCommand *clientEvents = new TorControlCommand; - connect(clientEvents, &TorControlCommand::replyLine, this, &TorControlPrivate::statusEvent); - socket->registerEvent(ByteArray("STATUS_CLIENT"), clientEvents); + clientEvents->set_replyLine_callback([this](int code, const ByteArray &data) + { + statusEvent(code,data); // no async needed here. + }); + + mSocket->registerEvent(ByteArray("STATUS_CLIENT"), clientEvents); getTorInfo(); publishServices(); // XXX Fix old configurations that would store unwanted options in torrc. // This can be removed some suitable amount of time after 1.0.4. - if (hasOwnership) - q->saveConfiguration(); + if (mHasOwnership) + saveConfiguration(); } -void TorControlPrivate::socketConnected() +void TorControl::socketConnected() { - Q_ASSERT(status == TorControl::Connecting); + assert(mStatus == TorControl::Connecting); torCtrlDebug() << "torctrl: Connected socket; querying information" << std::endl; setStatus(TorControl::Authenticating); - ProtocolInfoCommand *command = new ProtocolInfoCommand(q); - connect(command, &TorControlCommand::finished, this, &TorControlPrivate::protocolInfoReply); - socket->sendCommand(command, command->build()); + ProtocolInfoCommand *command = new ProtocolInfoCommand(this); + + 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 */ - torVersion.clear(); - socksAddress.clear(); - socksPort = 0; + mTorVersion.clear(); + mSocksAddress.clear(); + mSocksPort = 0; setTorStatus(TorControl::TorUnknown); /* This emits the disconnected() signal as well */ 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(sender()); + ProtocolInfoCommand *info = dynamic_cast(sender); if (!info) return; - torVersion = info->torVersion(); + mTorVersion = info->torVersion(); - if (status == TorControl::Authenticating) + if (mStatus == TorControl::Authenticating) { AuthenticateCommand *auth = new AuthenticateCommand; - connect(auth, &TorControlCommand::finished, this, &TorControlPrivate::authenticateReply); + connect(auth, &TorControlCommand::finished, this, &TorControl::authenticateReply); ByteArray data; - ProtocolInfoCommand::AuthMethods methods = info->authMethods(); + ProtocolInfoCommand::AuthMethod methods = info->authMethods(); 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. * This is a strange corner case that will likely never happen in a normal configuration, * 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; goto usePasswordAuth; @@ -437,11 +436,11 @@ void TorControlPrivate::protocolInfoReply() return; } } - else if (methods.testFlag(ProtocolInfoCommand::AuthHashedPassword) && !authPassword.empty()) + else if (methods.testFlag(ProtocolInfoCommand::AuthHashedPassword) && !mAuthPassword.empty()) { usePasswordAuth: torCtrlDebug() << "torctrl: Using hashed password authentication" << std::endl; - data = auth->build(authPassword); + data = auth->build(mAuthPassword); } else { @@ -453,16 +452,16 @@ void TorControlPrivate::protocolInfoReply() 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); - connect(command, &TorControlCommand::finished, this, &TorControlPrivate::getTorInfoReply); + connect(command, &TorControlCommand::finished, this, &TorControl::getTorInfoReply); std::list keys{ "status/circuit-established","status/bootstrap-phase" }; @@ -489,13 +488,13 @@ void TorControlPrivate::getTorInfo() #endif 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(sender()); - if (!command || !q->isConnected()) + if (!command || !isConnected()) return; std::list 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, * just use the first address and rely on the user to reconfigure if necessary (not a problem; * their setup is already very customized) */ - if (socksAddress.empty() || address == socket->peerAddress()) { - socksAddress = address; - socksPort = port; - if (address == socket->peerAddress()) + if (mSocksAddress.empty() || address == mSocket->peerAddress()) { + mSocksAddress = address; + mSocksPort = port; + if (address == mSocket->peerAddress()) 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 * listener yet. To handle that situation, we'll try to read the socks address again when TorReady state * is reached. */ - if (!socksAddress.empty()) { - torCtrlDebug() << "torctrl: SOCKS address is " << socksAddress << ":" << socksPort << std::endl; + if (!mSocksAddress.empty()) { + torCtrlDebug() << "torctrl: SOCKS address is " << mSocksAddress << ":" << mSocksPort << std::endl; 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; setTorStatus(TorControl::TorReady); - } else { - setTorStatus(TorControl::TorOffline); } + else + setTorStatus(TorControl::TorOffline); auto bootstrap = command->get("status/bootstrap-phase"); if (!bootstrap.empty()) @@ -546,18 +546,18 @@ void TorControlPrivate::getTorInfoReply() void TorControl::addHiddenService(HiddenService *service) { - if (d->services.contains(service)) + if (std::find(mServices.begin(),mServices.end(),service) != mServices.end()) return; - d->services.append(service); + mServices.push_back(service); } -void TorControlPrivate::publishServices() +void TorControl::publishServices() { torCtrlDebug() << "Publish Services... " ; - Q_ASSERT(q->isConnected()); - if (services.isEmpty()) + assert(isConnected()); + if (mServices.empty()) { std::cerr << "No service regstered!" << std::endl; return; @@ -578,22 +578,23 @@ void TorControlPrivate::publishServices() } #endif - if (q->torVersionAsNewAs("0.2.7")) { - foreach (HiddenService *service, services) { + if (torVersionAsNewAs("0.2.7")) { + for(HiddenService *service: mServices) + { if (service->hostname().empty()) torCtrlDebug() << "torctrl: Creating a new hidden service" << std::endl; else torCtrlDebug() << "torctrl: Publishing hidden service: " << service->hostname() << std::endl; AddOnionCommand *onionCommand = new AddOnionCommand(service); QObject::connect(onionCommand, &AddOnionCommand::succeeded, service, &HiddenService::servicePublished); - socket->sendCommand(onionCommand, onionCommand->build()); + mSocket->sendCommand(onionCommand, onionCommand->build()); } } 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; std::list > torConfig; - foreach (HiddenService *service, services) + for(HiddenService *service: mServices) { if (service->dataPath().empty()) continue; @@ -621,35 +622,35 @@ void TorControlPrivate::publishServices() } if (!torConfig.empty()) - socket->sendCommand(command, command->build(torConfig)); + mSocket->sendCommand(command, command->build(torConfig)); } } void TorControl::shutdown() { 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; } - d->socket->sendCommand(ByteArray("SIGNAL SHUTDOWN\r\n")); + mSocket->sendCommand(ByteArray("SIGNAL SHUTDOWN\r\n")); } void TorControl::shutdownSync() { 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; } shutdown(); - while (d->socket->moretowrite()) + while (mSocket->moretowrite(0)) 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); @@ -670,7 +671,7 @@ void TorControlPrivate::statusEvent(int code, const ByteArray &data) } } -void TorControlPrivate::updateBootstrap(const std::list &data) +void TorControl::updateBootstrap(const std::list &data) { bootstrapStatus.clear(); // WARN or NOTICE @@ -704,7 +705,7 @@ void TorControlPrivate::updateBootstrap(const std::list &data) QObject *TorControl::getConfiguration(const std::string& options) { GetConfCommand *command = new GetConfCommand(GetConfCommand::GetConf); - d->socket->sendCommand(command, command->build(options)); + mSocket->sendCommand(command, command->build(options)); //QQmlEngine::setObjectOwnership(command, QQmlEngine::CppOwnership); return command; @@ -714,7 +715,7 @@ QObject *TorControl::setConfiguration(const std::listsetResetMode(true); - d->socket->sendCommand(command, command->build(options)); + mSocket->sendCommand(command, command->build(options)); //QQmlEngine::setObjectOwnership(command, QQmlEngine::CppOwnership); return command; @@ -818,13 +819,13 @@ private: PendingOperation *TorControl::saveConfiguration() { 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; } SaveConfigOperation *operation = new SaveConfigOperation(this); QObject::connect(operation, &PendingOperation::finished, operation, &QObject::deleteLater); - operation->start(d->socket); + operation->start(mSocket); //QQmlEngine::setObjectOwnership(operation, QQmlEngine::CppOwnership); return operation; @@ -832,13 +833,13 @@ PendingOperation *TorControl::saveConfiguration() bool TorControl::hasOwnership() const { - return d->hasOwnership; + return mHasOwnership; } void TorControl::takeOwnership() { - d->hasOwnership = true; - d->socket->sendCommand(ByteArray("TAKEOWNERSHIP\r\n")); + mHasOwnership = true; + mSocket->sendCommand(ByteArray("TAKEOWNERSHIP\r\n")); // Reset PID-based polling std::list > options; @@ -848,22 +849,29 @@ void TorControl::takeOwnership() bool TorControl::torVersionAsNewAs(const std::string& match) const { - QRegularExpression r(QStringLiteral("[.-]")); - QStringList split = torVersion().split(r); - QStringList matchSplit = match.split(r); + auto split = ByteArray(torVersion()).split(ByteArray(".-")); + auto matchSplit = ByteArray(match).split(ByteArray(".-")); - for (int i = 0; i < matchSplit.size(); i++) { - if (i >= split.size()) + int split_size = split.size(); + int i=0; + const auto& b_split(split.begin()); + + for(const auto& b_matchsplit:matchSplit) + { + if (i >= split_size) return false; - bool ok1 = false, ok2 = false; - int currentVal = split[i].toInt(&ok1); - int matchVal = matchSplit[i].toInt(&ok2); + int currentVal,matchVal; + bool ok1 = RsUtil::StringToInt((*b_split).toString(),currentVal); + bool ok2 = RsUtil::StringToInt(b_matchsplit.toString(),matchVal); + if (!ok1 || !ok2) return false; if (currentVal > matchVal) return true; if (currentVal < matchVal) return false; + + ++i; } // Versions are equal, up to the length of match diff --git a/libretroshare/src/tor/TorControl.h b/libretroshare/src/tor/TorControl.h index 7380e240f..bb21fba95 100644 --- a/libretroshare/src/tor/TorControl.h +++ b/libretroshare/src/tor/TorControl.h @@ -35,10 +35,9 @@ #include -#include -#include #include "PendingOperation.h" #include "bytearray.h" +#include "TorControlSocket.h" class QNetworkProxy; @@ -46,23 +45,23 @@ namespace Tor { class HiddenService; -class TorControlPrivate; +class TorControlSocket; +class TorControlCommand; -class TorControl : public QObject +class TorControl : public TorControlSocketClient { - Q_OBJECT - Q_ENUMS(Status TorStatus) - - // Status of the control connection - Q_PROPERTY(Status status READ status NOTIFY statusChanged) - // Status of Tor (and whether it believes it can connect) - Q_PROPERTY(TorStatus torStatus READ torStatus NOTIFY torStatusChanged) - // Whether it's possible to make a SOCKS connection and connect - Q_PROPERTY(bool hasConnectivity READ hasConnectivity NOTIFY connectivityChanged) - Q_PROPERTY(QString torVersion READ torVersion NOTIFY connected) - Q_PROPERTY(QString errorMessage READ errorMessage NOTIFY statusChanged) - Q_PROPERTY(QVariantMap bootstrapStatus READ bootstrapStatus NOTIFY bootstrapStatusChanged) - Q_PROPERTY(bool hasOwnership READ hasOwnership NOTIFY hasOwnershipChanged) +// Q_ENUMS(Status TorStatus) +// +// // Status of the control connection +// Q_PROPERTY(Status status READ status NOTIFY statusChanged) +// // Status of Tor (and whether it believes it can connect) +// Q_PROPERTY(TorStatus torStatus READ torStatus NOTIFY torStatusChanged) +// // Whether it's possible to make a SOCKS connection and connect +// Q_PROPERTY(bool hasConnectivity READ hasConnectivity NOTIFY connectivityChanged) +// Q_PROPERTY(QString torVersion READ torVersion NOTIFY connected) +// Q_PROPERTY(QString errorMessage READ errorMessage NOTIFY statusChanged) +// Q_PROPERTY(QVariantMap bootstrapStatus READ bootstrapStatus NOTIFY bootstrapStatusChanged) +// Q_PROPERTY(bool hasOwnership READ hasOwnership NOTIFY hasOwnershipChanged) public: enum Status @@ -81,8 +80,7 @@ public: TorReady = 0x02 }; - - explicit TorControl(QObject *parent = 0); + explicit TorControl(); /* Information */ Status status() const; @@ -92,7 +90,7 @@ public: std::string errorMessage() const; bool hasConnectivity() const; - QHostAddress socksAddress() const; + std::string socksAddress() const; quint16 socksPort() const; QNetworkProxy connectionProxy(); @@ -109,24 +107,26 @@ public: void takeOwnership(); /* Hidden Services */ - QList hiddenServices() const; + std::list hiddenServices() const; void addHiddenService(HiddenService *service); std::map bootstrapStatus() const; - Q_INVOKABLE QObject *getConfiguration(const std::string &options); - Q_INVOKABLE QObject *setConfiguration(const std::list > &options); - Q_INVOKABLE PendingOperation *saveConfiguration(); + /*Q_INVOKABLE*/ QObject *getConfiguration(const std::string &options); + /*Q_INVOKABLE*/ QObject *setConfiguration(const std::list > &options); + /*Q_INVOKABLE*/ PendingOperation *saveConfiguration(); -signals: - void statusChanged(int newStatus, int oldStatus); - void torStatusChanged(int newStatus, int oldStatus); - void connected(); - void disconnected(); - void connectivityChanged(); - void bootstrapStatusChanged(); - void hasOwnershipChanged(); +//signals: +// void statusChanged(int newStatus, int oldStatus); +// void torStatusChanged(int newStatus, int oldStatus); +// void connected(); +// void disconnected(); +// void connectivityChanged(); +// void bootstrapStatusChanged(); +// void hasOwnershipChanged(); -public slots: + virtual void socketError(const std::string &s) override; + +//public slots: /* Instruct Tor to shutdown */ void shutdown(); /* Call shutdown(), and wait synchronously for the command to be written */ @@ -135,7 +135,31 @@ public slots: void reconnect(); private: - TorControlPrivate *d; + TorControlSocket *mSocket; + std::string mTorAddress; + std::string mErrorMessage; + std::string mTorVersion; + ByteArray mAuthPassword; + std::string mSocksAddress; + std::list mServices; + quint16 mControlPort, mSocksPort; + TorControl::Status mStatus; + TorControl::TorStatus mTorStatus; + std::map 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& data); + void setError(const std::string& message); + void publishServices(); + void protocolInfoReply(TorControlCommand *sender); + void socketDisconnected(); + void socketConnected(); + void authenticateReply(); }; } diff --git a/libretroshare/src/tor/TorControlCommand.cpp b/libretroshare/src/tor/TorControlCommand.cpp index 702392ac0..67e02169a 100644 --- a/libretroshare/src/tor/TorControlCommand.cpp +++ b/libretroshare/src/tor/TorControlCommand.cpp @@ -31,7 +31,6 @@ */ #include "TorControlCommand.h" -#include using namespace Tor; @@ -42,22 +41,23 @@ TorControlCommand::TorControlCommand() void TorControlCommand::onReply(int statusCode, const ByteArray &data) { - emit replyLine(statusCode, data); + //emit replyLine(statusCode, data); + mReplyLine(statusCode, data); } void TorControlCommand::onFinished(int statusCode) { m_finalStatus = statusCode; - emit finished(); + //emit finished(); + mFinished(this); } void TorControlCommand::onDataLine(const ByteArray &data) { - Q_UNUSED(data); } void TorControlCommand::onDataFinished() { - qWarning() << "torctrl: Unexpected data response for command"; + RsWarn() << "torctrl: Unexpected data response for command"; } diff --git a/libretroshare/src/tor/TorControlCommand.h b/libretroshare/src/tor/TorControlCommand.h index a33c12ffa..6e0a2a176 100644 --- a/libretroshare/src/tor/TorControlCommand.h +++ b/libretroshare/src/tor/TorControlCommand.h @@ -30,33 +30,31 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#ifndef TORCONTROLCOMMAND_H -#define TORCONTROLCOMMAND_H - -#include +#pragma once +#include #include "bytearray.h" namespace Tor { -class TorControlCommand : public QObject -{ - Q_OBJECT - Q_DISABLE_COPY(TorControlCommand) +class ProtocolInfoCommand; +class TorControlCommand +{ friend class TorControlSocket; public: TorControlCommand(); + virtual ~TorControlCommand()=default; int statusCode() const { return m_finalStatus; } -signals: - void replyLine(int statusCode, const ByteArray &data); - void finished(); +//signals: + void set_replyLine_callback( const std::function& f) { mReplyLine=f ; } + void set_finished_callback( const std::function& f) { mFinished=f; }; -protected: +public: virtual void onReply(int statusCode, const ByteArray &data); virtual void onFinished(int statusCode); virtual void onDataLine(const ByteArray &data); @@ -64,8 +62,13 @@ protected: private: int m_finalStatus; + + // Disable copy + TorControlCommand(const TorControlCommand&){} + TorControlCommand& operator=(const TorControlCommand&){ return *this; } + + std::function mReplyLine; + std::function mFinished; }; } - -#endif // TORCONTROLCOMMAND_H diff --git a/libretroshare/src/tor/TorControlSocket.cpp b/libretroshare/src/tor/TorControlSocket.cpp index a3d465acc..849ca4926 100644 --- a/libretroshare/src/tor/TorControlSocket.cpp +++ b/libretroshare/src/tor/TorControlSocket.cpp @@ -37,8 +37,8 @@ using namespace Tor; -TorControlSocket::TorControlSocket(const std::string& tcp_address,uint16_t tcp_port) - : RsThreadedTcpSocket(tcp_address,tcp_port),currentCommand(0), inDataReply(false) +TorControlSocket::TorControlSocket(TorControlSocketClient *client) + : RsThreadedTcpSocket(),currentCommand(0), inDataReply(false),mClient(client) { //connect(this, SIGNAL(readyRead()), this, SLOT(process())); //connect(this, SIGNAL(disconnected()), this, SLOT(clear())); @@ -98,7 +98,7 @@ void TorControlSocket::clear() void TorControlSocket::setError(const std::string &message) { m_errorMessage = message; - emit error(message); + mClient->socketError(message); abort(); } @@ -202,7 +202,7 @@ void TorControlSocket::process() commandQueue.pop_front(); if (command) { command->onFinished(statusCode); - command->deleteLater(); + delete command; // should we "delete later" ? } } } diff --git a/libretroshare/src/tor/TorControlSocket.h b/libretroshare/src/tor/TorControlSocket.h index a62feedf2..979d85fa5 100644 --- a/libretroshare/src/tor/TorControlSocket.h +++ b/libretroshare/src/tor/TorControlSocket.h @@ -40,12 +40,20 @@ namespace Tor class TorControlCommand; +class TorControlSocketClient +{ +public: + virtual void socketError(const std::string& s) = 0; +}; + class TorControlSocket : public RsThreadedTcpSocket { public: - explicit TorControlSocket(const std::string& tcp_address,uint16_t tcp_port); + explicit TorControlSocket(TorControlSocketClient *client); virtual ~TorControlSocket(); + void connect(const std::string& tcp_address,uint16_t tcp_port); + std::string errorMessage() const { return m_errorMessage; } void connectToHost(const std::string& tcp_address,uint16_t tcp_port); @@ -62,7 +70,9 @@ public: std::string peerAddress() const; //signals: - void error(const std::string& message); +// void error(const std::string& message); + + const std::string& errorString() const { return m_errorMessage ;} //private slots: void process(); @@ -74,6 +84,7 @@ private: std::string m_errorMessage; TorControlCommand *currentCommand; bool inDataReply; + TorControlSocketClient *mClient; void setError(const std::string& message); }; diff --git a/libretroshare/src/tor/TorManager.cpp b/libretroshare/src/tor/TorManager.cpp index a1aeb4bde..ec198beb6 100644 --- a/libretroshare/src/tor/TorManager.cpp +++ b/libretroshare/src/tor/TorManager.cpp @@ -211,23 +211,22 @@ bool TorManager::setupHiddenService() // 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 + 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)) - { - // XXX error case - std::cerr << " Failed to open incoming socket" << std::endl; - return false; - } +// if (!QTcpServer().listen(address, port)) +// { +// // XXX error case +// std::cerr << " Failed to open incoming socket" << std::endl; +// return false; +// } std::cerr << " OK - Adding hidden service to TorControl." << std::endl; //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); return true ; @@ -408,7 +407,7 @@ bool TorManager::start() 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_port = control()->socksPort(); @@ -416,7 +415,7 @@ bool TorManager::getProxyServerInfo(QHostAddress& proxy_server_adress,uint16_t& 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 hidden_services = control()->hiddenServices(); @@ -444,7 +443,7 @@ bool TorManager::getHiddenServiceInfo(std::string& service_id,std::string& servi 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; if (state == TorProcess::Ready) { @@ -605,14 +604,14 @@ bool RsTor::getHiddenServiceInfo(std::string& service_id, { std::string sid; std::string soa; - QHostAddress sta; + std::string sta; if(!instance()->getHiddenServiceInfo(sid,soa,service_port,sta,target_port)) return false; service_id = sid; service_onion_address = soa; - service_target_address = sta.toString().toStdString(); + service_target_address = sta; return true; } @@ -624,7 +623,7 @@ std::list RsTor::logMessages() std::string RsTor::socksAddress() { - return instance()->control()->socksAddress().toString().toStdString(); + return instance()->control()->socksAddress(); } uint16_t RsTor::socksPort() { @@ -700,10 +699,10 @@ std::string RsTor::errorMessage() void RsTor::getProxyServerInfo(std::string& server_address, uint16_t& server_port) { - QHostAddress qserver_address; + std::string qserver_address; instance()->getProxyServerInfo(qserver_address,server_port); - server_address = qserver_address.toString().toStdString(); + server_address = qserver_address; } bool RsTor::start() diff --git a/libretroshare/src/tor/TorManager.h b/libretroshare/src/tor/TorManager.h index c396c2e5b..100d55779 100644 --- a/libretroshare/src/tor/TorManager.h +++ b/libretroshare/src/tor/TorManager.h @@ -38,8 +38,6 @@ #include "retroshare/rstor.h" #include "HiddenService.h" -#include - namespace Tor { @@ -86,8 +84,8 @@ public: bool hasError() 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 getProxyServerInfo(QHostAddress& proxy_server_adress,uint16_t& proxy_server_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(std::string &proxy_server_adress, uint16_t& proxy_server_port); //public slots: bool start(); diff --git a/libretroshare/src/tor/TorProcess.cpp b/libretroshare/src/tor/TorProcess.cpp index 907b9b78b..77f561063 100644 --- a/libretroshare/src/tor/TorProcess.cpp +++ b/libretroshare/src/tor/TorProcess.cpp @@ -333,12 +333,12 @@ ByteArray TorProcess::controlPassword() return mControlPassword; } -QHostAddress TorProcess::controlHost() +std::string TorProcess::controlHost() { return mControlHost; } -quint16 TorProcess::controlPort() +unsigned short TorProcess::controlPort() { return mControlPort; } diff --git a/libretroshare/src/tor/TorProcess.h b/libretroshare/src/tor/TorProcess.h index 68649aa90..c48b758b8 100644 --- a/libretroshare/src/tor/TorProcess.h +++ b/libretroshare/src/tor/TorProcess.h @@ -33,8 +33,6 @@ #ifndef TORPROCESS_H #define TORPROCESS_H -#include - #include "bytearray.h" #include "util/rsthreads.h" @@ -89,8 +87,8 @@ public: State state() const; std::string errorMessage() const; - QHostAddress controlHost(); - quint16 controlPort(); + std::string controlHost(); + unsigned short controlPort(); ByteArray controlPassword(); //signals: @@ -116,8 +114,8 @@ private: std::list mExtraSettings; TorProcess::State mState; std::string mErrorMessage; - QHostAddress mControlHost; - quint16 mControlPort; + std::string mControlHost; + unsigned short mControlPort; ByteArray mControlPassword; int controlPortAttempts; @@ -127,7 +125,7 @@ private: bool ensureFilesExist(); pid_t mTorProcessId; -public slots: +//public slots: void processStarted(); void processFinished(); void processError(std::string error); diff --git a/libretroshare/src/tor/bytearray.h b/libretroshare/src/tor/bytearray.h index 44727bce5..b237a333a 100644 --- a/libretroshare/src/tor/bytearray.h +++ b/libretroshare/src/tor/bytearray.h @@ -4,6 +4,7 @@ #include #include +#include #include #include @@ -42,7 +43,7 @@ public: { std::istringstream is(toString().c_str()); - int res = 0; + int res = -1; is >> res ; return res; @@ -103,6 +104,8 @@ public: return res; } + // Splits the byte array using sep as separator. + std::list split(unsigned char sep) { std::list res; @@ -120,6 +123,25 @@ public: return res; } + // Splits the byte array using any of the characters in sep as separators. + + std::list split(const ByteArray& sep) + { + std::list res; + ByteArray current_block; + + for(uint32_t i=0;i Date: Mon, 6 Dec 2021 22:08:56 +0100 Subject: [PATCH 22/65] finished removing latest Qt bits --- libretroshare/src/tor/AddOnionCommand.cpp | 13 +-- libretroshare/src/tor/AddOnionCommand.h | 6 +- libretroshare/src/tor/CryptoKey.h | 9 +- libretroshare/src/tor/HiddenService.cpp | 2 +- libretroshare/src/tor/HiddenService.h | 18 ++-- libretroshare/src/tor/PendingOperation.cpp | 16 ++-- libretroshare/src/tor/PendingOperation.h | 44 ++++----- libretroshare/src/tor/ProtocolInfoCommand.cpp | 2 +- libretroshare/src/tor/TorControl.cpp | 92 +++++++++---------- libretroshare/src/tor/TorControl.h | 24 +++-- libretroshare/src/tor/TorManager.cpp | 37 +++----- libretroshare/src/tor/bytearray.h | 1 + 12 files changed, 125 insertions(+), 139 deletions(-) diff --git a/libretroshare/src/tor/AddOnionCommand.cpp b/libretroshare/src/tor/AddOnionCommand.cpp index 667dfd57b..8b0f488fa 100644 --- a/libretroshare/src/tor/AddOnionCommand.cpp +++ b/libretroshare/src/tor/AddOnionCommand.cpp @@ -40,7 +40,7 @@ using namespace Tor; AddOnionCommand::AddOnionCommand(HiddenService *service) : m_service(service) { - Q_ASSERT(m_service); + assert(m_service); } bool AddOnionCommand::isSuccessful() const @@ -61,13 +61,14 @@ ByteArray AddOnionCommand::build() out += " NEW:BEST"; // this is v3, but without control of key type. Generates a RSA1024 key on older Tor versions. } - foreach (const HiddenService::Target &target, m_service->targets()) { + for(const HiddenService::Target& target: m_service->targets()) + { out += " Port="; - out += QByteArray::number(target.servicePort); + out += RsUtil::NumberToString(target.servicePort); out += ","; out += target.targetAddress; out += ":"; - out += QByteArray::number(target.targetPort); + out += RsUtil::NumberToString(target.targetPort); } out.append("\r\n"); @@ -82,8 +83,8 @@ void AddOnionCommand::onReply(int statusCode, const ByteArray &data) return; } - const QByteArray keyPrefix("PrivateKey="); - const QByteArray sidPrefix("ServiceID="); + const ByteArray keyPrefix("PrivateKey="); + const ByteArray sidPrefix("ServiceID="); if(data.startsWith("ServiceID=")){ ByteArray service_id = data.mid(sidPrefix.size()); diff --git a/libretroshare/src/tor/AddOnionCommand.h b/libretroshare/src/tor/AddOnionCommand.h index 1e8389cde..fddab89af 100644 --- a/libretroshare/src/tor/AddOnionCommand.h +++ b/libretroshare/src/tor/AddOnionCommand.h @@ -30,8 +30,7 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#ifndef ADDONIONCOMMAND_H -#define ADDONIONCOMMAND_H +#pragma once #include "TorControlCommand.h" @@ -69,6 +68,3 @@ protected: }; } - -#endif // ADDONIONCOMMAND_H - diff --git a/libretroshare/src/tor/CryptoKey.h b/libretroshare/src/tor/CryptoKey.h index 7cb1d6562..ab6fb320f 100644 --- a/libretroshare/src/tor/CryptoKey.h +++ b/libretroshare/src/tor/CryptoKey.h @@ -30,12 +30,7 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#ifndef CRYPTOKEY_H -#define CRYPTOKEY_H - -#include -#include -#include +#pragma once #include "bytearray.h" @@ -67,5 +62,3 @@ private: }; ByteArray torControlHashedPassword(const ByteArray &password); - -#endif // CRYPTOKEY_H diff --git a/libretroshare/src/tor/HiddenService.cpp b/libretroshare/src/tor/HiddenService.cpp index cb9adfa8a..cb991828a 100644 --- a/libretroshare/src/tor/HiddenService.cpp +++ b/libretroshare/src/tor/HiddenService.cpp @@ -83,7 +83,7 @@ void HiddenService::addTarget(const Target &target) m_targets.push_back(target); } -void HiddenService::addTarget(quint16 servicePort, std::string targetAddress, quint16 targetPort) +void HiddenService::addTarget(uint16_t servicePort, std::string targetAddress, uint16_t targetPort) { Target t = { targetAddress, servicePort, targetPort }; m_targets.push_back(t); diff --git a/libretroshare/src/tor/HiddenService.h b/libretroshare/src/tor/HiddenService.h index 2b69915f6..ae77d51ed 100644 --- a/libretroshare/src/tor/HiddenService.h +++ b/libretroshare/src/tor/HiddenService.h @@ -33,7 +33,6 @@ #ifndef HIDDENSERVICE_H #define HIDDENSERVICE_H -#include #include "CryptoKey.h" #include "bytearray.h" @@ -52,18 +51,15 @@ public: virtual void hiddenServiceHostnameChanged() =0; }; -class HiddenService : public QObject +class HiddenService { - Q_OBJECT - Q_DISABLE_COPY(HiddenService) - - friend class TorControlPrivate; + friend class TorControl; public: struct Target { std::string targetAddress; - quint16 servicePort, targetPort; + uint16_t servicePort, targetPort; }; enum Status @@ -89,9 +85,9 @@ public: const std::list &targets() const { return m_targets; } void addTarget(const Target &target); - void addTarget(quint16 servicePort, std::string targetAddress, quint16 targetPort); + void addTarget(uint16_t servicePort, std::string targetAddress, uint16_t targetPort); -private slots: +//private slots: void servicePublished(); private: @@ -106,6 +102,10 @@ private: void setStatus(Status newStatus); HiddenServiceClient *m_client; + + // make the object non copyable + HiddenService(const HiddenService& s) {} + HiddenService& operator=(const HiddenService& s) { return *this ; } }; } diff --git a/libretroshare/src/tor/PendingOperation.cpp b/libretroshare/src/tor/PendingOperation.cpp index adc4792a5..e22f63852 100644 --- a/libretroshare/src/tor/PendingOperation.cpp +++ b/libretroshare/src/tor/PendingOperation.cpp @@ -30,10 +30,11 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ +#include #include "PendingOperation.h" -PendingOperation::PendingOperation(QObject *parent) - : QObject(parent), m_finished(false) +PendingOperation::PendingOperation() + : m_finished(false) { } @@ -65,20 +66,21 @@ void PendingOperation::finishWithError(const std::string &message) if (!m_finished) { m_finished = true; - emit finished(); - emit error(m_errorMessage); + + finished_callback(); + error_callback(m_errorMessage); } } void PendingOperation::finishWithSuccess() { - Q_ASSERT(m_errorMessage.empty()); + assert(m_errorMessage.empty()); if (!m_finished) { m_finished = true; - emit finished(); + finished_callback(); if (isSuccess()) - emit success(); + success_callback(); } } diff --git a/libretroshare/src/tor/PendingOperation.h b/libretroshare/src/tor/PendingOperation.h index e3a1716df..5965bfd26 100644 --- a/libretroshare/src/tor/PendingOperation.h +++ b/libretroshare/src/tor/PendingOperation.h @@ -30,10 +30,9 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#ifndef PENDINGOPERATION_H -#define PENDINGOPERATION_H +#pragma once -#include +#include /* Represents an asynchronous operation for reporting status * @@ -48,40 +47,41 @@ * PendingOperation will emit finished() and one of success() or * error() when completed. */ -class PendingOperation : public QObject +class PendingOperation { - Q_OBJECT - - Q_PROPERTY(bool isFinished READ isFinished NOTIFY finished FINAL) - Q_PROPERTY(bool isSuccess READ isSuccess NOTIFY success FINAL) - Q_PROPERTY(bool isError READ isError NOTIFY error FINAL) - Q_PROPERTY(std::string errorMessage READ errorMessage NOTIFY finished FINAL) +// Q_PROPERTY(bool isFinished READ isFinished NOTIFY finished FINAL) +// Q_PROPERTY(bool isSuccess READ isSuccess NOTIFY success FINAL) +// Q_PROPERTY(bool isError READ isError NOTIFY error FINAL) +// Q_PROPERTY(std::string errorMessage READ errorMessage NOTIFY finished FINAL) public: - PendingOperation(QObject *parent = 0); + PendingOperation(); bool isFinished() const; bool isSuccess() const; bool isError() const; std::string errorMessage() const; -signals: - // Always emitted once when finished, regardless of status - void finished(); +// signals: +// // Always emitted once when finished, regardless of status +// void finished(); +// +// // One of error() or success() is emitted once +// void error(const std::string &errorMessage); +// void success(); - // One of error() or success() is emitted once - void error(const std::string &errorMessage); - void success(); - -protected slots: +//protected slots: void finishWithError(const std::string &errorMessage); void finishWithSuccess(); + void set_finished_callback(const std::function& f) { finished_callback = f; } private: bool m_finished; std::string m_errorMessage; + + std::function finished_callback; + std::function success_callback; + std::function error_callback; + }; -Q_DECLARE_METATYPE(PendingOperation*) - -#endif diff --git a/libretroshare/src/tor/ProtocolInfoCommand.cpp b/libretroshare/src/tor/ProtocolInfoCommand.cpp index b1f773d96..867541e56 100644 --- a/libretroshare/src/tor/ProtocolInfoCommand.cpp +++ b/libretroshare/src/tor/ProtocolInfoCommand.cpp @@ -56,7 +56,7 @@ void ProtocolInfoCommand::onReply(int statusCode, const ByteArray &data) { std::list tokens = splitQuotedStrings(data.mid(5), ' '); - foreach (ByteArray token, tokens) + for(ByteArray token: tokens) { if (token.startsWith("METHODS=")) { diff --git a/libretroshare/src/tor/TorControl.cpp b/libretroshare/src/tor/TorControl.cpp index d9aeddc8e..1051a0abe 100644 --- a/libretroshare/src/tor/TorControl.cpp +++ b/libretroshare/src/tor/TorControl.cpp @@ -81,7 +81,7 @@ namespace Tor { // ByteArray authPassword; // std::string socksAddress; // QList services; -// quint16 controlPort, socksPort; +// uint16_t controlPort, socksPort; // TorControl::Status status; // TorControl::TorStatus torStatus; // std::map bootstrapStatus; @@ -177,14 +177,12 @@ void TorControl::setStatus(TorControl::Status n) rsEvents->sendEvent(ev); } -#ifdef TO_REMOVE - emit statusChanged(status, old); + mStatusChanged_callback(mStatus, old); - if (status == TorControl::Connected && old < TorControl::Connected) - emit connected(); - else if (status < TorControl::Connected && old >= TorControl::Connected) - emit disconnected(); -#endif + if (mStatus == TorControl::Connected && old < TorControl::Connected) + socketConnected();//mConnected_callback(); + else if (mStatus < TorControl::Connected && old >= TorControl::Connected) + socketDisconnected();//mDisconnected_callback(); } void TorControl::setTorStatus(TorControl::TorStatus n) @@ -194,10 +192,6 @@ void TorControl::setTorStatus(TorControl::TorStatus n) TorControl::TorStatus old = mTorStatus; mTorStatus = n; -#ifdef TO_REMOVE - emit torStatusChanged(torStatus, old); - emit connectivityChanged(); -#endif if(rsEvents) { @@ -255,7 +249,7 @@ std::string TorControl::socksAddress() const return mSocksAddress; } -quint16 TorControl::socksPort() const +uint16_t TorControl::socksPort() const { return mSocksPort; } @@ -275,7 +269,7 @@ void TorControl::setAuthPassword(const ByteArray &password) mAuthPassword = password; } -void TorControl::connect(const std::string &address, quint16 port) +void TorControl::connect(const std::string &address, uint16_t port) { if (status() > Connecting) { @@ -306,9 +300,9 @@ void TorControl::reconnect() mSocket->connectToHost(mTorAddress, mControlPort); } -void TorControl::authenticateReply() +void TorControl::authenticateReply(TorControlCommand *sender) { - AuthenticateCommand *command = qobject_cast(sender()); + AuthenticateCommand *command = dynamic_cast(sender); assert(command); assert(mStatus == TorControl::Authenticating); if (!command) @@ -384,17 +378,18 @@ void TorControl::protocolInfoReply(TorControlCommand *sender) if (mStatus == TorControl::Authenticating) { AuthenticateCommand *auth = new AuthenticateCommand; - connect(auth, &TorControlCommand::finished, this, &TorControl::authenticateReply); + //connect(auth, &TorControlCommand::finished, this, &TorControl::authenticateReply); + auth->set_finished_callback( [this](TorControlCommand *sender) { authenticateReply(sender); }); ByteArray data; ProtocolInfoCommand::AuthMethod methods = info->authMethods(); - if (methods.testFlag(ProtocolInfoCommand::AuthNull)) + if(methods & ProtocolInfoCommand::AuthNull) { torCtrlDebug() << "torctrl: Using null authentication" << std::endl; data = auth->build(); } - else if (methods.testFlag(ProtocolInfoCommand::AuthCookie) && !info->cookieFile().empty()) + else if ((methods & ProtocolInfoCommand::AuthCookie) && !info->cookieFile().empty()) { std::string cookieFile = info->cookieFile(); std::string cookieError; @@ -425,7 +420,7 @@ void TorControl::protocolInfoReply(TorControlCommand *sender) /* 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, * but it has happened. */ - if (methods.testFlag(ProtocolInfoCommand::AuthHashedPassword) && !mAuthPassword.empty()) + if ((methods & ProtocolInfoCommand::AuthHashedPassword) && !mAuthPassword.empty()) { torCtrlDebug() << "torctrl: Unable to read authentication cookie file:" << cookieError << std::endl; goto usePasswordAuth; @@ -436,7 +431,7 @@ void TorControl::protocolInfoReply(TorControlCommand *sender) return; } } - else if (methods.testFlag(ProtocolInfoCommand::AuthHashedPassword) && !mAuthPassword.empty()) + else if ((methods & ProtocolInfoCommand::AuthHashedPassword) && !mAuthPassword.empty()) { usePasswordAuth: torCtrlDebug() << "torctrl: Using hashed password authentication" << std::endl; @@ -444,7 +439,7 @@ void TorControl::protocolInfoReply(TorControlCommand *sender) } else { - if (methods.testFlag(ProtocolInfoCommand::AuthHashedPassword)) + if (methods & ProtocolInfoCommand::AuthHashedPassword) setError("Tor requires a control password to connect, but no password is configured."); else setError("Tor is not configured to accept any supported authentication methods."); @@ -461,7 +456,8 @@ void TorControl::getTorInfo() assert(isConnected()); GetConfCommand *command = new GetConfCommand(GetConfCommand::GetInfo); - connect(command, &TorControlCommand::finished, this, &TorControl::getTorInfoReply); + //connect(command, &TorControlCommand::finished, this, &TorControl::getTorInfoReply); + command->set_finished_callback( [this](TorControlCommand *sender) { getTorInfoReply(sender); }); std::list keys{ "status/circuit-established","status/bootstrap-phase" }; @@ -469,7 +465,7 @@ void TorControl::getTorInfo() /* If these are set in the config, they override the automatic behavior. */ SettingsObject settings("tor"); QHostAddress forceAddress(settings.read("socksAddress").toString()); - quint16 port = (quint16)settings.read("socksPort").toInt(); + uint16_t port = (uint16_t)settings.read("socksPort").toInt(); if (!forceAddress.isNull() && port) { torCtrlDebug() << "torctrl: Using manually specified SOCKS connection settings"; @@ -491,9 +487,9 @@ void TorControl::getTorInfo() mSocket->sendCommand(command, command->build(keys)); } -void TorControl::getTorInfoReply() +void TorControl::getTorInfoReply(TorControlCommand *sender) { - GetConfCommand *command = qobject_cast(sender()); + GetConfCommand *command = dynamic_cast(sender); if (!command || !isConnected()) return; @@ -503,7 +499,7 @@ void TorControl::getTorInfoReply() ByteArray value = unquotedString(add); int sepp = value.indexOf(':'); std::string address(value.mid(0, sepp).toString()); - quint16 port = (quint16)value.mid(sepp+1).toInt(); + uint16_t port = (uint16_t)value.mid(sepp+1).toInt(); /* 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; @@ -586,7 +582,8 @@ void TorControl::publishServices() else torCtrlDebug() << "torctrl: Publishing hidden service: " << service->hostname() << std::endl; AddOnionCommand *onionCommand = new AddOnionCommand(service); - QObject::connect(onionCommand, &AddOnionCommand::succeeded, service, &HiddenService::servicePublished); + //protocolInfoReplyQObject::connect(onionCommand, &AddOnionCommand::succeeded, service, &HiddenService::servicePublished); + onionCommand->set_succeeded_callback( [service]() { service->servicePublished(); }); mSocket->sendCommand(onionCommand, onionCommand->build()); } } else { @@ -618,7 +615,8 @@ void TorControl::publishServices() torConfig.push_back(std::make_pair("HiddenServicePort", target)); } - QObject::connect(command, &SetConfCommand::setConfSucceeded, service, &HiddenService::servicePublished); + command->set_ConfSucceeded_callback( [service]() { service->servicePublished(); }); + //QObject::connect(command, &SetConfCommand::setConfSucceeded, service, &HiddenService::servicePublished); } if (!torConfig.empty()) @@ -650,10 +648,8 @@ void TorControl::shutdownSync() mSocket->close(); } -void TorControl::statusEvent(int code, const ByteArray &data) +void TorControl::statusEvent(int /* code */, const ByteArray &data) { - Q_UNUSED(code); - std::list tokens = splitQuotedStrings(data.trimmed(), ' '); if (tokens.size() < 3) return; @@ -673,9 +669,9 @@ void TorControl::statusEvent(int code, const ByteArray &data) void TorControl::updateBootstrap(const std::list &data) { - bootstrapStatus.clear(); + mBootstrapStatus.clear(); // WARN or NOTICE - bootstrapStatus["severity"] = (*data.begin()).toString(); + mBootstrapStatus["severity"] = (*data.begin()).toString(); auto dat = data.begin(); ++dat; @@ -688,7 +684,7 @@ void TorControl::updateBootstrap(const std::list &data) if (equals >= 0) value = unquotedString((*dat).mid(equals + 1)); - bootstrapStatus[key.toLower().toString()] = value.toString(); + mBootstrapStatus[key.toLower().toString()] = value.toString(); } //torCtrlDebug() << bootstrapStatus << std::endl; @@ -702,7 +698,7 @@ void TorControl::updateBootstrap(const std::list &data) } } -QObject *TorControl::getConfiguration(const std::string& options) +TorControlCommand *TorControl::getConfiguration(const std::string& options) { GetConfCommand *command = new GetConfCommand(GetConfCommand::GetConf); mSocket->sendCommand(command, command->build(options)); @@ -711,7 +707,7 @@ QObject *TorControl::getConfiguration(const std::string& options) return command; } -QObject *TorControl::setConfiguration(const std::list >& options) +TorControlCommand *TorControl::setConfiguration(const std::list >& options) { SetConfCommand *command = new SetConfCommand; command->setResetMode(true); @@ -725,27 +721,25 @@ namespace Tor { class SaveConfigOperation : public PendingOperation { - Q_OBJECT - public: - SaveConfigOperation(QObject *parent) - : PendingOperation(parent), command(0) + SaveConfigOperation() + : PendingOperation(), command(0) { } void start(TorControlSocket *socket) { - Q_ASSERT(!command); + assert(!command); command = new GetConfCommand(GetConfCommand::GetInfo); - QObject::connect(command, &TorControlCommand::finished, this, &SaveConfigOperation::configTextReply); + //QObject::connect(command, &TorControlCommand::finished, this, &SaveConfigOperation::configTextReply); + command->set_finished_callback([this](TorControlCommand *sender){ configTextReply(sender); }); socket->sendCommand(command, command->build(std::list { "config-text" , "config-file" } )); } -private slots: - void configTextReply() + void configTextReply(TorControlCommand * /*sender*/) { - Q_ASSERT(command); + assert(command); if (!command) return; @@ -823,8 +817,10 @@ PendingOperation *TorControl::saveConfiguration() return 0; } - SaveConfigOperation *operation = new SaveConfigOperation(this); - QObject::connect(operation, &PendingOperation::finished, operation, &QObject::deleteLater); + SaveConfigOperation *operation = new SaveConfigOperation(); + + //QObject::connect(operation, &PendingOperation::finished, operation, &QObject::deleteLater); + operation->set_finished_callback( [operation]() { delete operation; }); operation->start(mSocket); //QQmlEngine::setObjectOwnership(operation, QQmlEngine::CppOwnership); diff --git a/libretroshare/src/tor/TorControl.h b/libretroshare/src/tor/TorControl.h index bb21fba95..5ffc1174f 100644 --- a/libretroshare/src/tor/TorControl.h +++ b/libretroshare/src/tor/TorControl.h @@ -39,7 +39,6 @@ #include "bytearray.h" #include "TorControlSocket.h" -class QNetworkProxy; namespace Tor { @@ -91,15 +90,14 @@ public: bool hasConnectivity() const; std::string socksAddress() const; - quint16 socksPort() const; - QNetworkProxy connectionProxy(); + uint16_t socksPort() const; /* Authentication */ void setAuthPassword(const ByteArray& password); /* Connection */ bool isConnected() const { return status() == Connected; } - void connect(const std::string &address, quint16 port); + void connect(const std::string &address, uint16_t port); /* Ownership means that tor is managed by this socket, and we * can shut it down, own its configuration, etc. */ @@ -111,8 +109,8 @@ public: void addHiddenService(HiddenService *service); std::map bootstrapStatus() const; - /*Q_INVOKABLE*/ QObject *getConfiguration(const std::string &options); - /*Q_INVOKABLE*/ QObject *setConfiguration(const std::list > &options); + /*Q_INVOKABLE*/ TorControlCommand *getConfiguration(const std::string &options); + /*Q_INVOKABLE*/ TorControlCommand *setConfiguration(const std::list > &options); /*Q_INVOKABLE*/ PendingOperation *saveConfiguration(); //signals: @@ -124,6 +122,10 @@ public: // void bootstrapStatusChanged(); // void hasOwnershipChanged(); + void set_statusChanged_callback(const std::function& f) { mStatusChanged_callback = f ;} + void set_connected_callback(const std::function& f) { mConnected_callback = f ;} + void set_disconnected_callback(const std::function& f) { mDisconnected_callback = f ;} + virtual void socketError(const std::string &s) override; //public slots: @@ -142,14 +144,14 @@ private: ByteArray mAuthPassword; std::string mSocksAddress; std::list mServices; - quint16 mControlPort, mSocksPort; + uint16_t mControlPort, mSocksPort; TorControl::Status mStatus; TorControl::TorStatus mTorStatus; std::map mBootstrapStatus; bool mHasOwnership; void getTorInfo(); - void getTorInfoReply(); + void getTorInfoReply(TorControlCommand *sender); void setStatus(TorControl::Status n); void statusEvent(int code, const ByteArray &data); void setTorStatus(TorControl::TorStatus n); @@ -159,7 +161,11 @@ private: void protocolInfoReply(TorControlCommand *sender); void socketDisconnected(); void socketConnected(); - void authenticateReply(); + void authenticateReply(TorControlCommand *sender); + + std::function mStatusChanged_callback; + std::function mConnected_callback; + std::function mDisconnected_callback; }; } diff --git a/libretroshare/src/tor/TorManager.cpp b/libretroshare/src/tor/TorManager.cpp index ec198beb6..289e8ec0c 100644 --- a/libretroshare/src/tor/TorManager.cpp +++ b/libretroshare/src/tor/TorManager.cpp @@ -44,29 +44,20 @@ #include "util/rsdir.h" #include "retroshare/rsinit.h" -#include - #include "TorManager.h" #include "TorProcess.h" #include "TorControl.h" #include "CryptoKey.h" #include "HiddenService.h" #include "GetConfCommand.h" -#include -#include -#include -#include -#include using namespace Tor; namespace Tor { -class TorManagerPrivate : public QObject, public TorProcessClient +class TorManagerPrivate : public TorProcessClient { - Q_OBJECT - public: TorManager *q; TorProcess *process; @@ -91,9 +82,9 @@ public: virtual void processErrorChanged(const std::string &errorMessage) override; virtual void processLogMessage(const std::string &message) override; -public slots: +//public slots: void controlStatusChanged(int status); - void getConfFinished(); + void getConfFinished(TorControlCommand *sender); }; } @@ -104,14 +95,14 @@ TorManager::TorManager() } TorManagerPrivate::TorManagerPrivate(TorManager *parent) - : QObject(nullptr) - , q(parent) + : q(parent) , process(0) - , control(new TorControl(this)) + , control(new TorControl()) , configNeeded(false) , hiddenService(NULL) { - connect(control, SIGNAL(statusChanged(int,int)), SLOT(controlStatusChanged(int))); + //connect(control, SIGNAL(statusChanged(int,int)), SLOT(controlStatusChanged(int))); + control->set_statusChanged_callback([this](int new_status,int /*old_status*/) { controlStatusChanged(new_status); }); } TorManager *TorManager::instance() @@ -178,12 +169,12 @@ bool TorManager::setupHiddenService() std::cerr << "Using legacy dir: " << legacyDir << std::endl; - if (!legacyDir.empty() && QFile::exists(legacyDir.c_str() + QLatin1String("/private_key"))) + if (!legacyDir.empty() && RsDirUtil::fileExists(RsDirUtil::makePath(legacyDir,"/private_key"))) { std::cerr << "Attempting to load key from legacy filesystem format in " << legacyDir << std::endl; CryptoKey key; - if (!key.loadFromFile(legacyDir + "/private_key")) + if (!key.loadFromFile(RsDirUtil::makePath(legacyDir , "/private_key"))) { RsWarn() << "Cannot load legacy format key from" << legacyDir << "for conversion"; return false; @@ -417,7 +408,7 @@ bool TorManager::getProxyServerInfo(std::string& proxy_server_adress,uint16_t& p 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 hidden_services = control()->hiddenServices(); + auto hidden_services = control()->hiddenServices(); if(hidden_services.empty()) return false ; @@ -471,8 +462,8 @@ void TorManagerPrivate::controlStatusChanged(int status) if (status == TorControl::Connected) { if (!configNeeded) { // If DisableNetwork is 1, trigger configurationNeeded - connect(control->getConfiguration("DisableNetwork"), - SIGNAL(finished()), SLOT(getConfFinished())); + auto cmd = control->getConfiguration("DisableNetwork"); + cmd->set_finished_callback( [this](TorControlCommand *sender) { getConfFinished(sender) ; }); } if (process) { @@ -482,9 +473,9 @@ void TorManagerPrivate::controlStatusChanged(int status) } } -void TorManagerPrivate::getConfFinished() +void TorManagerPrivate::getConfFinished(TorControlCommand *sender) { - GetConfCommand *command = qobject_cast(sender()); + GetConfCommand *command = dynamic_cast(sender); if (!command) return; diff --git a/libretroshare/src/tor/bytearray.h b/libretroshare/src/tor/bytearray.h index b237a333a..ebf2b9f85 100644 --- a/libretroshare/src/tor/bytearray.h +++ b/libretroshare/src/tor/bytearray.h @@ -49,6 +49,7 @@ public: return res; } bool endsWith(const ByteArray& b) const { return size() >= b.size() && !memcmp(&data()[size()-b.size()],b.data(),b.size()); } + bool startsWith(const ByteArray& b) const { return b.size() <= size() && !strncmp((char*)b.data(),(char*)data(),std::min(size(),b.size())); } bool startsWith(const char *b) const { for(uint32_t n=0;b[n]!=0;++n) From b323a1635e1bdd0848139f2f6be65b3cf8ebba45 Mon Sep 17 00:00:00 2001 From: csoler Date: Mon, 6 Dec 2021 22:33:50 +0100 Subject: [PATCH 23/65] fixed compilation. Qt is completely gone --- libretroshare/src/libretroshare.pro | 5 - libretroshare/src/pqi/rstcpsocket.h | 2 +- libretroshare/src/tor/CryptoKey.cpp | 3 +- libretroshare/src/tor/HiddenService.h | 5 +- libretroshare/src/tor/SecureRNG.cpp | 147 --------------------- libretroshare/src/tor/SecureRNG.h | 51 ------- libretroshare/src/tor/TorControl.cpp | 1 - libretroshare/src/tor/TorControl.h | 5 +- libretroshare/src/tor/TorControlSocket.cpp | 4 + libretroshare/src/tor/TorControlSocket.h | 2 - libretroshare/src/tor/TorManager.cpp | 2 - libretroshare/src/tor/TorManager.h | 6 +- libretroshare/src/tor/TorProcess.cpp | 1 - libretroshare/src/tor/Useful.h | 13 +- 14 files changed, 13 insertions(+), 234 deletions(-) delete mode 100644 libretroshare/src/tor/SecureRNG.cpp delete mode 100644 libretroshare/src/tor/SecureRNG.h diff --git a/libretroshare/src/libretroshare.pro b/libretroshare/src/libretroshare.pro index 559c77354..4811fa2d6 100644 --- a/libretroshare/src/libretroshare.pro +++ b/libretroshare/src/libretroshare.pro @@ -9,9 +9,6 @@ libretroshare_shared { } else { CONFIG += staticlib } -CONFIG += qt - -QT += network TARGET = retroshare TARGET_PRL = libretroshare @@ -732,7 +729,6 @@ HEADERS += tor/AddOnionCommand.h \ tor/HiddenService.h \ tor/PendingOperation.h \ tor/ProtocolInfoCommand.h \ - tor/SecureRNG.h \ tor/TorTypes.h \ tor/SetConfCommand.h \ tor/StrUtil.h \ @@ -757,7 +753,6 @@ SOURCES += tor/AddOnionCommand.cpp \ tor/TorProcess.cpp \ tor/CryptoKey.cpp \ tor/PendingOperation.cpp \ - tor/SecureRNG.cpp \ tor/StrUtil.cpp # gxs tunnels diff --git a/libretroshare/src/pqi/rstcpsocket.h b/libretroshare/src/pqi/rstcpsocket.h index b268d685c..0099189ba 100644 --- a/libretroshare/src/pqi/rstcpsocket.h +++ b/libretroshare/src/pqi/rstcpsocket.h @@ -7,7 +7,7 @@ class RsTcpSocket: public RsFdBinInterface public: RsTcpSocket(const std::string& tcp_address,uint16_t tcp_port); RsTcpSocket(); - virtual ~RsTcpSocket(); + virtual ~RsTcpSocket()=default; enum State: uint8_t { UNKNOWN = 0x00, diff --git a/libretroshare/src/tor/CryptoKey.cpp b/libretroshare/src/tor/CryptoKey.cpp index 2dd151bad..a914b03aa 100644 --- a/libretroshare/src/tor/CryptoKey.cpp +++ b/libretroshare/src/tor/CryptoKey.cpp @@ -33,7 +33,6 @@ #include #include "CryptoKey.h" -#include "SecureRNG.h" #include "Useful.h" #include @@ -134,7 +133,7 @@ ByteArray torControlHashedPassword(const ByteArray &password) ByteArray salt(8); RsRandom::random_bytes(&salt[0],8); - uint32_t count = ((quint32)16 + (96 & 15)) << ((96 >> 4) + 6); + uint32_t count = ((uint32_t)16 + (96 & 15)) << ((96 >> 4) + 6); Sha1CheckSum md = RsDirUtil::sha1sum((salt+password).data(),count); diff --git a/libretroshare/src/tor/HiddenService.h b/libretroshare/src/tor/HiddenService.h index ae77d51ed..0f4f50dbf 100644 --- a/libretroshare/src/tor/HiddenService.h +++ b/libretroshare/src/tor/HiddenService.h @@ -30,8 +30,7 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#ifndef HIDDENSERVICE_H -#define HIDDENSERVICE_H +#pragma once #include "CryptoKey.h" #include "bytearray.h" @@ -109,5 +108,3 @@ private: }; } - -#endif // HIDDENSERVICE_H diff --git a/libretroshare/src/tor/SecureRNG.cpp b/libretroshare/src/tor/SecureRNG.cpp deleted file mode 100644 index 60cf3c048..000000000 --- a/libretroshare/src/tor/SecureRNG.cpp +++ /dev/null @@ -1,147 +0,0 @@ -/* Ricochet - https://ricochet.im/ - * Copyright (C) 2014, John Brooks - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * * Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following disclaimer - * in the documentation and/or other materials provided with the - * distribution. - * - * * Neither the names of the copyright owners nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include "SecureRNG.h" -#include -#include -#include -#include - -#ifdef Q_OS_WIN -#include -#include -#endif - -#if QT_VERSION >= 0x040700 -#include -#endif - -bool SecureRNG::seed() -{ -#if QT_VERSION >= 0x040700 - QElapsedTimer timer; - timer.start(); -#endif - -#ifdef Q_OS_WIN - /* RAND_poll is very unreliable on windows; with older versions of OpenSSL, - * it can take up to several minutes to run and has been known to crash. - * Even newer versions seem to take around 400ms, which is far too long for - * interactive startup. Random data from the windows CSP is used as a seed - * instead, as it should be very high quality random and fast. */ - HCRYPTPROV provider = 0; - if (!CryptAcquireContext(&provider, NULL, NULL, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT)) - { - qWarning() << "Failed to acquire CSP context for RNG seed:" << hex << GetLastError(); - return false; - } - - /* Same amount of entropy OpenSSL uses, apparently. */ - char buf[32]; - - if (!CryptGenRandom(provider, sizeof(buf), reinterpret_cast(buf))) - { - qWarning() << "Failed to get entropy from CSP for RNG seed: " << hex << GetLastError(); - CryptReleaseContext(provider, 0); - return false; - } - - CryptReleaseContext(provider, 0); - - RAND_seed(buf, sizeof(buf)); - memset(buf, 0, sizeof(buf)); -#else - if (!RAND_poll()) - { - qWarning() << "OpenSSL RNG seed failed:" << ERR_get_error(); - return false; - } -#endif - -#if QT_VERSION >= 0x040700 - qDebug() << "RNG seed took" << timer.elapsed() << "ms"; -#endif - - return true; -} - -void SecureRNG::random(char *buf, int size) -{ - int r = RAND_bytes(reinterpret_cast(buf), size); - if (r <= 0) - qFatal("RNG failed: %lu", ERR_get_error()); -} - -QByteArray SecureRNG::random(int size) -{ - QByteArray re(size, 0); - random(re.data(), size); - return re; -} - -QByteArray SecureRNG::randomPrintable(int length) -{ - QByteArray re(length, 0); - for (int i = 0; i < re.size(); i++) - re[i] = randomInt(95) + 32; - return re; -} - -unsigned SecureRNG::randomInt(unsigned max) -{ - unsigned cutoff = UINT_MAX - (UINT_MAX % max); - unsigned value = 0; - - for (;;) - { - random(reinterpret_cast(&value), sizeof(value)); - if (value < cutoff) - return value % max; - } -} - -#ifndef UINT64_MAX -#define UINT64_MAX ((quint64)-1) -#endif - -quint64 SecureRNG::randomInt64(quint64 max) -{ - quint64 cutoff = UINT64_MAX - (UINT64_MAX % max); - quint64 value = 0; - - for (;;) - { - random(reinterpret_cast(value), sizeof(value)); - if (value < cutoff) - return value % max; - } -} diff --git a/libretroshare/src/tor/SecureRNG.h b/libretroshare/src/tor/SecureRNG.h deleted file mode 100644 index f3b2a4b64..000000000 --- a/libretroshare/src/tor/SecureRNG.h +++ /dev/null @@ -1,51 +0,0 @@ -/* Ricochet - https://ricochet.im/ - * Copyright (C) 2014, John Brooks - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * * Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following disclaimer - * in the documentation and/or other materials provided with the - * distribution. - * - * * Neither the names of the copyright owners nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef SECURERNG_H -#define SECURERNG_H - -#include - -class SecureRNG -{ -public: - static bool seed(); - - static void random(char *buf, int size); - static QByteArray random(int size); - - static QByteArray randomPrintable(int length); - static unsigned randomInt(unsigned max); - static quint64 randomInt64(quint64 max); -}; - -#endif // SECURERNG_H diff --git a/libretroshare/src/tor/TorControl.cpp b/libretroshare/src/tor/TorControl.cpp index 1051a0abe..f858c92b8 100644 --- a/libretroshare/src/tor/TorControl.cpp +++ b/libretroshare/src/tor/TorControl.cpp @@ -874,5 +874,4 @@ bool TorControl::torVersionAsNewAs(const std::string& match) const return true; } -#include "TorControl.moc" diff --git a/libretroshare/src/tor/TorControl.h b/libretroshare/src/tor/TorControl.h index 5ffc1174f..2f4df85b9 100644 --- a/libretroshare/src/tor/TorControl.h +++ b/libretroshare/src/tor/TorControl.h @@ -30,8 +30,7 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#ifndef TORCONTROL_H -#define TORCONTROL_H +#pragma once #include @@ -171,5 +170,3 @@ private: } extern Tor::TorControl *torControl; - -#endif // TORCONTROLMANAGER_H diff --git a/libretroshare/src/tor/TorControlSocket.cpp b/libretroshare/src/tor/TorControlSocket.cpp index 849ca4926..f2142e1d1 100644 --- a/libretroshare/src/tor/TorControlSocket.cpp +++ b/libretroshare/src/tor/TorControlSocket.cpp @@ -49,6 +49,10 @@ TorControlSocket::~TorControlSocket() clear(); } +void TorControlSocket::connectToHost(const std::string& tcp_address,uint16_t tcp_port) +{ + RsTcpSocket::connect(tcp_address,tcp_port); +} std::string TorControlSocket::peerAddress() const { if(connectionState() == State::CONNECTED) diff --git a/libretroshare/src/tor/TorControlSocket.h b/libretroshare/src/tor/TorControlSocket.h index 979d85fa5..779fd6da5 100644 --- a/libretroshare/src/tor/TorControlSocket.h +++ b/libretroshare/src/tor/TorControlSocket.h @@ -52,8 +52,6 @@ public: explicit TorControlSocket(TorControlSocketClient *client); virtual ~TorControlSocket(); - void connect(const std::string& tcp_address,uint16_t tcp_port); - std::string errorMessage() const { return m_errorMessage; } void connectToHost(const std::string& tcp_address,uint16_t tcp_port); diff --git a/libretroshare/src/tor/TorManager.cpp b/libretroshare/src/tor/TorManager.cpp index 289e8ec0c..e06dec02b 100644 --- a/libretroshare/src/tor/TorManager.cpp +++ b/libretroshare/src/tor/TorManager.cpp @@ -580,8 +580,6 @@ void TorManagerPrivate::setError(const std::string &message) //emit q->errorChanged(); } -#include "TorManager.moc" - bool RsTor::isTorAvailable() { return !instance()->d->torExecutablePath().empty(); diff --git a/libretroshare/src/tor/TorManager.h b/libretroshare/src/tor/TorManager.h index 100d55779..e146a6819 100644 --- a/libretroshare/src/tor/TorManager.h +++ b/libretroshare/src/tor/TorManager.h @@ -32,8 +32,7 @@ // This code has been further modified to fit Retroshare context. -#ifndef TORMANAGER_H -#define TORMANAGER_H +#pragma once #include "retroshare/rstor.h" #include "HiddenService.h" @@ -107,6 +106,3 @@ private: }; } - -#endif -# diff --git a/libretroshare/src/tor/TorProcess.cpp b/libretroshare/src/tor/TorProcess.cpp index 77f561063..e744f1268 100644 --- a/libretroshare/src/tor/TorProcess.cpp +++ b/libretroshare/src/tor/TorProcess.cpp @@ -40,7 +40,6 @@ #include "TorProcess.h" #include "CryptoKey.h" -#include "SecureRNG.h" using namespace Tor; diff --git a/libretroshare/src/tor/Useful.h b/libretroshare/src/tor/Useful.h index 6bb6e44c1..cdead13e7 100644 --- a/libretroshare/src/tor/Useful.h +++ b/libretroshare/src/tor/Useful.h @@ -30,11 +30,9 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#ifndef UTILS_USEFUL_H -#define UTILS_USEFUL_H +#pragma once -#include -#include +#include "util/rsdebug.h" /* Print a warning for bug conditions, and assert on a debug build. * @@ -50,7 +48,7 @@ * triggered unless the code or logic is wrong. */ #if !defined(QT_NO_DEBUG) || defined(QT_FORCE_ASSERTS) -# define BUG() Explode(__FILE__,__LINE__), qWarning() << "BUG:" +# define BUG() Explode(__FILE__,__LINE__), RsWarn() << "BUG:" namespace { class Explode { @@ -59,13 +57,10 @@ public: int line; Explode(const char *file, int line) : file(file), line(line) { } ~Explode() { - qt_assert("something broke!", file, line); + RsErr() << "something broke! in file " << file << line; } }; } #else # define BUG() qWarning() << "BUG:" #endif - -#endif - From e0812dce839d465014e18e2ca7d173f1f33e8268 Mon Sep 17 00:00:00 2001 From: csoler Date: Tue, 7 Dec 2021 21:20:19 +0100 Subject: [PATCH 24/65] added back read attempt for control port --- libretroshare/src/tor/TorProcess.cpp | 77 ++++++++++++++++------------ libretroshare/src/tor/TorProcess.h | 4 +- 2 files changed, 47 insertions(+), 34 deletions(-) diff --git a/libretroshare/src/tor/TorProcess.cpp b/libretroshare/src/tor/TorProcess.cpp index e744f1268..3a7f06fbc 100644 --- a/libretroshare/src/tor/TorProcess.cpp +++ b/libretroshare/src/tor/TorProcess.cpp @@ -43,9 +43,12 @@ using namespace Tor; +static const int INTERVAL_BETWEEN_CONTROL_PORT_READ_TRIES = 5; // try every 5 secs. + TorProcess::TorProcess(TorProcessClient *client) - : m_client(client) + : m_client(client), mLastTryReadControlPort(0) { + mControlPortReadNbTries=0; } TorProcess::~TorProcess() @@ -282,6 +285,23 @@ void TorProcess::run() RsErr() << "Tor process died. Exiting TorControl process." ; return; } + time_t now = time(nullptr); + + if(mControlPortReadNbTries <= 10 && (mControlPort==0 || mControlHost.empty()) && mLastTryReadControlPort + INTERVAL_BETWEEN_CONTROL_PORT_READ_TRIES < now) + { + mLastTryReadControlPort = now; + + if(tryReadControlPort()) + { + mState = Ready; + // stateChanged(mState); + } + else if(mControlPortReadNbTries > 10) + { + //errorMessageChanged(errorMessage); + //stateChanged(state); + } + } } // Kill the Tor process since we've been asked to stop. @@ -378,6 +398,29 @@ std::string TorProcess::controlPortFilePath() const return mDataDir + "/" + "control-port"; } +bool TorProcess::tryReadControlPort() +{ + FILE *file = RsDirUtil::rs_fopen(controlPortFilePath().c_str(),"r"); + + if(file) + { + char *line = nullptr; + + size_t size = getline(&line,0,file); + ByteArray data = ByteArray((unsigned char*)line,size).trimmed(); + free(line); + + int p; + if (data.startsWith("PORT=") && (p = data.lastIndexOf(':')) > 0) { + mControlHost = data.mid(5, p - 5).toString(); + mControlPort = data.mid(p+1).toInt(); + + if (!mControlHost.empty() && mControlPort > 0) + return true; + } + } + return false; +} #ifdef TO_REMOVE void TorProcessPrivate::processStarted() { @@ -423,39 +466,7 @@ void TorProcessPrivate::processReadable() } } -void TorProcessPrivate::tryReadControlPort() -{ - FILE *file = RsDirUtil::rs_fopen(controlPortFilePath().c_str(),"r"); - if(file) - { - char *line = nullptr; - - size_t size = getline(&line,0,file); - ByteArray data = ByteArray((unsigned char*)line,size).trimmed(); - free(line); - - int p; - if (data.startsWith("PORT=") && (p = data.lastIndexOf(':')) > 0) { - controlHost = QHostAddress(data.mid(5, p - 5)); - controlPort = data.mid(p+1).toUShort(); - - if (!controlHost.isNull() && controlPort > 0) { - controlPortTimer.stop(); - state = TorProcess::Ready; - /*emit*/ q->stateChanged(state); - return; - } - } - } - - if (++controlPortAttempts * controlPortTimer.interval() > 10000) { - errorMessage = "No control port available after launching process"; - state = TorProcess::Failed; - /*emit*/ q->errorMessageChanged(errorMessage); - /*emit*/ q->stateChanged(state); - } -} TorProcessPrivate::TorProcessPrivate(TorProcess *q) : q(q), state(TorProcess::NotStarted), controlPort(0), controlPortAttempts(0) { diff --git a/libretroshare/src/tor/TorProcess.h b/libretroshare/src/tor/TorProcess.h index c48b758b8..7b7868417 100644 --- a/libretroshare/src/tor/TorProcess.h +++ b/libretroshare/src/tor/TorProcess.h @@ -125,12 +125,14 @@ private: bool ensureFilesExist(); pid_t mTorProcessId; + time_t mLastTryReadControlPort ; + int mControlPortReadNbTries ; //public slots: void processStarted(); void processFinished(); void processError(std::string error); void processReadable(); - void tryReadControlPort(); + bool tryReadControlPort(); }; } From a757419d6591ad5ca42c8a7346ded175c5b66627 Mon Sep 17 00:00:00 2001 From: csoler Date: Thu, 9 Dec 2021 21:04:49 +0100 Subject: [PATCH 25/65] fixed compilation --- libretroshare/src/rsserver/rsinit.cc | 5 +---- libretroshare/src/tor/GetConfCommand.cpp | 7 +++---- 2 files changed, 4 insertions(+), 8 deletions(-) diff --git a/libretroshare/src/rsserver/rsinit.cc b/libretroshare/src/rsserver/rsinit.cc index cad6d3ae7..8383a8eda 100644 --- a/libretroshare/src/rsserver/rsinit.cc +++ b/libretroshare/src/rsserver/rsinit.cc @@ -36,8 +36,6 @@ # include // for QString::fromStdString(...) #endif -#include - #include "util/argstream.h" #include "util/rsdebug.h" #include "util/rsdir.h" @@ -1975,8 +1973,7 @@ bool RsInit::startAutoTor() return false; } // process Qt event loop to deal with messages of online/offline info - - QCoreApplication::processEvents(); + // QCoreApplication::processEvents(); } return true; } diff --git a/libretroshare/src/tor/GetConfCommand.cpp b/libretroshare/src/tor/GetConfCommand.cpp index f85f640c1..02e1df1ce 100644 --- a/libretroshare/src/tor/GetConfCommand.cpp +++ b/libretroshare/src/tor/GetConfCommand.cpp @@ -32,7 +32,6 @@ #include "GetConfCommand.h" #include "StrUtil.h" -#include using namespace Tor; @@ -54,11 +53,11 @@ ByteArray GetConfCommand::build(const std::list &keys) } else if (type == GetInfo) { out = "GETINFO"; } else { - Q_ASSERT(false); + assert(false); return out; } - foreach (const ByteArray &key, keys) { + for(const ByteArray &key: keys) { out.append(' '); out.append(key); } @@ -86,7 +85,7 @@ void GetConfCommand::onReply(int statusCode, const ByteArray &data) void GetConfCommand::onDataLine(const ByteArray &data) { if (m_lastKey.empty()) { - qWarning() << "torctrl: Unexpected data line in GetConf command"; + RsWarn() << "torctrl: Unexpected data line in GetConf command"; return; } m_results[m_lastKey].push_back(data.toString()); From 7c77cfd603e49a2ec4c36c545a2237f565159361 Mon Sep 17 00:00:00 2001 From: csoler Date: Thu, 9 Dec 2021 22:19:00 +0100 Subject: [PATCH 26/65] fixed a few bugs in new TorManager --- libretroshare/src/tor/CryptoKey.cpp | 2 +- libretroshare/src/tor/GetConfCommand.cpp | 2 +- libretroshare/src/tor/StrUtil.cpp | 10 +++++----- libretroshare/src/tor/TorManager.cpp | 7 ++++--- libretroshare/src/tor/TorProcess.cpp | 3 ++- libretroshare/src/tor/bytearray.h | 2 ++ libretroshare/src/util/rsrandom.cc | 12 ++++++++---- 7 files changed, 23 insertions(+), 15 deletions(-) diff --git a/libretroshare/src/tor/CryptoKey.cpp b/libretroshare/src/tor/CryptoKey.cpp index a914b03aa..641c1e4dc 100644 --- a/libretroshare/src/tor/CryptoKey.cpp +++ b/libretroshare/src/tor/CryptoKey.cpp @@ -82,7 +82,7 @@ bool CryptoKey::loadFromFile(const std::string& path) ByteArray data ; int c; while(EOF != (c=fgetc(file))) - data.append((unsigned char)c); + data.push_back((unsigned char)c); fclose(file); diff --git a/libretroshare/src/tor/GetConfCommand.cpp b/libretroshare/src/tor/GetConfCommand.cpp index 02e1df1ce..02f903b4a 100644 --- a/libretroshare/src/tor/GetConfCommand.cpp +++ b/libretroshare/src/tor/GetConfCommand.cpp @@ -58,7 +58,7 @@ ByteArray GetConfCommand::build(const std::list &keys) } for(const ByteArray &key: keys) { - out.append(' '); + out.push_back(' '); out.append(key); } diff --git a/libretroshare/src/tor/StrUtil.cpp b/libretroshare/src/tor/StrUtil.cpp index b0d035845..8e4ac9d20 100644 --- a/libretroshare/src/tor/StrUtil.cpp +++ b/libretroshare/src/tor/StrUtil.cpp @@ -37,7 +37,7 @@ ByteArray quotedString(const ByteArray &string) ByteArray out; out.reserve(string.size() * 2); - out.append('"'); + out.push_back('"'); for (uint i = 0; i < string.size(); ++i) { @@ -50,12 +50,12 @@ ByteArray quotedString(const ByteArray &string) out.append("\\\\"); break; default: - out.append(string[i]); + out.push_back(string[i]); break; } } - out.append('"'); + out.push_back('"'); return out; } @@ -73,12 +73,12 @@ ByteArray unquotedString(const ByteArray& string) { case '\\': if (++i < string.size()) - out.append(string[i]); + out.push_back(string[i]); break; case '"': return out; default: - out.append(string[i]); + out.push_back(string[i]); } } diff --git a/libretroshare/src/tor/TorManager.cpp b/libretroshare/src/tor/TorManager.cpp index e06dec02b..e19e8a10d 100644 --- a/libretroshare/src/tor/TorManager.cpp +++ b/libretroshare/src/tor/TorManager.cpp @@ -168,13 +168,14 @@ bool TorManager::setupHiddenService() } std::cerr << "Using legacy dir: " << legacyDir << std::endl; + auto key_path = RsDirUtil::makePath(legacyDir,"/private_key"); - if (!legacyDir.empty() && RsDirUtil::fileExists(RsDirUtil::makePath(legacyDir,"/private_key"))) + if (!legacyDir.empty() && RsDirUtil::fileExists(key_path)) { - std::cerr << "Attempting to load key from legacy filesystem format in " << legacyDir << std::endl; + std::cerr << "Attempting to load key from legacy filesystem format from file \"" << key_path << "\"" << std::endl; CryptoKey key; - if (!key.loadFromFile(RsDirUtil::makePath(legacyDir , "/private_key"))) + if (!key.loadFromFile(key_path)) { RsWarn() << "Cannot load legacy format key from" << legacyDir << "for conversion"; return false; diff --git a/libretroshare/src/tor/TorProcess.cpp b/libretroshare/src/tor/TorProcess.cpp index 3a7f06fbc..7cb4c832e 100644 --- a/libretroshare/src/tor/TorProcess.cpp +++ b/libretroshare/src/tor/TorProcess.cpp @@ -46,9 +46,10 @@ using namespace Tor; static const int INTERVAL_BETWEEN_CONTROL_PORT_READ_TRIES = 5; // try every 5 secs. TorProcess::TorProcess(TorProcessClient *client) - : m_client(client), mLastTryReadControlPort(0) + : m_client(client), mState(TorProcess::NotStarted), mControlPort(0), mLastTryReadControlPort(0) { mControlPortReadNbTries=0; + } TorProcess::~TorProcess() diff --git a/libretroshare/src/tor/bytearray.h b/libretroshare/src/tor/bytearray.h index ebf2b9f85..6d8897ae9 100644 --- a/libretroshare/src/tor/bytearray.h +++ b/libretroshare/src/tor/bytearray.h @@ -32,6 +32,8 @@ public: void append(const ByteArray& b) { for(auto c:b) push_back(c); } void append(const char *b) { for(uint32_t n=0;b[n]!=0;++n) push_back(b[n]); } + template void append(const T) = delete;// Prevents any implicit when calling the preceding functions which actually causes real bugs. + ByteArray& operator+=(const ByteArray& b) { for(auto c:b) push_back(c); return *this; } ByteArray& operator+=(const char *b) { for(uint32_t n=0;b[n]!=0;++n) push_back(b[n]); return *this;} diff --git a/libretroshare/src/util/rsrandom.cc b/libretroshare/src/util/rsrandom.cc index dc7d9ac67..96a24b140 100644 --- a/libretroshare/src/util/rsrandom.cc +++ b/libretroshare/src/util/rsrandom.cc @@ -139,8 +139,12 @@ double RsRandom::random_f64() /*static*/ std::string RsRandom::printable(uint32_t length) { - std::string ret(length, 0); - random_bytes(reinterpret_cast(&ret[0]), length); - for(uint32_t i=0; i Date: Fri, 10 Dec 2021 16:29:10 +0100 Subject: [PATCH 27/65] debugged pipe system with tor executable --- libretroshare/src/pqi/pqifdbin.cc | 3 +- libretroshare/src/tor/TorManager.cpp | 58 +++++++++++++++++-- libretroshare/src/tor/TorProcess.cpp | 23 ++++++-- .../src/TorControl/TorControlWindow.cpp | 2 - 4 files changed, 71 insertions(+), 15 deletions(-) diff --git a/libretroshare/src/pqi/pqifdbin.cc b/libretroshare/src/pqi/pqifdbin.cc index 68b192c2b..1ace8a6b1 100644 --- a/libretroshare/src/pqi/pqifdbin.cc +++ b/libretroshare/src/pqi/pqifdbin.cc @@ -64,7 +64,8 @@ int RsFdBinInterface::read_pending() char inBuffer[1025]; memset(inBuffer,0,1025); - ssize_t readbytes = recv(mCLintConnt, inBuffer, sizeof(inBuffer),MSG_DONTWAIT); + ssize_t readbytes = read(mCLintConnt, inBuffer, sizeof(inBuffer)); // Needs read instead of recv which is only for sockets. + // Sockets should be set to non blocking by the client process. if(readbytes == 0) { diff --git a/libretroshare/src/tor/TorManager.cpp b/libretroshare/src/tor/TorManager.cpp index e19e8a10d..86d857980 100644 --- a/libretroshare/src/tor/TorManager.cpp +++ b/libretroshare/src/tor/TorManager.cpp @@ -148,6 +148,44 @@ void TorManager::setHiddenServiceDirectory(const std::string &path) d->hiddenServiceDir += '/'; } +static bool test_listening_port(const std::string& address,uint16_t port) +{ + int sockfd, portno; + struct sockaddr_in serv_addr; + + /* First call to socket() function */ + sockfd = socket(AF_INET, SOCK_STREAM, 0); + + if (sockfd < 0) + return false; + + /* Initialize socket structure */ + bzero((char *) &serv_addr, sizeof(serv_addr)); + portno = 5001; + + serv_addr.sin_family = AF_INET; + serv_addr.sin_addr.s_addr = INADDR_ANY; + serv_addr.sin_port = htons(portno); + + /* Now bind the host address using bind() call.*/ + if (bind(sockfd, (struct sockaddr *) &serv_addr, sizeof(serv_addr)) < 0) { + perror("ERROR on binding"); + close(sockfd); + return false; + } + int flags = fcntl(sockfd, F_GETFL); + fcntl(sockfd, F_SETFL, flags | O_NONBLOCK); + + int res = listen(sockfd,5); + + int err = errno; + close(sockfd); + + if(!res) + return true; + + return false; +} bool TorManager::setupHiddenService() { if(d->hiddenService != NULL) @@ -208,12 +246,12 @@ bool TorManager::setupHiddenService() std::cerr << "Testing host address: " << address << ":" << port ; -// if (!QTcpServer().listen(address, port)) -// { -// // XXX error case -// std::cerr << " Failed to open incoming socket" << std::endl; -// return false; -// } + if(!test_listening_port(address,port)) + { + // XXX error case + std::cerr << " Failed to open incoming socket" << std::endl; + return false; + } std::cerr << " OK - Adding hidden service to TorControl." << std::endl; @@ -538,6 +576,14 @@ std::string TorManagerPrivate::torExecutablePath() const return tor_exe_path; #endif +#ifdef __linux__ + // On linux try system-installed tor /usr/bin/tor + + if(RsDirUtil::fileExists("/usr/bin/tor")) + return std::string("/usr/bin/tor"); +#endif + + RsErr() << "Could not find Tor executable anywhere!" ; // Try $PATH return filename.substr(1); } diff --git a/libretroshare/src/tor/TorProcess.cpp b/libretroshare/src/tor/TorProcess.cpp index 7cb4c832e..a26b5228a 100644 --- a/libretroshare/src/tor/TorProcess.cpp +++ b/libretroshare/src/tor/TorProcess.cpp @@ -113,6 +113,8 @@ std::string TorProcess::errorMessage() const int popen3(int fd[3],const char **const cmd,pid_t& pid) { + RsErr() << "Launching Tor in background..." ; + int i, e; int p[3][2]; // set all the FDs to invalid @@ -141,6 +143,7 @@ int popen3(int fd[3],const char **const cmd,pid_t& pid) } else { + RsErr() << "Launching sub-process..." ; // child dup2(p[STDIN_FILENO][0],STDIN_FILENO); close(p[STDIN_FILENO][1]); @@ -148,16 +151,20 @@ int popen3(int fd[3],const char **const cmd,pid_t& pid) close(p[STDOUT_FILENO][0]); dup2(p[STDERR_FILENO][1],STDERR_FILENO); close(p[STDERR_FILENO][0]); + // here we try and run it + execv(*cmd,const_cast(cmd)); + // if we are there, then we failed to launch our program perror("Could not launch"); fprintf(stderr," \"%s\"\n",*cmd); } error: - // preserve original error e = errno; + // preserve original error + RsErr() << "An error occurred while trying to launch tor in background." ; for(i=0; i<3; i++) { close(p[i][0]); close(p[i][1]); @@ -253,8 +260,8 @@ void TorProcess::run() // We first pushed everything into a vector of strings to save the pointers obtained from string returning methods // by the time the process is launched. - for(auto s:args) - arguments[n++]= s.c_str(); + for(uint32_t i=0;isetText(s) ;: - std::cerr << "Connexion Proxy: " << RsTor::socksAddress() << ":" << QString::number(RsTor::socksPort()).toStdString() << std::endl; } From 1c576411fbda7c43f00756288d72208360ce62da Mon Sep 17 00:00:00 2001 From: csoler Date: Fri, 10 Dec 2021 18:01:21 +0100 Subject: [PATCH 28/65] fixed control port reading --- libretroshare/src/pqi/pqifdbin.cc | 8 ++++++++ libretroshare/src/tor/TorProcess.cpp | 7 ++++++- 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/libretroshare/src/pqi/pqifdbin.cc b/libretroshare/src/pqi/pqifdbin.cc index 1ace8a6b1..ee43a1c42 100644 --- a/libretroshare/src/pqi/pqifdbin.cc +++ b/libretroshare/src/pqi/pqifdbin.cc @@ -30,6 +30,9 @@ RsFdBinInterface::RsFdBinInterface(int file_descriptor) mTotalInBufferBytes=0; mTotalWrittenBytes=0; mTotalOutBufferBytes=0; + + if(file_descriptor!=0) + setSocket(file_descriptor); } void RsFdBinInterface::setSocket(int s) @@ -39,6 +42,11 @@ void RsFdBinInterface::setSocket(int s) RsErr() << "Changing socket to active FsBioInterface! Canceling all pending R/W data." ; close(); } + int flags = fcntl(s,F_GETFL); + + if(!(flags & O_NONBLOCK)) + throw std::runtime_error("Trying to use a blocking file descriptor in RsFdBinInterface. This is not going to work!"); + mCLintConnt = s; mIsActive = (s!=0); } diff --git a/libretroshare/src/tor/TorProcess.cpp b/libretroshare/src/tor/TorProcess.cpp index a26b5228a..809afdbe9 100644 --- a/libretroshare/src/tor/TorProcess.cpp +++ b/libretroshare/src/tor/TorProcess.cpp @@ -413,12 +413,14 @@ std::string TorProcess::controlPortFilePath() const bool TorProcess::tryReadControlPort() { FILE *file = RsDirUtil::rs_fopen(controlPortFilePath().c_str(),"r"); + std::cerr << "Trying to read control port" << std::endl; if(file) { char *line = nullptr; + size_t tmp_buffsize = 0; - size_t size = getline(&line,0,file); + size_t size = getline(&line,&tmp_buffsize,file); ByteArray data = ByteArray((unsigned char*)line,size).trimmed(); free(line); @@ -428,7 +430,10 @@ bool TorProcess::tryReadControlPort() mControlPort = data.mid(p+1).toInt(); if (!mControlHost.empty() && mControlPort > 0) + { + std::cerr << "Read control port = " << mControlPort << std::endl; return true; + } } } return false; From 24e862ae25ef2063de35a180f019f5908bf3cc55 Mon Sep 17 00:00:00 2001 From: csoler Date: Mon, 13 Dec 2021 20:28:07 +0100 Subject: [PATCH 29/65] moved event loop in TorManager to the TorManager class --- libretroshare/src/retroshare/rstor.h | 1 + libretroshare/src/tor/TorManager.cpp | 34 +++++++++++-- libretroshare/src/tor/TorManager.h | 12 ++--- libretroshare/src/tor/TorProcess.cpp | 74 ++++++++++++---------------- libretroshare/src/tor/TorProcess.h | 23 +++------ 5 files changed, 78 insertions(+), 66 deletions(-) diff --git a/libretroshare/src/retroshare/rstor.h b/libretroshare/src/retroshare/rstor.h index dd4739304..347d8b1c7 100644 --- a/libretroshare/src/retroshare/rstor.h +++ b/libretroshare/src/retroshare/rstor.h @@ -38,6 +38,7 @@ enum class RsTorManagerEventCode: uint8_t TOR_CONNECTIVITY_CHANGED = 0x03, TOR_MANAGER_ERROR = 0x04, CONFIGURATION_NEEDED = 0x05, + TOR_MANAGER_STOPPED = 0x06, }; // Status of the Tor hidden service setup/loaded by RS diff --git a/libretroshare/src/tor/TorManager.cpp b/libretroshare/src/tor/TorManager.cpp index 86d857980..c4e012de8 100644 --- a/libretroshare/src/tor/TorManager.cpp +++ b/libretroshare/src/tor/TorManager.cpp @@ -328,7 +328,7 @@ std::string TorManager::errorMessage() const return d->errorMessage; } -bool TorManager::start() +bool TorManager::startTorManager() { if (!d->errorMessage.empty()) { d->errorMessage.clear(); @@ -432,11 +432,39 @@ bool TorManager::start() d->process->setExecutable(executable); d->process->setDataDir(d->dataDir); d->process->setDefaultTorrc(defaultTorrc); - d->process->start(); } + + std::cerr << "Starting Tor manager thread:" << std::endl; + RsThread::start("TorManager"); return true ; } +void TorManager::run() +{ + d->process->start(); + + while(!shouldStop()) + { + threadTick(); + std::this_thread::sleep_for(std::chrono::milliseconds(50)); + } + + d->control->shutdown(); + d->process->stop(); + + if(rsEvents) + { + auto ev = std::make_shared(); + ev->mTorManagerEventType = RsTorManagerEventCode::TOR_MANAGER_STOPPED; + rsEvents->sendEvent(ev); + } +} + +void TorManager::threadTick() +{ + d->process->tick(); +} + bool TorManager::getProxyServerInfo(std::string& proxy_server_adress,uint16_t& proxy_server_port) { proxy_server_adress = control()->socksAddress(); @@ -743,7 +771,7 @@ void RsTor::getProxyServerInfo(std::string& server_address, uint16_t& server_po bool RsTor::start() { - return instance()->start(); + return instance()->startTorManager(); } void RsTor::setTorDataDirectory(const std::string& dir) diff --git a/libretroshare/src/tor/TorManager.h b/libretroshare/src/tor/TorManager.h index e146a6819..555192852 100644 --- a/libretroshare/src/tor/TorManager.h +++ b/libretroshare/src/tor/TorManager.h @@ -47,7 +47,7 @@ class TorManagerPrivate; /* Run/connect to an instance of Tor according to configuration, and manage * UI interaction, first time configuration, etc. */ -class TorManager : public HiddenServiceClient, public RsTor +class TorManager : public HiddenServiceClient, public RsThread, public RsTor { // Q_OBJECT @@ -65,7 +65,6 @@ public: TorProcess *process(); TorControl *control(); - std::string torDataDirectory() const; void setTorDataDirectory(const std::string &path); @@ -87,7 +86,7 @@ public: bool getProxyServerInfo(std::string &proxy_server_adress, uint16_t& proxy_server_port); //public slots: - bool start(); + bool startTorManager(); //private slots: virtual void hiddenServiceOnline() override {} // do nothing here. @@ -95,9 +94,10 @@ public: virtual void hiddenServiceHostnameChanged() override; virtual void hiddenServiceStatusChanged(int old_status,int new_status) override; -//signals: -// void configurationNeededChanged(); -// void errorChanged(); + // Thread stuff + + virtual void run() override; + void threadTick() ; private: explicit TorManager(); diff --git a/libretroshare/src/tor/TorProcess.cpp b/libretroshare/src/tor/TorProcess.cpp index 809afdbe9..3142e9488 100644 --- a/libretroshare/src/tor/TorProcess.cpp +++ b/libretroshare/src/tor/TorProcess.cpp @@ -216,12 +216,7 @@ void TorProcess::start() mControlPort = 0; mControlHost.clear(); - RsThread::start("TorControl"); -} - -void TorProcess::run() -{ - // We're inside the process control thread: launch the process, + // Launch the process std::vector args; @@ -278,51 +273,44 @@ void TorProcess::run() flags = fcntl(fd[STDOUT_FILENO], F_GETFL); fcntl(fd[STDOUT_FILENO], F_SETFL, flags | O_NONBLOCK); flags = fcntl(fd[STDERR_FILENO], F_GETFL); fcntl(fd[STDERR_FILENO], F_SETFL, flags | O_NONBLOCK); - RsFdBinInterface stdout_FD(fd[STDOUT_FILENO]); - RsFdBinInterface stderr_FD(fd[STDERR_FILENO]); + mStdOutFD = new RsFdBinInterface(fd[STDOUT_FILENO]); + mStdErrFD = new RsFdBinInterface(fd[STDERR_FILENO]); +} + +void TorProcess::tick() +{ + mStdOutFD->tick(); + mStdErrFD->tick(); unsigned char buff[1024]; + int s; - while(!shouldStop()) + if((s=mStdOutFD->readline(buff,1024))) logMessage(std::string((char*)buff,s)); + if((s=mStdErrFD->readline(buff,1024))) logMessage(std::string((char*)buff,s)); + + if(!mStdOutFD->isactive() && !mStdErrFD->isactive()) { - stdout_FD.tick(); - stderr_FD.tick(); - int s; + RsErr() << "Tor process died. Exiting TorControl process." ; + stop(); + return; + } + time_t now = time(nullptr); - if((s=stdout_FD.readline(buff,1024))) logMessage(std::string((char*)buff,s)); - if((s=stderr_FD.readline(buff,1024))) logMessage(std::string((char*)buff,s)); + if(mControlPortReadNbTries <= 10 && (mControlPort==0 || mControlHost.empty()) && mLastTryReadControlPort + INTERVAL_BETWEEN_CONTROL_PORT_READ_TRIES < now) + { + mLastTryReadControlPort = now; - if(!stdout_FD.isactive() && !stderr_FD.isactive()) + if(tryReadControlPort()) { - RsErr() << "Tor process died. Exiting TorControl process." ; - return; + mState = Ready; + // stateChanged(mState); } - time_t now = time(nullptr); - - if(mControlPortReadNbTries <= 10 && (mControlPort==0 || mControlHost.empty()) && mLastTryReadControlPort + INTERVAL_BETWEEN_CONTROL_PORT_READ_TRIES < now) + else if(mControlPortReadNbTries > 10) { - mLastTryReadControlPort = now; - - if(tryReadControlPort()) - { - mState = Ready; - // stateChanged(mState); - } - else if(mControlPortReadNbTries > 10) - { - //errorMessageChanged(errorMessage); - //stateChanged(state); - } + //errorMessageChanged(errorMessage); + //stateChanged(state); } } - - // Kill the Tor process since we've been asked to stop. - - kill(mTorProcessId,SIGTERM); - int status=0; - wait(&status); - - RsInfo() << "Tor process has been normally terminated. Exiting."; } void TorProcess::stop() @@ -333,7 +321,9 @@ void TorProcess::stop() while(mState == Starting) std::this_thread::sleep_for(std::chrono::milliseconds(100)); - fullstop(); + kill(mTorProcessId,SIGTERM); + + RsInfo() << "Tor process has been normally terminated. Exiting."; mState = NotStarted; @@ -431,7 +421,7 @@ bool TorProcess::tryReadControlPort() if (!mControlHost.empty() && mControlPort > 0) { - std::cerr << "Read control port = " << mControlPort << std::endl; + std::cerr << "Got control host/port = " << mControlHost << ":" << mControlPort << std::endl; return true; } } diff --git a/libretroshare/src/tor/TorProcess.h b/libretroshare/src/tor/TorProcess.h index 7b7868417..77f3bb60b 100644 --- a/libretroshare/src/tor/TorProcess.h +++ b/libretroshare/src/tor/TorProcess.h @@ -36,6 +36,8 @@ #include "bytearray.h" #include "util/rsthreads.h" +class RsFdBinInterface ; + namespace Tor { @@ -53,14 +55,8 @@ public: /* Launches and controls a Tor instance with behavior suitable for bundling * an instance with the application. */ -class TorProcess: public RsThread +class TorProcess { - //Q_OBJECT - //Q_ENUMS(State) - - //Q_PROPERTY(State state READ state NOTIFY stateChanged) - //Q_PROPERTY(std::string errorMessage READ errorMessage NOTIFY errorMessageChanged) - public: enum State { Failed = -1, @@ -91,20 +87,14 @@ public: unsigned short controlPort(); ByteArray controlPassword(); -//signals: void stateChanged(int newState); void errorMessageChanged(const std::string &errorMessage); void logMessage(const std::string &message); -//public slots: void start(); void stop(); + void tick(); - // Implements RsThread - void run() override ; - - // Keeps reading the output of the tor process and so on. - void threadTick(); private: TorProcessClient *m_client; @@ -127,12 +117,15 @@ private: pid_t mTorProcessId; time_t mLastTryReadControlPort ; int mControlPortReadNbTries ; -//public slots: + void processStarted(); void processFinished(); void processError(std::string error); void processReadable(); bool tryReadControlPort(); + + RsFdBinInterface *mStdOutFD; + RsFdBinInterface *mStdErrFD; }; } From d9368507a9fcc8fac9970097d0be4c99490f1a5c Mon Sep 17 00:00:00 2001 From: csoler Date: Wed, 15 Dec 2021 22:15:52 +0100 Subject: [PATCH 30/65] fixed a few bugs in torcontrol socket methods --- libretroshare/src/pqi/pqifdbin.cc | 2 +- libretroshare/src/pqi/rstcpsocket.cc | 18 ++++++++++------- libretroshare/src/pqi/rstcpsocket.h | 6 +++--- libretroshare/src/tor/TorControl.cpp | 19 ++++++++++-------- libretroshare/src/tor/TorControl.h | 7 ++++--- libretroshare/src/tor/TorControlSocket.cpp | 4 ++-- libretroshare/src/tor/TorControlSocket.h | 2 +- libretroshare/src/tor/TorManager.cpp | 23 ++++++++++++++++++++++ 8 files changed, 56 insertions(+), 25 deletions(-) diff --git a/libretroshare/src/pqi/pqifdbin.cc b/libretroshare/src/pqi/pqifdbin.cc index ee43a1c42..a982d670c 100644 --- a/libretroshare/src/pqi/pqifdbin.cc +++ b/libretroshare/src/pqi/pqifdbin.cc @@ -24,7 +24,7 @@ #include "pqi/pqifdbin.h" RsFdBinInterface::RsFdBinInterface(int file_descriptor) - : mCLintConnt(file_descriptor),mIsActive(file_descriptor!=0) + : mCLintConnt(file_descriptor),mIsActive(false) { mTotalReadBytes=0; mTotalInBufferBytes=0; diff --git a/libretroshare/src/pqi/rstcpsocket.cc b/libretroshare/src/pqi/rstcpsocket.cc index 89350d8bd..e104da46e 100644 --- a/libretroshare/src/pqi/rstcpsocket.cc +++ b/libretroshare/src/pqi/rstcpsocket.cc @@ -16,16 +16,17 @@ RsTcpSocket::RsTcpSocket() { } -int RsTcpSocket::connect(const std::string& tcp_address,uint16_t tcp_port) +bool RsTcpSocket::connect(const std::string& tcp_address,uint16_t tcp_port) { - close(); + if(mState == CONNECTED) + close(); mConnectPort = tcp_port; mConnectAddress = tcp_address; return connect(); } -int RsTcpSocket::connect() +bool RsTcpSocket::connect() { int CreateSocket = 0; char dataReceived[1024]; @@ -38,18 +39,21 @@ int RsTcpSocket::connect() printf("Socket not created \n"); return false; } - ipOfServer.sin_family = AF_INET; ipOfServer.sin_port = htons(mConnectPort); ipOfServer.sin_addr.s_addr = inet_addr(mConnectAddress.c_str()); - if(::connect(mSocket, (struct sockaddr *)&ipOfServer, sizeof(ipOfServer))<0) + if(::connect(CreateSocket, (struct sockaddr *)&ipOfServer, sizeof(ipOfServer))<0) { - printf("Connection failed due to port and ip problems, or server is not available\n"); + printf("Connection failed due to port and ip problems, or server is not available. Socket=%d,ConnectPort=%d,ConnectAddress=%s Errno=%d\n",mSocket,mConnectPort,mConnectAddress.c_str(),errno); return false; } mState = CONNECTED; - setSocket(mSocket); + + int flags = fcntl(CreateSocket,F_GETFL); + fcntl(CreateSocket, F_SETFL, flags | O_NONBLOCK); + + setSocket(CreateSocket); return true; } diff --git a/libretroshare/src/pqi/rstcpsocket.h b/libretroshare/src/pqi/rstcpsocket.h index 0099189ba..a51c400ef 100644 --- a/libretroshare/src/pqi/rstcpsocket.h +++ b/libretroshare/src/pqi/rstcpsocket.h @@ -15,10 +15,10 @@ public: CONNECTED = 0x02 }; - // Return 1 when OK, 0 otherwise. - int connect(); + // Return true when OK, false otherwise. + bool connect(); - int connect(const std::string& tcp_address,uint16_t tcp_port); + bool connect(const std::string& tcp_address,uint16_t tcp_port); // Returns 1 when OK, 0 otherwise. int close(); diff --git a/libretroshare/src/tor/TorControl.cpp b/libretroshare/src/tor/TorControl.cpp index f858c92b8..ac13ddcab 100644 --- a/libretroshare/src/tor/TorControl.cpp +++ b/libretroshare/src/tor/TorControl.cpp @@ -179,10 +179,10 @@ void TorControl::setStatus(TorControl::Status n) } mStatusChanged_callback(mStatus, old); - if (mStatus == TorControl::Connected && old < TorControl::Connected) - socketConnected();//mConnected_callback(); - else if (mStatus < TorControl::Connected && old >= TorControl::Connected) - socketDisconnected();//mDisconnected_callback(); +// if (mStatus == TorControl::Connected && old < TorControl::Connected) +// socketConnected();//mConnected_callback(); +// else if (mStatus < TorControl::Connected && old >= TorControl::Connected) +// socketDisconnected();//mDisconnected_callback(); } void TorControl::setTorStatus(TorControl::TorStatus n) @@ -282,11 +282,14 @@ void TorControl::connect(const std::string &address, uint16_t port) setTorStatus(TorUnknown); //bool b = d->socket->blockSignals(true); - mSocket->fullstop(); + if(mSocket->isRunning()) + mSocket->fullstop(); //d->socket->blockSignals(b); setStatus(Connecting); - mSocket->connectToHost(address, port); + + if(mSocket->connectToHost(address, port)) + setStatus(SocketConnected); } void TorControl::reconnect() @@ -336,9 +339,9 @@ void TorControl::authenticateReply(TorControlCommand *sender) } -void TorControl::socketConnected() +void TorControl::authenticate() { - assert(mStatus == TorControl::Connecting); + assert(mStatus == TorControl::SocketConnected); torCtrlDebug() << "torctrl: Connected socket; querying information" << std::endl; setStatus(TorControl::Authenticating); diff --git a/libretroshare/src/tor/TorControl.h b/libretroshare/src/tor/TorControl.h index 2f4df85b9..13aad5c9e 100644 --- a/libretroshare/src/tor/TorControl.h +++ b/libretroshare/src/tor/TorControl.h @@ -67,8 +67,9 @@ public: Error = -1, NotConnected = 0x00, Connecting = 0x01, - Authenticating = 0x02, - Connected = 0x03 + SocketConnected= 0x02, + Authenticating = 0x03, + Connected = 0x04 }; enum TorStatus @@ -97,6 +98,7 @@ public: /* Connection */ bool isConnected() const { return status() == Connected; } void connect(const std::string &address, uint16_t port); + void authenticate(); /* Ownership means that tor is managed by this socket, and we * can shut it down, own its configuration, etc. */ @@ -159,7 +161,6 @@ private: void publishServices(); void protocolInfoReply(TorControlCommand *sender); void socketDisconnected(); - void socketConnected(); void authenticateReply(TorControlCommand *sender); std::function mStatusChanged_callback; diff --git a/libretroshare/src/tor/TorControlSocket.cpp b/libretroshare/src/tor/TorControlSocket.cpp index f2142e1d1..40beb95ee 100644 --- a/libretroshare/src/tor/TorControlSocket.cpp +++ b/libretroshare/src/tor/TorControlSocket.cpp @@ -49,9 +49,9 @@ TorControlSocket::~TorControlSocket() clear(); } -void TorControlSocket::connectToHost(const std::string& tcp_address,uint16_t tcp_port) +bool TorControlSocket::connectToHost(const std::string& tcp_address,uint16_t tcp_port) { - RsTcpSocket::connect(tcp_address,tcp_port); + return RsTcpSocket::connect(tcp_address,tcp_port); } std::string TorControlSocket::peerAddress() const { diff --git a/libretroshare/src/tor/TorControlSocket.h b/libretroshare/src/tor/TorControlSocket.h index 779fd6da5..b5ba4181c 100644 --- a/libretroshare/src/tor/TorControlSocket.h +++ b/libretroshare/src/tor/TorControlSocket.h @@ -54,7 +54,7 @@ public: std::string errorMessage() const { return m_errorMessage; } - void connectToHost(const std::string& tcp_address,uint16_t tcp_port); + bool connectToHost(const std::string& tcp_address,uint16_t tcp_port); void registerEvent(const ByteArray &event, TorControlCommand *handler); void sendCommand(const ByteArray& data) { sendCommand(0, data); } diff --git a/libretroshare/src/tor/TorManager.cpp b/libretroshare/src/tor/TorManager.cpp index c4e012de8..c63b38e11 100644 --- a/libretroshare/src/tor/TorManager.cpp +++ b/libretroshare/src/tor/TorManager.cpp @@ -463,6 +463,29 @@ void TorManager::run() void TorManager::threadTick() { d->process->tick(); + + if(d->process->state() != TorProcess::Ready) + return; + + switch(d->control->status()) + { + case TorControl::NotConnected: + RsDbg() << "Connecting to tor process at " << d->process->controlHost() << ":" << d->process->controlPort() << "..." ; + d->control->connect(d->process->controlHost(),d->process->controlPort()); + break; + + case TorControl::SocketConnected: + RsDbg() << "Connection established." ; + d->control->authenticate(); + break; + + case TorControl::Authenticating: + RsDbg() << "Authenticating..." ; + break; + + case TorControl::Connected:; + break; + } } bool TorManager::getProxyServerInfo(std::string& proxy_server_adress,uint16_t& proxy_server_port) From af4c948024b0405bd5361fdd430be6617498e57c Mon Sep 17 00:00:00 2001 From: csoler Date: Fri, 17 Dec 2021 16:54:44 +0100 Subject: [PATCH 31/65] fixed some bugs in TorControl --- libretroshare/src/pqi/pqifdbin.cc | 4 +- libretroshare/src/pqi/rstcpsocket.cc | 6 --- libretroshare/src/retroshare/rstor.h | 12 +++--- libretroshare/src/tor/CryptoKey.cpp | 16 +++++++- libretroshare/src/tor/PendingOperation.cpp | 10 ++--- libretroshare/src/tor/PendingOperation.h | 8 ++-- libretroshare/src/tor/SetConfCommand.cpp | 2 +- libretroshare/src/tor/TorControl.cpp | 38 ++++++++++++------- libretroshare/src/tor/TorControl.h | 16 ++++---- libretroshare/src/tor/TorControlCommand.cpp | 4 +- libretroshare/src/tor/TorControlSocket.cpp | 9 ++++- libretroshare/src/tor/TorManager.cpp | 34 +++++++++++++---- libretroshare/src/tor/TorProcess.cpp | 8 +++- libretroshare/src/tor/bytearray.h | 14 +++++-- .../src/TorControl/TorControlWindow.cpp | 6 ++- .../src/gui/statusbar/torstatus.cpp | 2 +- retroshare-gui/src/main.cpp | 2 +- 17 files changed, 128 insertions(+), 63 deletions(-) diff --git a/libretroshare/src/pqi/pqifdbin.cc b/libretroshare/src/pqi/pqifdbin.cc index a982d670c..9a3d7ca2e 100644 --- a/libretroshare/src/pqi/pqifdbin.cc +++ b/libretroshare/src/pqi/pqifdbin.cc @@ -97,8 +97,8 @@ int RsFdBinInterface::read_pending() if(readbytes > 0) { - RsDbg() << "Received the following bytes: " << RsUtil::BinToHex( reinterpret_cast(inBuffer),readbytes,50) << std::endl; - //RsDbg() << "Received the following bytes: " << std::string(inBuffer,readbytes) << std::endl; + //RsDbg() << "Received the following bytes: " << RsUtil::BinToHex( reinterpret_cast(inBuffer),readbytes,50) << std::endl; + RsDbg() << "Received the following bytes: " << std::string(inBuffer,readbytes) << std::endl; void *ptr = malloc(readbytes); diff --git a/libretroshare/src/pqi/rstcpsocket.cc b/libretroshare/src/pqi/rstcpsocket.cc index e104da46e..1c8848941 100644 --- a/libretroshare/src/pqi/rstcpsocket.cc +++ b/libretroshare/src/pqi/rstcpsocket.cc @@ -75,12 +75,6 @@ RsThreadedTcpSocket::RsThreadedTcpSocket() : RsTcpSocket() } void RsThreadedTcpSocket::run() { - if(!connect()) - { - RsErr() << "Cannot connect socket to " << connectAddress() << ":" << connectPort() ; - return ; - } - while(connectionState() == CONNECTED) { tick(); diff --git a/libretroshare/src/retroshare/rstor.h b/libretroshare/src/retroshare/rstor.h index 347d8b1c7..0ae966a7e 100644 --- a/libretroshare/src/retroshare/rstor.h +++ b/libretroshare/src/retroshare/rstor.h @@ -53,11 +53,13 @@ enum class RsTorHiddenServiceStatus: uint8_t { // Status of the connection/authentication between RS and the Tor service enum class RsTorConnectivityStatus: uint8_t { - ERROR = 0x00, - NOT_CONNECTED = 0x01, - CONNECTING = 0x02, - AUTHENTICATING = 0x03, - CONNECTED = 0x04 + ERROR = 0x00, + NOT_CONNECTED = 0x01, + CONNECTING = 0x02, + AUTHENTICATING = 0x03, + AUTHENTICATED = 0x04, + HIDDEN_SERVICE_READY = 0x05, + UNKNOWN = 0x06 }; // Status of the Tor service with which RS is talking. diff --git a/libretroshare/src/tor/CryptoKey.cpp b/libretroshare/src/tor/CryptoKey.cpp index 641c1e4dc..95fdab016 100644 --- a/libretroshare/src/tor/CryptoKey.cpp +++ b/libretroshare/src/tor/CryptoKey.cpp @@ -135,8 +135,20 @@ ByteArray torControlHashedPassword(const ByteArray &password) uint32_t count = ((uint32_t)16 + (96 & 15)) << ((96 >> 4) + 6); - Sha1CheckSum md = RsDirUtil::sha1sum((salt+password).data(),count); + SHA_CTX hash; + SHA1_Init(&hash); + + ByteArray tmp = salt + password; + while (count) + { + int c = std::min((size_t)count, tmp.size()); + SHA1_Update(&hash, reinterpret_cast(tmp.data()), c); + count -= c; + } + + unsigned char md[20]; + SHA1_Final(md, &hash); /* 60 is the hex-encoded value of 96, which is a constant used by Tor's algorithm. */ - return ByteArray("16:") + salt.toHex().toUpper() + ByteArray("60") + ByteArray(md.toByteArray(), md.SIZE_IN_BYTES).toHex().toUpper(); + return ByteArray("16:") + salt.toHex().toUpper() + ByteArray("60") + ByteArray(md, 20).toHex().toUpper(); } diff --git a/libretroshare/src/tor/PendingOperation.cpp b/libretroshare/src/tor/PendingOperation.cpp index e22f63852..cbfb8897c 100644 --- a/libretroshare/src/tor/PendingOperation.cpp +++ b/libretroshare/src/tor/PendingOperation.cpp @@ -34,7 +34,7 @@ #include "PendingOperation.h" PendingOperation::PendingOperation() - : m_finished(false) + : m_finished(false),mFinishedCallback([](){}), mSuccessCallback([](){}),mErrorCallback([](const std::string&){}) { } @@ -67,8 +67,8 @@ void PendingOperation::finishWithError(const std::string &message) if (!m_finished) { m_finished = true; - finished_callback(); - error_callback(m_errorMessage); + mFinishedCallback(); + mErrorCallback(m_errorMessage); } } @@ -78,9 +78,9 @@ void PendingOperation::finishWithSuccess() if (!m_finished) { m_finished = true; - finished_callback(); + mFinishedCallback(); if (isSuccess()) - success_callback(); + mSuccessCallback(); } } diff --git a/libretroshare/src/tor/PendingOperation.h b/libretroshare/src/tor/PendingOperation.h index 5965bfd26..4a75b1c9e 100644 --- a/libretroshare/src/tor/PendingOperation.h +++ b/libretroshare/src/tor/PendingOperation.h @@ -74,14 +74,14 @@ public: void finishWithError(const std::string &errorMessage); void finishWithSuccess(); - void set_finished_callback(const std::function& f) { finished_callback = f; } + void set_finished_callback(const std::function& f) { mFinishedCallback = f; } private: bool m_finished; std::string m_errorMessage; - std::function finished_callback; - std::function success_callback; - std::function error_callback; + std::function mFinishedCallback; + std::function mSuccessCallback; + std::function mErrorCallback; }; diff --git a/libretroshare/src/tor/SetConfCommand.cpp b/libretroshare/src/tor/SetConfCommand.cpp index f4660d2c5..0285c8c8b 100644 --- a/libretroshare/src/tor/SetConfCommand.cpp +++ b/libretroshare/src/tor/SetConfCommand.cpp @@ -36,7 +36,7 @@ using namespace Tor; SetConfCommand::SetConfCommand() - : m_resetMode(false) + : m_resetMode(false), mConfSucceeded([](){}), mConfFailed([](int){}) { } diff --git a/libretroshare/src/tor/TorControl.cpp b/libretroshare/src/tor/TorControl.cpp index ac13ddcab..579077bad 100644 --- a/libretroshare/src/tor/TorControl.cpp +++ b/libretroshare/src/tor/TorControl.cpp @@ -143,7 +143,7 @@ static RsTorConnectivityStatus torConnectivityStatus(Tor::TorControl::Status t) case TorControl::NotConnected: return RsTorConnectivityStatus::NOT_CONNECTED; case TorControl::Connecting: return RsTorConnectivityStatus::CONNECTING; case TorControl::Authenticating: return RsTorConnectivityStatus::AUTHENTICATING; - case TorControl::Connected: return RsTorConnectivityStatus::CONNECTED; + case TorControl::Authenticated: return RsTorConnectivityStatus::AUTHENTICATED; } } static RsTorStatus torStatus(Tor::TorControl::TorStatus t) @@ -173,6 +173,7 @@ void TorControl::setStatus(TorControl::Status n) auto ev = std::make_shared(); ev->mTorManagerEventType = RsTorManagerEventCode::TOR_STATUS_CHANGED; + ev->mTorStatus = ::torStatus(mTorStatus); ev->mTorConnectivityStatus = torConnectivityStatus(mStatus); rsEvents->sendEvent(ev); @@ -198,13 +199,10 @@ void TorControl::setTorStatus(TorControl::TorStatus n) auto ev = std::make_shared(); ev->mTorManagerEventType = RsTorManagerEventCode::TOR_STATUS_CHANGED; + ev->mTorConnectivityStatus = torConnectivityStatus(mStatus); ev->mTorStatus = ::torStatus(mTorStatus); rsEvents->sendEvent(ev); } - if (mTorStatus == TorControl::TorReady && mSocksAddress.empty()) { - // Request info again to read the SOCKS port - getTorInfo(); - } } void TorControl::setError(const std::string &message) @@ -213,10 +211,6 @@ void TorControl::setError(const std::string &message) setStatus(TorControl::Error); RsWarn() << "torctrl: Error:" << mErrorMessage; - - mSocket->fullstop(); - - reconnect(); } TorControl::Status TorControl::status() const @@ -317,7 +311,7 @@ void TorControl::authenticateReply(TorControlCommand *sender) } torCtrlDebug() << "torctrl: Authentication successful" << std::endl; - setStatus(TorControl::Connected); + setStatus(TorControl::Authenticated); setTorStatus(TorControl::TorUnknown); @@ -343,8 +337,8 @@ void TorControl::authenticate() { assert(mStatus == TorControl::SocketConnected); - torCtrlDebug() << "torctrl: Connected socket; querying information" << std::endl; setStatus(TorControl::Authenticating); + torCtrlDebug() << "torctrl: Connected socket; querying information for authentication" << std::endl; ProtocolInfoCommand *command = new ProtocolInfoCommand(this); @@ -437,7 +431,7 @@ void TorControl::protocolInfoReply(TorControlCommand *sender) else if ((methods & ProtocolInfoCommand::AuthHashedPassword) && !mAuthPassword.empty()) { usePasswordAuth: - torCtrlDebug() << "torctrl: Using hashed password authentication" << std::endl; + torCtrlDebug() << "torctrl: Using hashed password authentication with AuthPasswd=\"" << mAuthPassword.toString() << "\"" << std::endl; data = auth->build(mAuthPassword); } else @@ -526,6 +520,8 @@ void TorControl::getTorInfoReply(TorControlCommand *sender) auto ev = std::make_shared(); ev->mTorManagerEventType = RsTorManagerEventCode::TOR_CONNECTIVITY_CHANGED; + ev->mTorConnectivityStatus = torConnectivityStatus(mStatus); + ev->mTorStatus = ::torStatus(mTorStatus); rsEvents->sendEvent(ev); } } @@ -586,7 +582,7 @@ void TorControl::publishServices() torCtrlDebug() << "torctrl: Publishing hidden service: " << service->hostname() << std::endl; AddOnionCommand *onionCommand = new AddOnionCommand(service); //protocolInfoReplyQObject::connect(onionCommand, &AddOnionCommand::succeeded, service, &HiddenService::servicePublished); - onionCommand->set_succeeded_callback( [service]() { service->servicePublished(); }); + onionCommand->set_succeeded_callback( [this,service]() { checkHiddenService(service) ; }); mSocket->sendCommand(onionCommand, onionCommand->build()); } } else { @@ -618,7 +614,7 @@ void TorControl::publishServices() torConfig.push_back(std::make_pair("HiddenServicePort", target)); } - command->set_ConfSucceeded_callback( [service]() { service->servicePublished(); }); + command->set_ConfSucceeded_callback( [this,service]() { checkHiddenService(service); }); //QObject::connect(command, &SetConfCommand::setConfSucceeded, service, &HiddenService::servicePublished); } @@ -627,6 +623,18 @@ void TorControl::publishServices() } } +void TorControl::checkHiddenService(HiddenService *service) +{ + service->servicePublished(); + + if(service->status() == HiddenService::Online) + { + RsDbg() << "Hidden service published and ready!" ; + + setStatus(TorControl::HiddenServiceReady); + } +} + void TorControl::shutdown() { if (!hasOwnership()) { @@ -697,6 +705,8 @@ void TorControl::updateBootstrap(const std::list &data) auto ev = std::make_shared(); ev->mTorManagerEventType = RsTorManagerEventCode::BOOTSTRAP_STATUS_CHANGED; + ev->mTorConnectivityStatus = torConnectivityStatus(mStatus); + ev->mTorStatus = ::torStatus(mTorStatus); rsEvents->sendEvent(ev); } } diff --git a/libretroshare/src/tor/TorControl.h b/libretroshare/src/tor/TorControl.h index 13aad5c9e..6936e6653 100644 --- a/libretroshare/src/tor/TorControl.h +++ b/libretroshare/src/tor/TorControl.h @@ -65,11 +65,12 @@ public: enum Status { Error = -1, - NotConnected = 0x00, - Connecting = 0x01, - SocketConnected= 0x02, - Authenticating = 0x03, - Connected = 0x04 + NotConnected = 0x00, + Connecting = 0x01, + SocketConnected = 0x02, + Authenticating = 0x03, + Authenticated = 0x04, + HiddenServiceReady = 0x05, }; enum TorStatus @@ -96,7 +97,7 @@ public: void setAuthPassword(const ByteArray& password); /* Connection */ - bool isConnected() const { return status() == Connected; } + bool isConnected() const { return status() == Authenticated; } void connect(const std::string &address, uint16_t port); void authenticate(); @@ -137,6 +138,7 @@ public: void reconnect(); + void getTorInfo(); private: TorControlSocket *mSocket; std::string mTorAddress; @@ -151,7 +153,7 @@ private: std::map mBootstrapStatus; bool mHasOwnership; - void getTorInfo(); + void checkHiddenService(HiddenService *service); void getTorInfoReply(TorControlCommand *sender); void setStatus(TorControl::Status n); void statusEvent(int code, const ByteArray &data); diff --git a/libretroshare/src/tor/TorControlCommand.cpp b/libretroshare/src/tor/TorControlCommand.cpp index 67e02169a..2bfc17a71 100644 --- a/libretroshare/src/tor/TorControlCommand.cpp +++ b/libretroshare/src/tor/TorControlCommand.cpp @@ -35,7 +35,9 @@ using namespace Tor; TorControlCommand::TorControlCommand() - : m_finalStatus(0) + : m_finalStatus(0), + mReplyLine ( std::function([](int, const ByteArray &){})), + mFinished ( std::function([](TorControlCommand*){})) { } diff --git a/libretroshare/src/tor/TorControlSocket.cpp b/libretroshare/src/tor/TorControlSocket.cpp index 40beb95ee..5d69dc7de 100644 --- a/libretroshare/src/tor/TorControlSocket.cpp +++ b/libretroshare/src/tor/TorControlSocket.cpp @@ -51,7 +51,14 @@ TorControlSocket::~TorControlSocket() bool TorControlSocket::connectToHost(const std::string& tcp_address,uint16_t tcp_port) { - return RsTcpSocket::connect(tcp_address,tcp_port); + if(RsTcpSocket::connect(tcp_address,tcp_port)) + { + start(); + return true; + } + else + return false; + } std::string TorControlSocket::peerAddress() const { diff --git a/libretroshare/src/tor/TorManager.cpp b/libretroshare/src/tor/TorManager.cpp index c63b38e11..338db478a 100644 --- a/libretroshare/src/tor/TorManager.cpp +++ b/libretroshare/src/tor/TorManager.cpp @@ -419,6 +419,8 @@ bool TorManager::startTorManager() { auto ev = std::make_shared(); ev->mTorManagerEventType = RsTorManagerEventCode::CONFIGURATION_NEEDED; + ev->mTorConnectivityStatus = RsTorConnectivityStatus::UNKNOWN; + ev->mTorStatus = RsTorStatus::UNKNOWN; rsEvents->sendEvent(ev); } //emit configurationNeededChanged(); @@ -469,6 +471,9 @@ void TorManager::threadTick() switch(d->control->status()) { + case TorControl::Connecting: + break; + case TorControl::NotConnected: RsDbg() << "Connecting to tor process at " << d->process->controlHost() << ":" << d->process->controlPort() << "..." ; d->control->connect(d->process->controlHost(),d->process->controlPort()); @@ -476,6 +481,7 @@ void TorManager::threadTick() case TorControl::SocketConnected: RsDbg() << "Connection established." ; + d->control->setAuthPassword(d->process->controlPassword()); d->control->authenticate(); break; @@ -483,7 +489,20 @@ void TorManager::threadTick() RsDbg() << "Authenticating..." ; break; - case TorControl::Connected:; + case TorControl::Authenticated:; + + RsDbg() << "Authenticated. Looking for hidden services."; + + for(auto service:d->control->hiddenServices()) + if(service->status() == HiddenService::Online) + { + + } + break; + + case TorControl::Error: + d->control->shutdown(); + d->control->reconnect(); break; } } @@ -549,7 +568,7 @@ void TorManagerPrivate::processLogMessage(const std::string &message) void TorManagerPrivate::controlStatusChanged(int status) { - if (status == TorControl::Connected) { + if (status == TorControl::Authenticated) { if (!configNeeded) { // If DisableNetwork is 1, trigger configurationNeeded auto cmd = control->getConfiguration("DisableNetwork"); @@ -738,11 +757,12 @@ RsTorConnectivityStatus RsTor::torConnectivityStatus() switch(ts) { default: - case Tor::TorControl::Error : return RsTorConnectivityStatus::ERROR; - case Tor::TorControl::NotConnected : return RsTorConnectivityStatus::NOT_CONNECTED; - case Tor::TorControl::Authenticating: return RsTorConnectivityStatus::AUTHENTICATING; - case Tor::TorControl::Connecting: return RsTorConnectivityStatus::CONNECTING; - case Tor::TorControl::Connected : return RsTorConnectivityStatus::CONNECTED; + case Tor::TorControl::Error : return RsTorConnectivityStatus::ERROR; + case Tor::TorControl::NotConnected : return RsTorConnectivityStatus::NOT_CONNECTED; + case Tor::TorControl::Authenticating: return RsTorConnectivityStatus::AUTHENTICATING; + case Tor::TorControl::Connecting: return RsTorConnectivityStatus::CONNECTING; + case Tor::TorControl::Authenticated : return RsTorConnectivityStatus::AUTHENTICATED; + case Tor::TorControl::HiddenServiceReady : return RsTorConnectivityStatus::HIDDEN_SERVICE_READY; } } diff --git a/libretroshare/src/tor/TorProcess.cpp b/libretroshare/src/tor/TorProcess.cpp index 3142e9488..c33fbb876 100644 --- a/libretroshare/src/tor/TorProcess.cpp +++ b/libretroshare/src/tor/TorProcess.cpp @@ -205,6 +205,8 @@ void TorProcess::start() if(m_client) m_client->processErrorChanged(mErrorMessage);// emit errorMessageChanged(d->errorMessage); if(m_client) m_client->processStateChanged(mState); // emit stateChanged(d->state); } + else + RsDbg() << "Using ControlPasswd=\"" << password.toString() << "\", hashed version=\"" << hashedPassword.toString() << "\"" ; mState = Starting; @@ -235,7 +237,7 @@ void TorProcess::start() args.push_back(mDataDir); args.push_back("HashedControlPassword") ; - args.push_back(torControlHashedPassword(mControlPassword).toString()); + args.push_back(hashedPassword.toString()); args.push_back("ControlPort") ; args.push_back("auto"); @@ -303,12 +305,14 @@ void TorProcess::tick() if(tryReadControlPort()) { mState = Ready; - // stateChanged(mState); + m_client->processStateChanged(mState);// stateChanged(mState); } else if(mControlPortReadNbTries > 10) { //errorMessageChanged(errorMessage); //stateChanged(state); + mState = Failed; + m_client->processStateChanged(mState);// stateChanged(mState); } } } diff --git a/libretroshare/src/tor/bytearray.h b/libretroshare/src/tor/bytearray.h index 6d8897ae9..f2c1903cf 100644 --- a/libretroshare/src/tor/bytearray.h +++ b/libretroshare/src/tor/bytearray.h @@ -15,8 +15,8 @@ class ByteArray: public std::vector { public: ByteArray() =default; - ByteArray(int n) : std::vector(n) {} - ByteArray(const unsigned char *d,int n) : std::vector(n) { memcpy(data(),d,n); } + explicit ByteArray(int n) : std::vector(n) {} + explicit ByteArray(const unsigned char *d,int n) : std::vector(n) { memcpy(data(),d,n); } virtual ~ByteArray() =default; ByteArray(const std::string& c) { resize(c.size()); memcpy(data(),c.c_str(),c.size()); } @@ -34,6 +34,7 @@ public: template void append(const T) = delete;// Prevents any implicit when calling the preceding functions which actually causes real bugs. + ByteArray& operator+=(char b) { push_back(b); return *this; } ByteArray& operator+=(const ByteArray& b) { for(auto c:b) push_back(c); return *this; } ByteArray& operator+=(const char *b) { for(uint32_t n=0;b[n]!=0;++n) push_back(b[n]); return *this;} @@ -51,6 +52,7 @@ public: return res; } bool endsWith(const ByteArray& b) const { return size() >= b.size() && !memcmp(&data()[size()-b.size()],b.data(),b.size()); } + bool endsWith(char b) const { return size() > 0 && back()==b; } bool startsWith(const ByteArray& b) const { return b.size() <= size() && !strncmp((char*)b.data(),(char*)data(),std::min(size(),b.size())); } bool startsWith(const char *b) const { @@ -121,7 +123,10 @@ public: current_block.clear(); } else - current_block += operator[](i); + current_block += (*this)[i]; + + if(!current_block.empty()) + res.push_back(current_block); return res; } @@ -142,6 +147,9 @@ public: else current_block += operator[](i); + if(!current_block.empty()) + res.push_back(current_block); + return res; } diff --git a/retroshare-gui/src/TorControl/TorControlWindow.cpp b/retroshare-gui/src/TorControl/TorControlWindow.cpp index b38d02038..7ec6f0392 100644 --- a/retroshare-gui/src/TorControl/TorControlWindow.cpp +++ b/retroshare-gui/src/TorControl/TorControlWindow.cpp @@ -90,7 +90,7 @@ void TorControlDialog::statusChanged(RsTorStatus torstatus, RsTorConnectivitySta case RsTorConnectivityStatus::NOT_CONNECTED: tor_control_status_str = tr("Not connected") ; break ; case RsTorConnectivityStatus::CONNECTING: tor_control_status_str = tr("Connecting") ; break ; case RsTorConnectivityStatus::AUTHENTICATING: tor_control_status_str = tr("Authenticating") ; break ; - case RsTorConnectivityStatus::CONNECTED: tor_control_status_str = tr("Connected") ; break ; + case RsTorConnectivityStatus::AUTHENTICATED: tor_control_status_str = tr("Authenticated") ; break ; } switch(torstatus) @@ -195,6 +195,10 @@ TorControlDialog::HiddenServiceStatus TorControlDialog::checkForHiddenService() switch(mHiddenServiceStatus) { default: + case HIDDEN_SERVICE_STATUS_FAIL: { + std::cerr << " Hidden service setup failed. Something's wrong." << std::endl; + return mHiddenServiceStatus; + } case HIDDEN_SERVICE_STATUS_UNKNOWN: { std::cerr << " trying to setup. " ; diff --git a/retroshare-gui/src/gui/statusbar/torstatus.cpp b/retroshare-gui/src/gui/statusbar/torstatus.cpp index 319d8da3d..44de873ae 100644 --- a/retroshare-gui/src/gui/statusbar/torstatus.cpp +++ b/retroshare-gui/src/gui/statusbar/torstatus.cpp @@ -104,7 +104,7 @@ void TorStatus::getTorStatus() case RsTorConnectivityStatus::NOT_CONNECTED: tor_control_ok = false ; tor_control_status_str = "Not connected" ; break ; case RsTorConnectivityStatus::CONNECTING: tor_control_ok = false ; tor_control_status_str = "Connecting" ; break ; case RsTorConnectivityStatus::AUTHENTICATING: tor_control_ok = false ; tor_control_status_str = "Authenticating" ; break ; - case RsTorConnectivityStatus::CONNECTED: tor_control_ok = true ; tor_control_status_str = "Connected" ; break ; + case RsTorConnectivityStatus::AUTHENTICATED: tor_control_ok = true ; tor_control_status_str = "Connected" ; break ; } switch(torstatus) diff --git a/retroshare-gui/src/main.cpp b/retroshare-gui/src/main.cpp index 104f525a8..56495d592 100644 --- a/retroshare-gui/src/main.cpp +++ b/retroshare-gui/src/main.cpp @@ -406,7 +406,7 @@ feenableexcept(FE_INVALID | FE_DIVBYZERO); RsDirUtil::checkCreateDirectory(std::string(tor_hidden_service_dir)) ; - RsTor::setupHiddenService(); + //RsTor::setupHiddenService(); if(! RsTor::start() || RsTor::hasError()) { From 3121a61910eb0c90fe532a2c2ef84e92b0ff07ef Mon Sep 17 00:00:00 2001 From: csoler Date: Fri, 17 Dec 2021 22:17:26 +0100 Subject: [PATCH 32/65] more bug fixing --- libretroshare/src/tor/ProtocolInfoCommand.cpp | 2 +- libretroshare/src/tor/TorControl.cpp | 15 +++-- libretroshare/src/tor/TorControl.h | 2 +- libretroshare/src/tor/TorManager.cpp | 16 +++-- .../src/TorControl/TorControlWindow.cpp | 65 +++++-------------- .../src/TorControl/TorControlWindow.h | 1 - 6 files changed, 39 insertions(+), 62 deletions(-) diff --git a/libretroshare/src/tor/ProtocolInfoCommand.cpp b/libretroshare/src/tor/ProtocolInfoCommand.cpp index 867541e56..cdb7d648b 100644 --- a/libretroshare/src/tor/ProtocolInfoCommand.cpp +++ b/libretroshare/src/tor/ProtocolInfoCommand.cpp @@ -37,7 +37,7 @@ using namespace Tor; ProtocolInfoCommand::ProtocolInfoCommand(TorControl *m) - : manager(m) + : manager(m),m_authMethods(0) { } diff --git a/libretroshare/src/tor/TorControl.cpp b/libretroshare/src/tor/TorControl.cpp index 579077bad..f5c9dc2f6 100644 --- a/libretroshare/src/tor/TorControl.cpp +++ b/libretroshare/src/tor/TorControl.cpp @@ -863,15 +863,14 @@ bool TorControl::torVersionAsNewAs(const std::string& match) const int split_size = split.size(); int i=0; - const auto& b_split(split.begin()); + auto b_split(split.begin()); + auto b_matchsplit(matchSplit.begin()); - for(const auto& b_matchsplit:matchSplit) + for(int i=0;;) { - if (i >= split_size) - return false; int currentVal,matchVal; bool ok1 = RsUtil::StringToInt((*b_split).toString(),currentVal); - bool ok2 = RsUtil::StringToInt(b_matchsplit.toString(),matchVal); + bool ok2 = RsUtil::StringToInt((*b_matchsplit).toString(),matchVal); if (!ok1 || !ok2) return false; @@ -881,6 +880,12 @@ bool TorControl::torVersionAsNewAs(const std::string& match) const return false; ++i; + + if(i >= split_size) + return false; + + ++b_split; + ++b_matchsplit; } // Versions are equal, up to the length of match diff --git a/libretroshare/src/tor/TorControl.h b/libretroshare/src/tor/TorControl.h index 6936e6653..8d26e20dd 100644 --- a/libretroshare/src/tor/TorControl.h +++ b/libretroshare/src/tor/TorControl.h @@ -70,7 +70,7 @@ public: SocketConnected = 0x02, Authenticating = 0x03, Authenticated = 0x04, - HiddenServiceReady = 0x05, + HiddenServiceReady = 0x05 }; enum TorStatus diff --git a/libretroshare/src/tor/TorManager.cpp b/libretroshare/src/tor/TorManager.cpp index 338db478a..d33075328 100644 --- a/libretroshare/src/tor/TorManager.cpp +++ b/libretroshare/src/tor/TorManager.cpp @@ -481,6 +481,13 @@ void TorManager::threadTick() case TorControl::SocketConnected: RsDbg() << "Connection established." ; + + if(d->hiddenService == nullptr) + { + RsDbg() << "Setting up hidden service" ; + setupHiddenService(); + } + d->control->setAuthPassword(d->process->controlPassword()); d->control->authenticate(); break; @@ -489,15 +496,12 @@ void TorManager::threadTick() RsDbg() << "Authenticating..." ; break; - case TorControl::Authenticated:; + case TorControl::Authenticated: RsDbg() << "Authenticated. Looking for hidden services."; + break; - for(auto service:d->control->hiddenServices()) - if(service->status() == HiddenService::Online) - { - - } + case TorControl::HiddenServiceReady: break; case TorControl::Error: diff --git a/retroshare-gui/src/TorControl/TorControlWindow.cpp b/retroshare-gui/src/TorControl/TorControlWindow.cpp index 7ec6f0392..31a2aa78c 100644 --- a/retroshare-gui/src/TorControl/TorControlWindow.cpp +++ b/retroshare-gui/src/TorControl/TorControlWindow.cpp @@ -36,7 +36,6 @@ TorControlDialog::TorControlDialog(QWidget *) //QTimer::singleShot(2000,this,SLOT(checkForHiddenService())) ; mIncomingServer = new QTcpServer(this) ; - mHiddenServiceStatus = HIDDEN_SERVICE_STATUS_UNKNOWN; connect(mIncomingServer, SIGNAL(QTcpServer::newConnection()), this, SLOT(onIncomingConnection())); @@ -192,63 +191,33 @@ TorControlDialog::HiddenServiceStatus TorControlDialog::checkForHiddenService() { std::cerr << "Checking for hidden services:" ; - switch(mHiddenServiceStatus) + std::string service_id; + + RsTorHiddenServiceStatus service_status = RsTor::getHiddenServiceStatus(service_id); + + if(service_id.empty()) { - default: - case HIDDEN_SERVICE_STATUS_FAIL: { - std::cerr << " Hidden service setup failed. Something's wrong." << std::endl; - return mHiddenServiceStatus; + std::cerr << "Not ready yet." << std::endl; + return HIDDEN_SERVICE_STATUS_REQUESTED ; } - case HIDDEN_SERVICE_STATUS_UNKNOWN: { + else + { + if(mHiddenService.empty()) + mHiddenService = service_id ; - std::cerr << " trying to setup. " ; + std::cerr << "New service acquired. Status is " << (int)service_status ; - if(!RsTor::setupHiddenService()) + if(service_status == RsTorHiddenServiceStatus::ONLINE) { - mHiddenServiceStatus = HIDDEN_SERVICE_STATUS_FAIL ; - std::cerr << "Failed." << std::endl; - return mHiddenServiceStatus ; - } - std::cerr << "Done." << std::endl; - mHiddenServiceStatus = HIDDEN_SERVICE_STATUS_REQUESTED ; - return mHiddenServiceStatus ; - } + std::cerr << ": published and running!" << std::endl; - case HIDDEN_SERVICE_STATUS_REQUESTED: { - - std::string service_id; - - RsTorHiddenServiceStatus service_status = RsTor::getHiddenServiceStatus(service_id); - - if(service_id.empty()) - { - std::cerr << "Not ready yet." << std::endl; - return mHiddenServiceStatus ; + return HIDDEN_SERVICE_STATUS_OK ; } else { - if(mHiddenService.empty()) - mHiddenService = service_id ; - - std::cerr << "New service acquired. Status is " << (int)service_status ; - - if(service_status == RsTorHiddenServiceStatus::ONLINE) - { - mHiddenServiceStatus = HIDDEN_SERVICE_STATUS_OK ; - std::cerr << ": published and running!" << std::endl; - - return mHiddenServiceStatus ; - } - else - { - std::cerr << ": not ready yet." << std::endl; - return mHiddenServiceStatus ; - } + std::cerr << ": not ready yet." << std::endl; + return HIDDEN_SERVICE_STATUS_REQUESTED ; } } - case HIDDEN_SERVICE_STATUS_OK : - std::cerr << "New service acquired." << std::endl; - return mHiddenServiceStatus ; - } } diff --git a/retroshare-gui/src/TorControl/TorControlWindow.h b/retroshare-gui/src/TorControl/TorControlWindow.h index 5fc23e8e9..7dc8c8bda 100644 --- a/retroshare-gui/src/TorControl/TorControlWindow.h +++ b/retroshare-gui/src/TorControl/TorControlWindow.h @@ -42,7 +42,6 @@ protected slots: void handleEvent_main_thread(std::shared_ptr event); private: QString mErrorMsg ; - HiddenServiceStatus mHiddenServiceStatus ; std::string mHiddenService; QTcpServer *mIncomingServer ; From bdbcadc43cf3aee5f639288984fe8c5755f87418 Mon Sep 17 00:00:00 2001 From: csoler Date: Fri, 17 Dec 2021 22:26:32 +0100 Subject: [PATCH 33/65] fixed Tor icon to stay red --- libretroshare/src/tor/TorManager.cpp | 12 +++++++++++- libretroshare/src/tor/TorManager.h | 2 +- retroshare-gui/src/gui/statusbar/torstatus.cpp | 5 +++-- 3 files changed, 15 insertions(+), 4 deletions(-) diff --git a/libretroshare/src/tor/TorManager.cpp b/libretroshare/src/tor/TorManager.cpp index d33075328..dd1c1f810 100644 --- a/libretroshare/src/tor/TorManager.cpp +++ b/libretroshare/src/tor/TorManager.cpp @@ -262,9 +262,19 @@ bool TorManager::setupHiddenService() return true ; } -void TorManager::hiddenServiceStatusChanged(int old_status,int new_status) +void TorManager::hiddenServiceStatusChanged(int new_status,int old_status) { std::cerr << "Hidden service status changed from " << old_status << " to " << new_status << std::endl; + + if(rsEvents) + { + auto ev = std::make_shared(); + ev->mTorManagerEventType = RsTorManagerEventCode::TOR_STATUS_CHANGED; + ev->mTorConnectivityStatus = RsTorConnectivityStatus::HIDDEN_SERVICE_READY; + ev->mTorStatus = RsTorStatus::READY; + + rsEvents->sendEvent(ev); + } } void TorManager::hiddenServicePrivateKeyChanged() diff --git a/libretroshare/src/tor/TorManager.h b/libretroshare/src/tor/TorManager.h index 555192852..c9a5e3769 100644 --- a/libretroshare/src/tor/TorManager.h +++ b/libretroshare/src/tor/TorManager.h @@ -92,7 +92,7 @@ public: virtual void hiddenServiceOnline() override {} // do nothing here. virtual void hiddenServicePrivateKeyChanged() override; virtual void hiddenServiceHostnameChanged() override; - virtual void hiddenServiceStatusChanged(int old_status,int new_status) override; + virtual void hiddenServiceStatusChanged(int new_status, int old_status) override; // Thread stuff diff --git a/retroshare-gui/src/gui/statusbar/torstatus.cpp b/retroshare-gui/src/gui/statusbar/torstatus.cpp index 44de873ae..c141ef0ce 100644 --- a/retroshare-gui/src/gui/statusbar/torstatus.cpp +++ b/retroshare-gui/src/gui/statusbar/torstatus.cpp @@ -104,8 +104,9 @@ void TorStatus::getTorStatus() case RsTorConnectivityStatus::NOT_CONNECTED: tor_control_ok = false ; tor_control_status_str = "Not connected" ; break ; case RsTorConnectivityStatus::CONNECTING: tor_control_ok = false ; tor_control_status_str = "Connecting" ; break ; case RsTorConnectivityStatus::AUTHENTICATING: tor_control_ok = false ; tor_control_status_str = "Authenticating" ; break ; - case RsTorConnectivityStatus::AUTHENTICATED: tor_control_ok = true ; tor_control_status_str = "Connected" ; break ; - } + case RsTorConnectivityStatus::AUTHENTICATED: tor_control_ok = false ; tor_control_status_str = "Connected" ; break ; + case RsTorConnectivityStatus::HIDDEN_SERVICE_READY: tor_control_ok = true ; tor_control_status_str = "Hidden service ready" ; break ; + } switch(torstatus) { From f352235ccd001f2a97f320bb6dfc0431377c6e46 Mon Sep 17 00:00:00 2001 From: csoler Date: Sat, 18 Dec 2021 16:45:53 +0100 Subject: [PATCH 34/65] fixed a few bugs --- libretroshare/src/tor/AddOnionCommand.cpp | 2 +- libretroshare/src/tor/TorControl.cpp | 2 +- libretroshare/src/tor/TorControl.h | 2 +- .../src/TorControl/TorControlWindow.cpp | 19 +++++------------- .../src/gui/statusbar/torstatus.cpp | 20 +++++++++---------- 5 files changed, 18 insertions(+), 27 deletions(-) diff --git a/libretroshare/src/tor/AddOnionCommand.cpp b/libretroshare/src/tor/AddOnionCommand.cpp index 8b0f488fa..199ab4650 100644 --- a/libretroshare/src/tor/AddOnionCommand.cpp +++ b/libretroshare/src/tor/AddOnionCommand.cpp @@ -38,7 +38,7 @@ using namespace Tor; AddOnionCommand::AddOnionCommand(HiddenService *service) - : m_service(service) + : m_service(service), mSucceeded([](){}), mFailed([](int){}) { assert(m_service); } diff --git a/libretroshare/src/tor/TorControl.cpp b/libretroshare/src/tor/TorControl.cpp index f5c9dc2f6..1baa0ac5c 100644 --- a/libretroshare/src/tor/TorControl.cpp +++ b/libretroshare/src/tor/TorControl.cpp @@ -487,7 +487,7 @@ void TorControl::getTorInfo() void TorControl::getTorInfoReply(TorControlCommand *sender) { GetConfCommand *command = dynamic_cast(sender); - if (!command || !isConnected()) + if (!command)// || !isConnected()) return; std::list listenAddresses = splitQuotedStrings(command->get("net/listeners/socks").front(), ' '); diff --git a/libretroshare/src/tor/TorControl.h b/libretroshare/src/tor/TorControl.h index 8d26e20dd..d9f550f6b 100644 --- a/libretroshare/src/tor/TorControl.h +++ b/libretroshare/src/tor/TorControl.h @@ -97,7 +97,7 @@ public: void setAuthPassword(const ByteArray& password); /* Connection */ - bool isConnected() const { return status() == Authenticated; } + bool isConnected() const { return status() >= Authenticated; } void connect(const std::string &address, uint16_t port); void authenticate(); diff --git a/retroshare-gui/src/TorControl/TorControlWindow.cpp b/retroshare-gui/src/TorControl/TorControlWindow.cpp index 31a2aa78c..135a467fc 100644 --- a/retroshare-gui/src/TorControl/TorControlWindow.cpp +++ b/retroshare-gui/src/TorControl/TorControlWindow.cpp @@ -53,21 +53,13 @@ TorControlDialog::TorControlDialog(QWidget *) void TorControlDialog::handleEvent_main_thread(std::shared_ptr event) { - if(event->mType != RsEventType::TOR_MANAGER) return; + if(event->mType != RsEventType::TOR_MANAGER) return; - const RsTorManagerEvent *fe = dynamic_cast(event.get()); - if(!fe) - return; + const RsTorManagerEvent *fe = dynamic_cast(event.get()); + if(!fe) + return; - switch (fe->mTorManagerEventType) - { - case RsTorManagerEventCode::BOOTSTRAP_STATUS_CHANGED: - case RsTorManagerEventCode::TOR_CONNECTIVITY_CHANGED: - case RsTorManagerEventCode::TOR_STATUS_CHANGED: statusChanged(fe->mTorStatus,fe->mTorConnectivityStatus); - break; - default: - break; - } + statusChanged(fe->mTorStatus,fe->mTorConnectivityStatus); } void TorControlDialog::onIncomingConnection() @@ -112,7 +104,6 @@ void TorControlDialog::statusChanged(RsTorStatus torstatus, RsTorConnectivitySta std::cerr << "Tor control status: " << tor_control_status_str.toStdString() << std::endl; std::cerr << "Tor status: " << torstatus_str.toStdString() << std::endl; - std::cerr << "Bootstrap status map: " << std::endl; for(auto it(qvm.begin());it!=qvm.end();++it) diff --git a/retroshare-gui/src/gui/statusbar/torstatus.cpp b/retroshare-gui/src/gui/statusbar/torstatus.cpp index c141ef0ce..fdde22337 100644 --- a/retroshare-gui/src/gui/statusbar/torstatus.cpp +++ b/retroshare-gui/src/gui/statusbar/torstatus.cpp @@ -100,12 +100,12 @@ void TorStatus::getTorStatus() switch(tor_control_status) { default: - case RsTorConnectivityStatus::ERROR : tor_control_ok = false ; tor_control_status_str = "Error" ; break ; - case RsTorConnectivityStatus::NOT_CONNECTED: tor_control_ok = false ; tor_control_status_str = "Not connected" ; break ; - case RsTorConnectivityStatus::CONNECTING: tor_control_ok = false ; tor_control_status_str = "Connecting" ; break ; - case RsTorConnectivityStatus::AUTHENTICATING: tor_control_ok = false ; tor_control_status_str = "Authenticating" ; break ; - case RsTorConnectivityStatus::AUTHENTICATED: tor_control_ok = false ; tor_control_status_str = "Connected" ; break ; - case RsTorConnectivityStatus::HIDDEN_SERVICE_READY: tor_control_ok = true ; tor_control_status_str = "Hidden service ready" ; break ; + case RsTorConnectivityStatus::ERROR : tor_control_ok = false ; tor_control_status_str = "Error" ; break ; + case RsTorConnectivityStatus::NOT_CONNECTED: tor_control_ok = false ; tor_control_status_str = "Not connected" ; break ; + case RsTorConnectivityStatus::CONNECTING: tor_control_ok = false ; tor_control_status_str = "Connecting" ; break ; + case RsTorConnectivityStatus::AUTHENTICATING: tor_control_ok = false ; tor_control_status_str = "Authenticating" ; break ; + case RsTorConnectivityStatus::AUTHENTICATED: tor_control_ok = false ; tor_control_status_str = "Connected" ; break ; + case RsTorConnectivityStatus::HIDDEN_SERVICE_READY: tor_control_ok = true ; tor_control_status_str = "Hidden service ready" ; break ; } switch(torstatus) @@ -141,12 +141,12 @@ void TorStatus::getTorStatus() if(!_updated) { RsPeerDetails pd; - uint32_t hiddentype; - if (rsPeers->getPeerDetails(rsPeers->getOwnId(), pd)) { + uint32_t hiddentype = RS_HIDDEN_TYPE_UNKNOWN; + + if (rsPeers->getPeerDetails(rsPeers->getOwnId(), pd)) + { if(pd.netMode == RS_NETMODE_HIDDEN) - { hiddentype = pd.hiddenType; - } } std::string proxyaddr; uint16_t proxyport; From 7e6156566ad32dc618f765eca337ae2fd8872a12 Mon Sep 17 00:00:00 2001 From: csoler Date: Sat, 18 Dec 2021 18:14:49 +0100 Subject: [PATCH 35/65] fixed display of tor bootstrap status --- libretroshare/src/tor/TorControl.cpp | 11 +++--- libretroshare/src/tor/TorManager.cpp | 5 ++- .../src/TorControl/TorControlWindow.cpp | 32 +++++++++++------ .../src/TorControl/TorControlWindow.ui | 34 +++++++++++++++++-- 4 files changed, 62 insertions(+), 20 deletions(-) diff --git a/libretroshare/src/tor/TorControl.cpp b/libretroshare/src/tor/TorControl.cpp index 1baa0ac5c..14443568b 100644 --- a/libretroshare/src/tor/TorControl.cpp +++ b/libretroshare/src/tor/TorControl.cpp @@ -191,7 +191,6 @@ void TorControl::setTorStatus(TorControl::TorStatus n) if (n == mTorStatus) return; - TorControl::TorStatus old = mTorStatus; mTorStatus = n; if(rsEvents) @@ -316,10 +315,7 @@ void TorControl::authenticateReply(TorControlCommand *sender) setTorStatus(TorControl::TorUnknown); TorControlCommand *clientEvents = new TorControlCommand; - clientEvents->set_replyLine_callback([this](int code, const ByteArray &data) - { - statusEvent(code,data); // no async needed here. - }); + clientEvents->set_replyLine_callback([this](int code, const ByteArray &data) { statusEvent(code,data);}); mSocket->registerEvent(ByteArray("STATUS_CLIENT"), clientEvents); @@ -343,6 +339,7 @@ void TorControl::authenticate() ProtocolInfoCommand *command = new ProtocolInfoCommand(this); command->set_finished_callback( [this](TorControlCommand *sender) { protocolInfoReply(sender); }); + command->set_replyLine_callback([this](int code, const ByteArray &data) { statusEvent(code,data); }); //connect(command, &TorControlCommand::finished, this, &protocolInfoReply); mSocket->sendCommand(command, command->build()); } @@ -455,6 +452,7 @@ void TorControl::getTorInfo() GetConfCommand *command = new GetConfCommand(GetConfCommand::GetInfo); //connect(command, &TorControlCommand::finished, this, &TorControl::getTorInfoReply); command->set_finished_callback( [this](TorControlCommand *sender) { getTorInfoReply(sender); }); + command->set_replyLine_callback([this](int code, const ByteArray &data) { statusEvent(code,data); }); std::list keys{ "status/circuit-established","status/bootstrap-phase" }; @@ -680,6 +678,7 @@ void TorControl::statusEvent(int /* code */, const ByteArray &data) void TorControl::updateBootstrap(const std::list &data) { + std::cerr << "********** Updating bootstrap status ************" << std::endl; mBootstrapStatus.clear(); // WARN or NOTICE mBootstrapStatus["severity"] = (*data.begin()).toString(); @@ -714,6 +713,7 @@ void TorControl::updateBootstrap(const std::list &data) TorControlCommand *TorControl::getConfiguration(const std::string& options) { GetConfCommand *command = new GetConfCommand(GetConfCommand::GetConf); + command->set_replyLine_callback([this](int code, const ByteArray &data) { statusEvent(code,data); }); mSocket->sendCommand(command, command->build(options)); //QQmlEngine::setObjectOwnership(command, QQmlEngine::CppOwnership); @@ -862,7 +862,6 @@ bool TorControl::torVersionAsNewAs(const std::string& match) const auto matchSplit = ByteArray(match).split(ByteArray(".-")); int split_size = split.size(); - int i=0; auto b_split(split.begin()); auto b_matchsplit(matchSplit.begin()); diff --git a/libretroshare/src/tor/TorManager.cpp b/libretroshare/src/tor/TorManager.cpp index dd1c1f810..32ee79322 100644 --- a/libretroshare/src/tor/TorManager.cpp +++ b/libretroshare/src/tor/TorManager.cpp @@ -577,7 +577,10 @@ void TorManagerPrivate::processLogMessage(const std::string &message) std::cerr << "tor:" << message << std::endl; if (logMessages.size() >= 50) logMessages.pop_front(); - logMessages.push_back(message); + + auto p = message.find_first_of('\n'); + + logMessages.push_back((p==std::string::npos)?message:message.substr(0,p)); } void TorManagerPrivate::controlStatusChanged(int status) diff --git a/retroshare-gui/src/TorControl/TorControlWindow.cpp b/retroshare-gui/src/TorControl/TorControlWindow.cpp index 135a467fc..c0dab3442 100644 --- a/retroshare-gui/src/TorControl/TorControlWindow.cpp +++ b/retroshare-gui/src/TorControl/TorControlWindow.cpp @@ -42,7 +42,7 @@ TorControlDialog::TorControlDialog(QWidget *) QTimer *timer = new QTimer ; QObject::connect(timer,SIGNAL(timeout()),this,SLOT(showLog())) ; - timer->start(500) ; + timer->start(300) ; // Hide some debug output for the released version @@ -143,23 +143,33 @@ void TorControlDialog::showLog() std::string s ; std::list logmsgs = RsTor::logMessages() ; - bool can_print = false ; + bool can_print = false ; for(auto it(logmsgs.begin());it!=logmsgs.end();++it) - { + { s += *it + "\n" ; - if(already_seen.find(*it) == already_seen.end()) - { - can_print = true ; - already_seen.insert(*it); - } + if(already_seen.find(*it) == already_seen.end()) + { + can_print = true ; + already_seen.insert(*it); + } - if(can_print) + if(can_print) + { std::cerr << "[TOR DEBUG LOG] " << *it << std::endl; - } - std::cerr << "Connexion Proxy: " << RsTor::socksAddress() << ":" << QString::number(RsTor::socksPort()).toStdString() << std::endl; + QString s = QString::fromStdString(*it); + int n = s.indexOf(QString("Bootstrapped")); + + if(n >= 0) + { + torBootstrapStatus_LB->setText(s.mid(n+QString("Bootstrapped").length())); + QCoreApplication::processEvents(); // forces update + } + } + } + //std::cerr << "Connexion Proxy: " << RsTor::socksAddress() << ":" << QString::number(RsTor::socksPort()).toStdString() << std::endl; } TorControlDialog::TorStatus TorControlDialog::checkForTor(QString& error_msg) diff --git a/retroshare-gui/src/TorControl/TorControlWindow.ui b/retroshare-gui/src/TorControl/TorControlWindow.ui index 602146641..6077485e5 100644 --- a/retroshare-gui/src/TorControl/TorControlWindow.ui +++ b/retroshare-gui/src/TorControl/TorControlWindow.ui @@ -40,6 +40,12 @@ + + + 0 + 0 + + @@ -55,6 +61,12 @@ + + + 0 + 0 + + Tor status: @@ -79,8 +91,14 @@ + + + 0 + 0 + + - Hidden service address: + Hidden address: Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter @@ -89,8 +107,14 @@ + + + 0 + 0 + + - Tor bootstrap status: + Tor status: Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter @@ -106,6 +130,12 @@ + + + 0 + 0 + + Onion address: From 40b965cab1d43e5362e458d07755c2662e4c4bd2 Mon Sep 17 00:00:00 2001 From: csoler Date: Sat, 18 Dec 2021 21:30:58 +0100 Subject: [PATCH 36/65] improved display of tor process completion --- libretroshare/src/pqi/pqifdbin.cc | 12 +++++- libretroshare/src/pqi/rstcpsocket.cc | 11 ++++++ libretroshare/src/tor/AddOnionCommand.cpp | 7 ++-- libretroshare/src/tor/HiddenService.cpp | 30 +++++++++++++-- libretroshare/src/tor/HiddenService.h | 2 +- libretroshare/src/tor/TorManager.cpp | 38 +++++++++---------- .../src/TorControl/TorControlWindow.cpp | 3 -- 7 files changed, 73 insertions(+), 30 deletions(-) diff --git a/libretroshare/src/pqi/pqifdbin.cc b/libretroshare/src/pqi/pqifdbin.cc index 9a3d7ca2e..a15b58689 100644 --- a/libretroshare/src/pqi/pqifdbin.cc +++ b/libretroshare/src/pqi/pqifdbin.cc @@ -91,14 +91,18 @@ int RsFdBinInterface::read_pending() return mTotalInBufferBytes; } +#ifdef DEBUG_FS_BIN RsDbg() << "clintConnt: " << mCLintConnt << ", readbytes: " << readbytes ; +#endif // display some debug info if(readbytes > 0) { - //RsDbg() << "Received the following bytes: " << RsUtil::BinToHex( reinterpret_cast(inBuffer),readbytes,50) << std::endl; +#ifdef DEBUG_FS_BIN + RsDbg() << "Received the following bytes: " << RsUtil::BinToHex( reinterpret_cast(inBuffer),readbytes,50) << std::endl; RsDbg() << "Received the following bytes: " << std::string(inBuffer,readbytes) << std::endl; +#endif void *ptr = malloc(readbytes); @@ -111,7 +115,9 @@ int RsFdBinInterface::read_pending() mTotalInBufferBytes += readbytes; mTotalReadBytes += readbytes; +#ifdef DEBUG_FS_BIN RsDbg() << "Socket: " << mCLintConnt << ". Total read: " << mTotalReadBytes << ". Buffer size: " << mTotalInBufferBytes ; +#endif } return mTotalInBufferBytes; } @@ -138,11 +144,15 @@ int RsFdBinInterface::write_pending() return mTotalOutBufferBytes; } +#ifdef DEBUG_FS_BIN RsDbg() << "clintConnt: " << mCLintConnt << ", written: " << written ; +#endif // display some debug info +#ifdef DEBUG_FS_BIN RsDbg() << "Sent the following bytes: " << RsUtil::BinToHex( reinterpret_cast(p.first),written,50) << std::endl; +#endif if(written < p.second) { diff --git a/libretroshare/src/pqi/rstcpsocket.cc b/libretroshare/src/pqi/rstcpsocket.cc index 1c8848941..13a93d70a 100644 --- a/libretroshare/src/pqi/rstcpsocket.cc +++ b/libretroshare/src/pqi/rstcpsocket.cc @@ -1,6 +1,17 @@ +/******************************* BEGIN WINDOWS/UNIX SPECIFIC PART ******************/ +#ifndef WINDOWS_SYS #include #include +#include #include +#else +#include +// Missing defines in MinGW +#ifndef MSG_WAITALL +#define MSG_WAITALL 8 +#endif +#endif +/********************************* END WINDOWS/UNIX SPECIFIC PART ******************/ #include #include diff --git a/libretroshare/src/tor/AddOnionCommand.cpp b/libretroshare/src/tor/AddOnionCommand.cpp index 199ab4650..e06bb3ede 100644 --- a/libretroshare/src/tor/AddOnionCommand.cpp +++ b/libretroshare/src/tor/AddOnionCommand.cpp @@ -86,13 +86,14 @@ void AddOnionCommand::onReply(int statusCode, const ByteArray &data) const ByteArray keyPrefix("PrivateKey="); const ByteArray sidPrefix("ServiceID="); - if(data.startsWith("ServiceID=")){ + if(data.startsWith(sidPrefix)) + { ByteArray service_id = data.mid(sidPrefix.size()); m_service->setServiceId(service_id); } - if (data.startsWith(keyPrefix)) { - + if (data.startsWith(keyPrefix)) + { ByteArray keyData(data.mid(keyPrefix.size())); CryptoKey key; diff --git a/libretroshare/src/tor/HiddenService.cpp b/libretroshare/src/tor/HiddenService.cpp index cb991828a..4cf3325dc 100644 --- a/libretroshare/src/tor/HiddenService.cpp +++ b/libretroshare/src/tor/HiddenService.cpp @@ -36,6 +36,8 @@ #include "Useful.h" #include "util/rsdir.h" +#include + using namespace Tor; HiddenService::HiddenService(HiddenServiceClient *client) @@ -110,20 +112,42 @@ void HiddenService::setPrivateKey(const CryptoKey &key) m_client->hiddenServicePrivateKeyChanged(); //emit privateKeyChanged(); } -void HiddenService::loadPrivateKey() +bool HiddenService::loadPrivateKey() { if (m_privateKey.isLoaded() || m_dataPath.empty()) - return; + return false; bool ok = m_privateKey.loadFromFile(m_dataPath + "/private_key"); if (!ok) { RsWarn() << "Failed to load hidden service key"; - return; + return false; + } + + // Also load the onion address stored in "hostname" file. This is not needed, except for early display + // of the onion address, since the onion address will be re-computed by Tor (to the same value) when the + // service is published. + + std::ifstream i((m_dataPath + "/hostname").c_str()); + + if(i) + { + std::string s; + i >> s; + if(ByteArray(s).endsWith(ByteArray(".onion"))) + { + m_hostname = s; + m_service_id = s.substr(0,s.length() - std::string(".onion").length()); + + RsDbg() << "Read existing hostname: " << m_hostname; + } + i.close(); } if(m_client) m_client->hiddenServicePrivateKeyChanged(); // emit privateKeyChanged(); + + return true; } void HiddenService::servicePublished() diff --git a/libretroshare/src/tor/HiddenService.h b/libretroshare/src/tor/HiddenService.h index 0f4f50dbf..b924a767a 100644 --- a/libretroshare/src/tor/HiddenService.h +++ b/libretroshare/src/tor/HiddenService.h @@ -97,7 +97,7 @@ private: CryptoKey m_privateKey; ByteArray m_service_id; - void loadPrivateKey(); + bool loadPrivateKey(); void setStatus(Status newStatus); HiddenServiceClient *m_client; diff --git a/libretroshare/src/tor/TorManager.cpp b/libretroshare/src/tor/TorManager.cpp index 32ee79322..e12b81d1b 100644 --- a/libretroshare/src/tor/TorManager.cpp +++ b/libretroshare/src/tor/TorManager.cpp @@ -148,10 +148,13 @@ void TorManager::setHiddenServiceDirectory(const std::string &path) d->hiddenServiceDir += '/'; } -static bool test_listening_port(const std::string& address,uint16_t port) +static bool test_listening_port(const std::string& /*address*/,uint16_t port) { - int sockfd, portno; - struct sockaddr_in serv_addr; +// sockaddr_storage addr; +// sockaddr_storage_fromString(address,addr); +// + int sockfd; + struct sockaddr_in serv_addr ; /* First call to socket() function */ sockfd = socket(AF_INET, SOCK_STREAM, 0); @@ -161,11 +164,10 @@ static bool test_listening_port(const std::string& address,uint16_t port) /* Initialize socket structure */ bzero((char *) &serv_addr, sizeof(serv_addr)); - portno = 5001; serv_addr.sin_family = AF_INET; serv_addr.sin_addr.s_addr = INADDR_ANY; - serv_addr.sin_port = htons(portno); + serv_addr.sin_port = htons(port); /* Now bind the host address using bind() call.*/ if (bind(sockfd, (struct sockaddr *) &serv_addr, sizeof(serv_addr)) < 0) { @@ -190,45 +192,43 @@ bool TorManager::setupHiddenService() { if(d->hiddenService != NULL) { - std::cerr << "TorManager: setupHiddenService() called twice! Not doing anything this time." << std::endl; + RsErr() << "TorManager: setupHiddenService() called twice! Not doing anything this time." ; return true ; } std::string keyData ;//= m_settings->read("serviceKey").toString(); std::string legacyDir = d->hiddenServiceDir; - std::cerr << "TorManager: setting up hidden service." << std::endl; + RsDbg() << "TorManager: setting up hidden service." << std::endl; if(legacyDir.empty()) { - std::cerr << "legacy dir not set! Cannot proceed." << std::endl; + RsErr() << "legacy dir not set! Cannot proceed." ; return false ; } - std::cerr << "Using legacy dir: " << legacyDir << std::endl; + RsDbg() << "Using legacy dir: " << legacyDir ; auto key_path = RsDirUtil::makePath(legacyDir,"/private_key"); if (!legacyDir.empty() && RsDirUtil::fileExists(key_path)) { std::cerr << "Attempting to load key from legacy filesystem format from file \"" << key_path << "\"" << std::endl; - CryptoKey key; - if (!key.loadFromFile(key_path)) + d->hiddenService = new Tor::HiddenService(this,legacyDir); + + if(!d->hiddenService->privateKey().bytes().empty()) { - RsWarn() << "Cannot load legacy format key from" << legacyDir << "for conversion"; - return false; + RsDbg() << "Got key from legacy dir: " ; + RsDbg() << d->hiddenService->privateKey().bytes().toHex().toString() ; } - - d->hiddenService = new Tor::HiddenService(this,key, legacyDir); - - std::cerr << "Got key from legacy dir: " << std::endl; - std::cerr << key.bytes().toHex().toString() << std::endl; + else + RsWarn() << "Failed to load existing hidden service. Creating a new one." ; } else { d->hiddenService = new Tor::HiddenService(this,legacyDir); - std::cerr << "Creating new hidden service." << std::endl; + RsDbg() << "Creating new hidden service." << std::endl; // connect(d->hiddenService, SIGNAL(privateKeyChanged()), this, SLOT(hiddenServicePrivateKeyChanged())) ; // connect(d->hiddenService, SIGNAL(hostnameChanged()), this, SLOT(hiddenServiceHostnameChanged())) ; diff --git a/retroshare-gui/src/TorControl/TorControlWindow.cpp b/retroshare-gui/src/TorControl/TorControlWindow.cpp index c0dab3442..f60e121f3 100644 --- a/retroshare-gui/src/TorControl/TorControlWindow.cpp +++ b/retroshare-gui/src/TorControl/TorControlWindow.cpp @@ -163,10 +163,7 @@ void TorControlDialog::showLog() int n = s.indexOf(QString("Bootstrapped")); if(n >= 0) - { torBootstrapStatus_LB->setText(s.mid(n+QString("Bootstrapped").length())); - QCoreApplication::processEvents(); // forces update - } } } //std::cerr << "Connexion Proxy: " << RsTor::socksAddress() << ":" << QString::number(RsTor::socksPort()).toStdString() << std::endl; From 6048a9a011dc7f49627bbaf7471ea58a2000df2f Mon Sep 17 00:00:00 2001 From: csoler Date: Sun, 19 Dec 2021 16:52:43 +0100 Subject: [PATCH 37/65] attempt to fix compilation on windows --- libretroshare/src/pqi/pqifdbin.cc | 16 +++++++++++----- libretroshare/src/pqi/rstcpsocket.cc | 5 +++++ libretroshare/src/tor/TorManager.cpp | 5 +++++ libretroshare/src/tor/TorProcess.cpp | 7 ++++++- 4 files changed, 27 insertions(+), 6 deletions(-) diff --git a/libretroshare/src/pqi/pqifdbin.cc b/libretroshare/src/pqi/pqifdbin.cc index a15b58689..d5634793d 100644 --- a/libretroshare/src/pqi/pqifdbin.cc +++ b/libretroshare/src/pqi/pqifdbin.cc @@ -37,15 +37,21 @@ RsFdBinInterface::RsFdBinInterface(int file_descriptor) void RsFdBinInterface::setSocket(int s) { - if(mIsActive != 0) - { - RsErr() << "Changing socket to active FsBioInterface! Canceling all pending R/W data." ; - close(); - } + if(mIsActive != 0) + { + RsErr() << "Changing socket to active FsBioInterface! Canceling all pending R/W data." ; + close(); + } +#ifndef WINDOWS_SYS int flags = fcntl(s,F_GETFL); if(!(flags & O_NONBLOCK)) throw std::runtime_error("Trying to use a blocking file descriptor in RsFdBinInterface. This is not going to work!"); +#else + // On windows, there is no way to determine whether a socket is blobking or not, so we set it to non blocking whatsoever. + unsigned long int on = 1; + ret = ioctlsocket(fd[STDOUT_FILENO], FIONBIO, &on); +#endif mCLintConnt = s; mIsActive = (s!=0); diff --git a/libretroshare/src/pqi/rstcpsocket.cc b/libretroshare/src/pqi/rstcpsocket.cc index 13a93d70a..8f77a993b 100644 --- a/libretroshare/src/pqi/rstcpsocket.cc +++ b/libretroshare/src/pqi/rstcpsocket.cc @@ -61,8 +61,13 @@ bool RsTcpSocket::connect() } mState = CONNECTED; +#ifndef WINDOWS_SYS int flags = fcntl(CreateSocket,F_GETFL); fcntl(CreateSocket, F_SETFL, flags | O_NONBLOCK); +#else + unsigned long int on = 1; + ret = ioctlsocket(fd, FIONBIO, &on); +#endif setSocket(CreateSocket); diff --git a/libretroshare/src/tor/TorManager.cpp b/libretroshare/src/tor/TorManager.cpp index e12b81d1b..9d84910ce 100644 --- a/libretroshare/src/tor/TorManager.cpp +++ b/libretroshare/src/tor/TorManager.cpp @@ -175,8 +175,13 @@ static bool test_listening_port(const std::string& /*address*/,uint16_t port) close(sockfd); return false; } +#ifndef WINDOWS_SYS int flags = fcntl(sockfd, F_GETFL); fcntl(sockfd, F_SETFL, flags | O_NONBLOCK); +#else + unsigned long int on = 1; + ret = ioctlsocket(fd, FIONBIO, &on); +#endif int res = listen(sockfd,5); diff --git a/libretroshare/src/tor/TorProcess.cpp b/libretroshare/src/tor/TorProcess.cpp index c33fbb876..8ae8721db 100644 --- a/libretroshare/src/tor/TorProcess.cpp +++ b/libretroshare/src/tor/TorProcess.cpp @@ -272,9 +272,14 @@ void TorProcess::start() } int flags ; +#ifndef WINDOWS_SYS flags = fcntl(fd[STDOUT_FILENO], F_GETFL); fcntl(fd[STDOUT_FILENO], F_SETFL, flags | O_NONBLOCK); flags = fcntl(fd[STDERR_FILENO], F_GETFL); fcntl(fd[STDERR_FILENO], F_SETFL, flags | O_NONBLOCK); - +#else + unsigned long int on = 1; + ret = ioctlsocket(fd[STDOUT_FILENO], FIONBIO, &on); + ret = ioctlsocket(fd[STDERR_FILENO], FIONBIO, &on); +#endif mStdOutFD = new RsFdBinInterface(fd[STDOUT_FILENO]); mStdErrFD = new RsFdBinInterface(fd[STDERR_FILENO]); } From 37d4e4f3df930eedf114740a4dbaf8d658592046 Mon Sep 17 00:00:00 2001 From: csoler Date: Sun, 19 Dec 2021 17:44:23 +0100 Subject: [PATCH 38/65] attempt to fix compilation on windows --- libretroshare/src/pqi/rstcpsocket.cc | 9 +-------- libretroshare/src/tor/TorManager.cpp | 9 +-------- libretroshare/src/tor/TorProcess.cpp | 11 +++-------- 3 files changed, 5 insertions(+), 24 deletions(-) diff --git a/libretroshare/src/pqi/rstcpsocket.cc b/libretroshare/src/pqi/rstcpsocket.cc index 8f77a993b..ac91414b3 100644 --- a/libretroshare/src/pqi/rstcpsocket.cc +++ b/libretroshare/src/pqi/rstcpsocket.cc @@ -61,14 +61,7 @@ bool RsTcpSocket::connect() } mState = CONNECTED; -#ifndef WINDOWS_SYS - int flags = fcntl(CreateSocket,F_GETFL); - fcntl(CreateSocket, F_SETFL, flags | O_NONBLOCK); -#else - unsigned long int on = 1; - ret = ioctlsocket(fd, FIONBIO, &on); -#endif - + unix_fcntl_nonblock(CreateSocket); setSocket(CreateSocket); return true; diff --git a/libretroshare/src/tor/TorManager.cpp b/libretroshare/src/tor/TorManager.cpp index 9d84910ce..c4e2d8789 100644 --- a/libretroshare/src/tor/TorManager.cpp +++ b/libretroshare/src/tor/TorManager.cpp @@ -175,14 +175,7 @@ static bool test_listening_port(const std::string& /*address*/,uint16_t port) close(sockfd); return false; } -#ifndef WINDOWS_SYS - int flags = fcntl(sockfd, F_GETFL); - fcntl(sockfd, F_SETFL, flags | O_NONBLOCK); -#else - unsigned long int on = 1; - ret = ioctlsocket(fd, FIONBIO, &on); -#endif - + unix_fcntl_nonblock(sockfd); int res = listen(sockfd,5); int err = errno; diff --git a/libretroshare/src/tor/TorProcess.cpp b/libretroshare/src/tor/TorProcess.cpp index 8ae8721db..92a4958e9 100644 --- a/libretroshare/src/tor/TorProcess.cpp +++ b/libretroshare/src/tor/TorProcess.cpp @@ -272,14 +272,9 @@ void TorProcess::start() } int flags ; -#ifndef WINDOWS_SYS - flags = fcntl(fd[STDOUT_FILENO], F_GETFL); fcntl(fd[STDOUT_FILENO], F_SETFL, flags | O_NONBLOCK); - flags = fcntl(fd[STDERR_FILENO], F_GETFL); fcntl(fd[STDERR_FILENO], F_SETFL, flags | O_NONBLOCK); -#else - unsigned long int on = 1; - ret = ioctlsocket(fd[STDOUT_FILENO], FIONBIO, &on); - ret = ioctlsocket(fd[STDERR_FILENO], FIONBIO, &on); -#endif + unix_fcntl_nonblock(fd[STDOUT_FILENO]); + unix_fcntl_nonblock(fd[STDERR_FILENO]); + mStdOutFD = new RsFdBinInterface(fd[STDOUT_FILENO]); mStdErrFD = new RsFdBinInterface(fd[STDERR_FILENO]); } From 9684b2ed94122d4977753226beecb0ae48e734a7 Mon Sep 17 00:00:00 2001 From: csoler Date: Sun, 19 Dec 2021 18:40:44 +0100 Subject: [PATCH 39/65] code cleaning --- libretroshare/src/libretroshare.pro | 3 +- libretroshare/src/tor/AddOnionCommand.h | 4 - libretroshare/src/tor/CryptoKey.cpp | 1 - libretroshare/src/tor/GetConfCommand.h | 7 +- libretroshare/src/tor/HiddenService.cpp | 3 +- libretroshare/src/tor/HiddenService.h | 1 - libretroshare/src/tor/PendingOperation.h | 14 --- libretroshare/src/tor/ProtocolInfoCommand.h | 2 - libretroshare/src/tor/SetConfCommand.cpp | 19 --- libretroshare/src/tor/SetConfCommand.h | 4 - libretroshare/src/tor/TorControl.cpp | 122 +------------------- libretroshare/src/tor/TorControl.h | 29 +---- libretroshare/src/tor/TorControlCommand.cpp | 2 - libretroshare/src/tor/TorControlCommand.h | 1 - libretroshare/src/tor/TorControlSocket.cpp | 4 - libretroshare/src/tor/TorControlSocket.h | 3 - libretroshare/src/tor/TorManager.cpp | 7 -- libretroshare/src/tor/TorManager.h | 12 -- libretroshare/src/tor/TorProcess.cpp | 71 +----------- libretroshare/src/tor/bytearray.h | 2 + 20 files changed, 14 insertions(+), 297 deletions(-) diff --git a/libretroshare/src/libretroshare.pro b/libretroshare/src/libretroshare.pro index 4811fa2d6..e3bc28006 100644 --- a/libretroshare/src/libretroshare.pro +++ b/libretroshare/src/libretroshare.pro @@ -737,8 +737,7 @@ HEADERS += tor/AddOnionCommand.h \ tor/TorControlCommand.h \ tor/TorControlSocket.h \ tor/TorManager.h \ - tor/TorProcess.h \ - tor/Useful.h + tor/TorProcess.h SOURCES += tor/AddOnionCommand.cpp \ tor/AuthenticateCommand.cpp \ diff --git a/libretroshare/src/tor/AddOnionCommand.h b/libretroshare/src/tor/AddOnionCommand.h index fddab89af..4b20de986 100644 --- a/libretroshare/src/tor/AddOnionCommand.h +++ b/libretroshare/src/tor/AddOnionCommand.h @@ -41,9 +41,6 @@ class HiddenService; class AddOnionCommand : public TorControlCommand { - // Q_PROPERTY(std::string errorMessage READ errorMessage CONSTANT) - // Q_PROPERTY(bool successful READ isSuccessful CONSTANT) - public: AddOnionCommand(HiddenService *service); @@ -52,7 +49,6 @@ public: std::string errorMessage() const { return m_errorMessage; } bool isSuccessful() const; -// signals: void set_succeeded_callback(const std::function& f) { mSucceeded=f;} void set_failed_callback(const std::function& f) { mFailed=f;} diff --git a/libretroshare/src/tor/CryptoKey.cpp b/libretroshare/src/tor/CryptoKey.cpp index 95fdab016..802caaf0c 100644 --- a/libretroshare/src/tor/CryptoKey.cpp +++ b/libretroshare/src/tor/CryptoKey.cpp @@ -33,7 +33,6 @@ #include #include "CryptoKey.h" -#include "Useful.h" #include #include diff --git a/libretroshare/src/tor/GetConfCommand.h b/libretroshare/src/tor/GetConfCommand.h index b6595fbf3..d3ca3bfc3 100644 --- a/libretroshare/src/tor/GetConfCommand.h +++ b/libretroshare/src/tor/GetConfCommand.h @@ -30,8 +30,7 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#ifndef GETCONFCOMMAND_H -#define GETCONFCOMMAND_H +#pragma once #include #include "TorControlCommand.h" @@ -41,8 +40,6 @@ namespace Tor class GetConfCommand : public TorControlCommand { - // Q_PROPERTY(QVariantMap results READ results CONSTANT) - public: enum Type { GetConf, @@ -69,5 +66,3 @@ private: }; } - -#endif // GETCONFCOMMAND_H diff --git a/libretroshare/src/tor/HiddenService.cpp b/libretroshare/src/tor/HiddenService.cpp index 4cf3325dc..a6b083eae 100644 --- a/libretroshare/src/tor/HiddenService.cpp +++ b/libretroshare/src/tor/HiddenService.cpp @@ -33,7 +33,6 @@ #include "HiddenService.h" #include "TorControl.h" #include "CryptoKey.h" -#include "Useful.h" #include "util/rsdir.h" #include @@ -102,7 +101,7 @@ void HiddenService::setServiceId(const ByteArray& sid) void HiddenService::setPrivateKey(const CryptoKey &key) { if (m_privateKey.isLoaded()) { - BUG() << "Cannot change the private key on an existing HiddenService"; + RsErr() << "Cannot change the private key on an existing HiddenService"; return; } diff --git a/libretroshare/src/tor/HiddenService.h b/libretroshare/src/tor/HiddenService.h index b924a767a..0e50e93b9 100644 --- a/libretroshare/src/tor/HiddenService.h +++ b/libretroshare/src/tor/HiddenService.h @@ -86,7 +86,6 @@ public: void addTarget(const Target &target); void addTarget(uint16_t servicePort, std::string targetAddress, uint16_t targetPort); -//private slots: void servicePublished(); private: diff --git a/libretroshare/src/tor/PendingOperation.h b/libretroshare/src/tor/PendingOperation.h index 4a75b1c9e..5115f3252 100644 --- a/libretroshare/src/tor/PendingOperation.h +++ b/libretroshare/src/tor/PendingOperation.h @@ -49,11 +49,6 @@ */ class PendingOperation { -// Q_PROPERTY(bool isFinished READ isFinished NOTIFY finished FINAL) -// Q_PROPERTY(bool isSuccess READ isSuccess NOTIFY success FINAL) -// Q_PROPERTY(bool isError READ isError NOTIFY error FINAL) -// Q_PROPERTY(std::string errorMessage READ errorMessage NOTIFY finished FINAL) - public: PendingOperation(); @@ -62,15 +57,6 @@ public: bool isError() const; std::string errorMessage() const; -// signals: -// // Always emitted once when finished, regardless of status -// void finished(); -// -// // One of error() or success() is emitted once -// void error(const std::string &errorMessage); -// void success(); - -//protected slots: void finishWithError(const std::string &errorMessage); void finishWithSuccess(); diff --git a/libretroshare/src/tor/ProtocolInfoCommand.h b/libretroshare/src/tor/ProtocolInfoCommand.h index 3d4f8baf2..b90e2fe7c 100644 --- a/libretroshare/src/tor/ProtocolInfoCommand.h +++ b/libretroshare/src/tor/ProtocolInfoCommand.h @@ -52,8 +52,6 @@ public: }; 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); ByteArray build(); diff --git a/libretroshare/src/tor/SetConfCommand.cpp b/libretroshare/src/tor/SetConfCommand.cpp index 0285c8c8b..463305731 100644 --- a/libretroshare/src/tor/SetConfCommand.cpp +++ b/libretroshare/src/tor/SetConfCommand.cpp @@ -55,25 +55,6 @@ ByteArray SetConfCommand::build(const std::string &key, const std::string &value return build(std::list > { std::make_pair(key, value) } ); } -// ByteArray SetConfCommand::build(const std::list > &data) -// { -// QList > out; -// -// for (QVariantMap::ConstIterator it = data.begin(); it != data.end(); it++) { -// QByteArray key = it.key().toLatin1(); -// -// if (static_cast(it.value().type()) == QMetaType::QVariantList) { -// QVariantList values = it.value().value(); -// foreach (const QVariant &value, values) -// out.append(qMakePair(key, value.toString().toLatin1())); -// } else { -// out.append(qMakePair(key, it.value().toString().toLatin1())); -// } -// } -// -// return build(out); -// } - ByteArray SetConfCommand::build(const std::list >& data) { ByteArray out(m_resetMode ? "RESETCONF" : "SETCONF"); diff --git a/libretroshare/src/tor/SetConfCommand.h b/libretroshare/src/tor/SetConfCommand.h index 8fb247e84..bf7713038 100644 --- a/libretroshare/src/tor/SetConfCommand.h +++ b/libretroshare/src/tor/SetConfCommand.h @@ -40,9 +40,6 @@ namespace Tor class SetConfCommand : public TorControlCommand { - //Q_PROPERTY(QString errorMessage READ errorMessage CONSTANT) - //Q_PROPERTY(bool successful READ isSuccessful CONSTANT) - public: SetConfCommand(); @@ -54,7 +51,6 @@ public: std::string errorMessage() const { return m_errorMessage; } bool isSuccessful() const; -//signals: void set_ConfSucceeded_callback(const std::function& f) { mConfSucceeded=f; } void set_ConfFailed_callback (const std::function& f){ mConfFailed=f; } diff --git a/libretroshare/src/tor/TorControl.cpp b/libretroshare/src/tor/TorControl.cpp index 14443568b..b1803dd4e 100644 --- a/libretroshare/src/tor/TorControl.cpp +++ b/libretroshare/src/tor/TorControl.cpp @@ -62,78 +62,13 @@ static std::ostream& torctrldebug() #define torCtrlDebug torctrldebug - using namespace Tor; -namespace Tor { - -// class TorControlPrivate : public QObject -// { -// Q_OBJECT -// -// public: -// TorControl *q; -// -// TorControlSocket *socket; -// std::string torAddress; -// std::string errorMessage; -// std::string torVersion; -// ByteArray authPassword; -// std::string socksAddress; -// QList services; -// uint16_t controlPort, socksPort; -// TorControl::Status status; -// TorControl::TorStatus torStatus; -// std::map bootstrapStatus; -// bool hasOwnership; -// -// TorControlPrivate(TorControl *parent); -// -// void setStatus(TorControl::Status status); -// void setTorStatus(TorControl::TorStatus status); -// -// void getTorInfo(); -// void publishServices(); -// -// public slots: -// void socketConnected(); -// void socketDisconnected(); -// void socketError(); -// -// void authenticateReply(); -// void protocolInfoReply(); -// void getTorInfoReply(); -// void setError(const std::string &message); -// -// void statusEvent(int code, const ByteArray &data); -// void updateBootstrap(const std::list &data); -// }; - -} - TorControl::TorControl() { mSocket = new TorControlSocket(this); } -// TorControlPrivate::TorControlPrivate(TorControl *parent) -// : QObject(parent), q(parent), controlPort(0), socksPort(0), -// status(TorControl::NotConnected), torStatus(TorControl::TorUnknown), -// hasOwnership(false) -// { -// socket = new TorControlSocket(); -// -// // QObject::connect(socket, SIGNAL(connected()), this, SLOT(socketConnected())); -// // QObject::connect(socket, SIGNAL(disconnected()), this, SLOT(socketDisconnected())); -// // QObject::connect(socket, SIGNAL(error(QAbstractSocket::SocketError)), this, SLOT(socketError())); -// // QObject::connect(socket, SIGNAL(error(QString)), this, SLOT(setError(QString))); -// } - -// QNetworkProxy TorControl::connectionProxy() -// { -// return QNetworkProxy(QNetworkProxy::Socks5Proxy, d->socksAddress.toString(), d->socksPort); -// } - static RsTorConnectivityStatus torConnectivityStatus(Tor::TorControl::Status t) { switch(t) @@ -179,11 +114,6 @@ void TorControl::setStatus(TorControl::Status n) rsEvents->sendEvent(ev); } mStatusChanged_callback(mStatus, old); - -// if (mStatus == TorControl::Connected && old < TorControl::Connected) -// socketConnected();//mConnected_callback(); -// else if (mStatus < TorControl::Connected && old >= TorControl::Connected) -// socketDisconnected();//mDisconnected_callback(); } void TorControl::setTorStatus(TorControl::TorStatus n) @@ -274,10 +204,8 @@ void TorControl::connect(const std::string &address, uint16_t port) mControlPort = port; setTorStatus(TorUnknown); - //bool b = d->socket->blockSignals(true); if(mSocket->isRunning()) mSocket->fullstop(); - //d->socket->blockSignals(b); setStatus(Connecting); @@ -340,7 +268,7 @@ void TorControl::authenticate() command->set_finished_callback( [this](TorControlCommand *sender) { protocolInfoReply(sender); }); command->set_replyLine_callback([this](int code, const ByteArray &data) { statusEvent(code,data); }); - //connect(command, &TorControlCommand::finished, this, &protocolInfoReply); + mSocket->sendCommand(command, command->build()); } @@ -372,7 +300,7 @@ void TorControl::protocolInfoReply(TorControlCommand *sender) if (mStatus == TorControl::Authenticating) { AuthenticateCommand *auth = new AuthenticateCommand; - //connect(auth, &TorControlCommand::finished, this, &TorControl::authenticateReply); + auth->set_finished_callback( [this](TorControlCommand *sender) { authenticateReply(sender); }); ByteArray data; @@ -456,28 +384,7 @@ void TorControl::getTorInfo() std::list keys{ "status/circuit-established","status/bootstrap-phase" }; -#ifdef TODO - /* If these are set in the config, they override the automatic behavior. */ - SettingsObject settings("tor"); - QHostAddress forceAddress(settings.read("socksAddress").toString()); - uint16_t port = (uint16_t)settings.read("socksPort").toInt(); - - if (!forceAddress.isNull() && port) { - torCtrlDebug() << "torctrl: Using manually specified SOCKS connection settings"; - socksAddress = forceAddress; - socksPort = port; - - if(rsEvents) - { - auto ev = std::make_shared(); - - ev->mTorManagerEventType = RsTorManagerEventCode::TOR_CONNECTIVITY_CHANGED; - rsEvents->sendEvent(ev); - } - } - else -#endif - keys .push_back("net/listeners/socks"); + keys.push_back("net/listeners/socks"); mSocket->sendCommand(command, command->build(keys)); } @@ -485,7 +392,7 @@ void TorControl::getTorInfo() void TorControl::getTorInfoReply(TorControlCommand *sender) { GetConfCommand *command = dynamic_cast(sender); - if (!command)// || !isConnected()) + if (!command) return; std::list listenAddresses = splitQuotedStrings(command->get("net/listeners/socks").front(), ' '); @@ -557,20 +464,6 @@ void TorControl::publishServices() } std::cerr << std::endl; -#ifdef TODO - SettingsObject settings("tor"); - if (settings.read("neverPublishServices").toBool()) - { - torCtrlDebug() << "torctrl: Skipping service publication because neverPublishService is enabled" << std::endl; - - /* Call servicePublished under the assumption that they're published externally. */ - for (QList::Iterator it = services.begin(); it != services.end(); ++it) - (*it)->servicePublished(); - - return; - } -#endif - if (torVersionAsNewAs("0.2.7")) { for(HiddenService *service: mServices) { @@ -697,8 +590,6 @@ void TorControl::updateBootstrap(const std::list &data) mBootstrapStatus[key.toLower().toString()] = value.toString(); } - //torCtrlDebug() << bootstrapStatus << std::endl; - if(rsEvents) { auto ev = std::make_shared(); @@ -716,7 +607,6 @@ TorControlCommand *TorControl::getConfiguration(const std::string& options) command->set_replyLine_callback([this](int code, const ByteArray &data) { statusEvent(code,data); }); mSocket->sendCommand(command, command->build(options)); - //QQmlEngine::setObjectOwnership(command, QQmlEngine::CppOwnership); return command; } @@ -726,7 +616,6 @@ TorControlCommand *TorControl::setConfiguration(const std::listsetResetMode(true); mSocket->sendCommand(command, command->build(options)); - //QQmlEngine::setObjectOwnership(command, QQmlEngine::CppOwnership); return command; } @@ -744,7 +633,6 @@ public: { assert(!command); command = new GetConfCommand(GetConfCommand::GetInfo); - //QObject::connect(command, &TorControlCommand::finished, this, &SaveConfigOperation::configTextReply); command->set_finished_callback([this](TorControlCommand *sender){ configTextReply(sender); }); socket->sendCommand(command, command->build(std::list { "config-text" , "config-file" } )); @@ -832,11 +720,9 @@ PendingOperation *TorControl::saveConfiguration() SaveConfigOperation *operation = new SaveConfigOperation(); - //QObject::connect(operation, &PendingOperation::finished, operation, &QObject::deleteLater); operation->set_finished_callback( [operation]() { delete operation; }); operation->start(mSocket); - //QQmlEngine::setObjectOwnership(operation, QQmlEngine::CppOwnership); return operation; } diff --git a/libretroshare/src/tor/TorControl.h b/libretroshare/src/tor/TorControl.h index d9f550f6b..941c088d2 100644 --- a/libretroshare/src/tor/TorControl.h +++ b/libretroshare/src/tor/TorControl.h @@ -48,19 +48,6 @@ class TorControlCommand; class TorControl : public TorControlSocketClient { -// Q_ENUMS(Status TorStatus) -// -// // Status of the control connection -// Q_PROPERTY(Status status READ status NOTIFY statusChanged) -// // Status of Tor (and whether it believes it can connect) -// Q_PROPERTY(TorStatus torStatus READ torStatus NOTIFY torStatusChanged) -// // Whether it's possible to make a SOCKS connection and connect -// Q_PROPERTY(bool hasConnectivity READ hasConnectivity NOTIFY connectivityChanged) -// Q_PROPERTY(QString torVersion READ torVersion NOTIFY connected) -// Q_PROPERTY(QString errorMessage READ errorMessage NOTIFY statusChanged) -// Q_PROPERTY(QVariantMap bootstrapStatus READ bootstrapStatus NOTIFY bootstrapStatusChanged) -// Q_PROPERTY(bool hasOwnership READ hasOwnership NOTIFY hasOwnershipChanged) - public: enum Status { @@ -111,18 +98,9 @@ public: void addHiddenService(HiddenService *service); std::map bootstrapStatus() const; - /*Q_INVOKABLE*/ TorControlCommand *getConfiguration(const std::string &options); - /*Q_INVOKABLE*/ TorControlCommand *setConfiguration(const std::list > &options); - /*Q_INVOKABLE*/ PendingOperation *saveConfiguration(); - -//signals: -// void statusChanged(int newStatus, int oldStatus); -// void torStatusChanged(int newStatus, int oldStatus); -// void connected(); -// void disconnected(); -// void connectivityChanged(); -// void bootstrapStatusChanged(); -// void hasOwnershipChanged(); + TorControlCommand *getConfiguration(const std::string &options); + TorControlCommand *setConfiguration(const std::list > &options); + PendingOperation *saveConfiguration(); void set_statusChanged_callback(const std::function& f) { mStatusChanged_callback = f ;} void set_connected_callback(const std::function& f) { mConnected_callback = f ;} @@ -130,7 +108,6 @@ public: virtual void socketError(const std::string &s) override; -//public slots: /* Instruct Tor to shutdown */ void shutdown(); /* Call shutdown(), and wait synchronously for the command to be written */ diff --git a/libretroshare/src/tor/TorControlCommand.cpp b/libretroshare/src/tor/TorControlCommand.cpp index 2bfc17a71..127b6a04a 100644 --- a/libretroshare/src/tor/TorControlCommand.cpp +++ b/libretroshare/src/tor/TorControlCommand.cpp @@ -43,14 +43,12 @@ TorControlCommand::TorControlCommand() void TorControlCommand::onReply(int statusCode, const ByteArray &data) { - //emit replyLine(statusCode, data); mReplyLine(statusCode, data); } void TorControlCommand::onFinished(int statusCode) { m_finalStatus = statusCode; - //emit finished(); mFinished(this); } diff --git a/libretroshare/src/tor/TorControlCommand.h b/libretroshare/src/tor/TorControlCommand.h index 6e0a2a176..8dee6aadb 100644 --- a/libretroshare/src/tor/TorControlCommand.h +++ b/libretroshare/src/tor/TorControlCommand.h @@ -50,7 +50,6 @@ public: int statusCode() const { return m_finalStatus; } -//signals: void set_replyLine_callback( const std::function& f) { mReplyLine=f ; } void set_finished_callback( const std::function& f) { mFinished=f; }; diff --git a/libretroshare/src/tor/TorControlSocket.cpp b/libretroshare/src/tor/TorControlSocket.cpp index 5d69dc7de..e9740515a 100644 --- a/libretroshare/src/tor/TorControlSocket.cpp +++ b/libretroshare/src/tor/TorControlSocket.cpp @@ -40,8 +40,6 @@ using namespace Tor; TorControlSocket::TorControlSocket(TorControlSocketClient *client) : RsThreadedTcpSocket(),currentCommand(0), inDataReply(false),mClient(client) { - //connect(this, SIGNAL(readyRead()), this, SLOT(process())); - //connect(this, SIGNAL(disconnected()), this, SLOT(clear())); } TorControlSocket::~TorControlSocket() @@ -84,8 +82,6 @@ void TorControlSocket::registerEvent(const ByteArray &event, TorControlCommand * ByteArray data("SETEVENTS"); for(auto it:eventCommands) { - //const ByteArray &key, eventCommands.keys()) { - //data += key; data += ' '; data += it.first; } diff --git a/libretroshare/src/tor/TorControlSocket.h b/libretroshare/src/tor/TorControlSocket.h index b5ba4181c..40437ed76 100644 --- a/libretroshare/src/tor/TorControlSocket.h +++ b/libretroshare/src/tor/TorControlSocket.h @@ -67,12 +67,9 @@ public: virtual int tick() override; std::string peerAddress() const; -//signals: -// void error(const std::string& message); const std::string& errorString() const { return m_errorMessage ;} -//private slots: void process(); void clear(); diff --git a/libretroshare/src/tor/TorManager.cpp b/libretroshare/src/tor/TorManager.cpp index c4e2d8789..d2baa128b 100644 --- a/libretroshare/src/tor/TorManager.cpp +++ b/libretroshare/src/tor/TorManager.cpp @@ -101,7 +101,6 @@ TorManagerPrivate::TorManagerPrivate(TorManager *parent) , configNeeded(false) , hiddenService(NULL) { - //connect(control, SIGNAL(statusChanged(int,int)), SLOT(controlStatusChanged(int))); control->set_statusChanged_callback([this](int new_status,int /*old_status*/) { controlStatusChanged(new_status); }); } @@ -150,9 +149,6 @@ void TorManager::setHiddenServiceDirectory(const std::string &path) static bool test_listening_port(const std::string& /*address*/,uint16_t port) { -// sockaddr_storage addr; -// sockaddr_storage_fromString(address,addr); -// int sockfd; struct sockaddr_in serv_addr ; @@ -227,9 +223,6 @@ bool TorManager::setupHiddenService() d->hiddenService = new Tor::HiddenService(this,legacyDir); RsDbg() << "Creating new hidden service." << std::endl; - - // connect(d->hiddenService, SIGNAL(privateKeyChanged()), this, SLOT(hiddenServicePrivateKeyChanged())) ; - // connect(d->hiddenService, SIGNAL(hostnameChanged()), this, SLOT(hiddenServiceHostnameChanged())) ; } assert(d->hiddenService); diff --git a/libretroshare/src/tor/TorManager.h b/libretroshare/src/tor/TorManager.h index c9a5e3769..5a62f6d00 100644 --- a/libretroshare/src/tor/TorManager.h +++ b/libretroshare/src/tor/TorManager.h @@ -49,16 +49,6 @@ class TorManagerPrivate; class TorManager : public HiddenServiceClient, public RsThread, public RsTor { - // Q_OBJECT - - // Q_PROPERTY(bool configurationNeeded READ configurationNeeded NOTIFY configurationNeededChanged) - // Q_PROPERTY(QStringList logMessages READ logMessages CONSTANT) - // Q_PROPERTY(Tor::TorProcess* process READ process CONSTANT) - // Q_PROPERTY(Tor::TorControl* control READ control CONSTANT) - // Q_PROPERTY(bool hasError READ hasError NOTIFY errorChanged) - // Q_PROPERTY(QString errorMessage READ errorMessage NOTIFY errorChanged) - // Q_PROPERTY(QString torDataDirectory READ torDataDirectory WRITE setTorDataDirectory) - public: static TorManager *instance(); @@ -85,10 +75,8 @@ public: 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(std::string &proxy_server_adress, uint16_t& proxy_server_port); -//public slots: bool startTorManager(); -//private slots: virtual void hiddenServiceOnline() override {} // do nothing here. virtual void hiddenServicePrivateKeyChanged() override; virtual void hiddenServiceHostnameChanged() override; diff --git a/libretroshare/src/tor/TorProcess.cpp b/libretroshare/src/tor/TorProcess.cpp index 92a4958e9..06ceb413f 100644 --- a/libretroshare/src/tor/TorProcess.cpp +++ b/libretroshare/src/tor/TorProcess.cpp @@ -271,7 +271,6 @@ void TorProcess::start() return; // stop the control thread } - int flags ; unix_fcntl_nonblock(fd[STDOUT_FILENO]); unix_fcntl_nonblock(fd[STDERR_FILENO]); @@ -309,8 +308,6 @@ void TorProcess::tick() } else if(mControlPortReadNbTries > 10) { - //errorMessageChanged(errorMessage); - //stateChanged(state); mState = Failed; m_client->processStateChanged(mState);// stateChanged(mState); } @@ -394,20 +391,18 @@ bool TorProcess::ensureFilesExist() std::string TorProcess::torrcPath() const { - //return QDir::toNativeSeparators(dataDir) + QDir::separator() + QStringLiteral("torrc"); return RsDirUtil::makePath(mDataDir,"torrc"); } std::string TorProcess::controlPortFilePath() const { - //return QDir::toNativeSeparators(dataDir) + QDir::separator() + QStringLiteral("control-port"); return RsDirUtil::makePath(mDataDir,"control-port"); } bool TorProcess::tryReadControlPort() { FILE *file = RsDirUtil::rs_fopen(controlPortFilePath().c_str(),"r"); - std::cerr << "Trying to read control port" << std::endl; + RsDbg() << "Trying to read control port" ; if(file) { @@ -425,72 +420,10 @@ bool TorProcess::tryReadControlPort() if (!mControlHost.empty() && mControlPort > 0) { - std::cerr << "Got control host/port = " << mControlHost << ":" << mControlPort << std::endl; + RsDbg() << "Got control host/port = " << mControlHost << ":" << mControlPort ; return true; } } } return false; } -#ifdef TO_REMOVE -void TorProcessPrivate::processStarted() -{ - state = TorProcess::Connecting; - - /*emit*/ q->stateChanged(state); - /*emit*/ q->stateChanged(state); - - controlPortAttempts = 0; - controlPortTimer.start(); -} - -void TorProcessPrivate::processFinished() -{ - if (state < TorProcess::Starting) - return; - - controlPortTimer.stop(); - errorMessage = process.errorString().toStdString(); - - if (errorMessage.empty()) - errorMessage = "Process exited unexpectedly (code " + RsUtil::NumberToString(process.exitCode()) + ")"; - - state = TorProcess::Failed; - /*emit*/ q->errorMessageChanged(errorMessage); - /*emit*/ q->stateChanged(state); -} - -void TorProcessPrivate::processError(QProcess::ProcessError error) -{ - if (error == QProcess::FailedToStart || error == QProcess::Crashed) - processFinished(); -} - -void TorProcessPrivate::processReadable() -{ - while (process.bytesAvailable() > 0) - { - ByteArray line = process.readLine(2048).trimmed(); - - if (!line.empty()) - /*emit*/ q->logMessage(line.toString())); - } -} - - -TorProcessPrivate::TorProcessPrivate(TorProcess *q) - : q(q), state(TorProcess::NotStarted), controlPort(0), controlPortAttempts(0) -{ - connect(&process, &QProcess::started, this, &TorProcessPrivate::processStarted); - connect(&process, (void (QProcess::*)(int, QProcess::ExitStatus))&QProcess::finished, - this, &TorProcessPrivate::processFinished); - connect(&process, (void (QProcess::*)(QProcess::ProcessError))&QProcess::error, - this, &TorProcessPrivate::processError); - connect(&process, &QProcess::readyRead, this, &TorProcessPrivate::processReadable); - - controlPortTimer.setInterval(500); - connect(&controlPortTimer, &QTimer::timeout, this, &TorProcessPrivate::tryReadControlPort); -} - - -#endif diff --git a/libretroshare/src/tor/bytearray.h b/libretroshare/src/tor/bytearray.h index f2c1903cf..e81db0a17 100644 --- a/libretroshare/src/tor/bytearray.h +++ b/libretroshare/src/tor/bytearray.h @@ -11,6 +11,8 @@ #include "util/rsprint.h" #include "util/rsdebug.h" +// This class re-implements QByteArray from Qt library. + class ByteArray: public std::vector { public: From 5fe39248f8d6d2769a264bc3343718334d990af6 Mon Sep 17 00:00:00 2001 From: csoler Date: Sun, 19 Dec 2021 20:22:04 +0100 Subject: [PATCH 40/65] fixed compilation on windows --- libretroshare/src/pqi/pqifdbin.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libretroshare/src/pqi/pqifdbin.cc b/libretroshare/src/pqi/pqifdbin.cc index d5634793d..a3ed6db16 100644 --- a/libretroshare/src/pqi/pqifdbin.cc +++ b/libretroshare/src/pqi/pqifdbin.cc @@ -50,7 +50,7 @@ void RsFdBinInterface::setSocket(int s) #else // On windows, there is no way to determine whether a socket is blobking or not, so we set it to non blocking whatsoever. unsigned long int on = 1; - ret = ioctlsocket(fd[STDOUT_FILENO], FIONBIO, &on); + ioctlsocket(s, FIONBIO, &on); #endif mCLintConnt = s; From f6892066bcaf37c4d952d09566e1ecbe2cf95b9e Mon Sep 17 00:00:00 2001 From: csoler Date: Mon, 20 Dec 2021 16:10:52 +0100 Subject: [PATCH 41/65] fixed compilation on win$ --- libretroshare/src/pqi/pqifdbin.cc | 6 ++++++ libretroshare/src/pqi/pqifdbin.h | 2 +- libretroshare/src/tor/HiddenService.h | 4 ++-- libretroshare/src/tor/TorManager.cpp | 3 +-- libretroshare/src/tor/TorProcess.cpp | 1 - 5 files changed, 10 insertions(+), 6 deletions(-) diff --git a/libretroshare/src/pqi/pqifdbin.cc b/libretroshare/src/pqi/pqifdbin.cc index 255e65b77..b413cf87b 100644 --- a/libretroshare/src/pqi/pqifdbin.cc +++ b/libretroshare/src/pqi/pqifdbin.cc @@ -295,6 +295,12 @@ bool RsFdBinInterface::moretoread(uint32_t /* usec */) { return mTotalInBufferBytes > 0; } + +bool RsFdBinInterface::moretowrite(uint32_t /* usec */) +{ + return mTotalOutBufferBytes > 0 ; +} + bool RsFdBinInterface::cansend(uint32_t) { return isactive(); diff --git a/libretroshare/src/pqi/pqifdbin.h b/libretroshare/src/pqi/pqifdbin.h index 5fa82df8e..df9af39a5 100644 --- a/libretroshare/src/pqi/pqifdbin.h +++ b/libretroshare/src/pqi/pqifdbin.h @@ -48,7 +48,7 @@ public: int netstatus() override; int isactive() override; bool moretoread(uint32_t usec) override; - bool moretowrite(uint32_t usec) { return mTotalOutBufferBytes > 0 ; } + bool moretowrite(uint32_t usec) ; bool cansend(uint32_t usec) override; int close() override; diff --git a/libretroshare/src/tor/HiddenService.h b/libretroshare/src/tor/HiddenService.h index 0e50e93b9..604d8083f 100644 --- a/libretroshare/src/tor/HiddenService.h +++ b/libretroshare/src/tor/HiddenService.h @@ -102,8 +102,8 @@ private: HiddenServiceClient *m_client; // make the object non copyable - HiddenService(const HiddenService& s) {} - HiddenService& operator=(const HiddenService& s) { return *this ; } + HiddenService(const HiddenService&) {} + HiddenService& operator=(const HiddenService&) { return *this ; } }; } diff --git a/libretroshare/src/tor/TorManager.cpp b/libretroshare/src/tor/TorManager.cpp index d2baa128b..ff61acbfc 100644 --- a/libretroshare/src/tor/TorManager.cpp +++ b/libretroshare/src/tor/TorManager.cpp @@ -159,7 +159,7 @@ static bool test_listening_port(const std::string& /*address*/,uint16_t port) return false; /* Initialize socket structure */ - bzero((char *) &serv_addr, sizeof(serv_addr)); + memset((char *) &serv_addr, 0,sizeof(serv_addr)); serv_addr.sin_family = AF_INET; serv_addr.sin_addr.s_addr = INADDR_ANY; @@ -174,7 +174,6 @@ static bool test_listening_port(const std::string& /*address*/,uint16_t port) unix_fcntl_nonblock(sockfd); int res = listen(sockfd,5); - int err = errno; close(sockfd); if(!res) diff --git a/libretroshare/src/tor/TorProcess.cpp b/libretroshare/src/tor/TorProcess.cpp index 06ceb413f..134e542db 100644 --- a/libretroshare/src/tor/TorProcess.cpp +++ b/libretroshare/src/tor/TorProcess.cpp @@ -31,7 +31,6 @@ */ #include -#include #include #include From 8af6ca9fb701bffbaf4dd91b94efb090531ceac5 Mon Sep 17 00:00:00 2001 From: csoler Date: Wed, 22 Dec 2021 14:03:29 +0100 Subject: [PATCH 42/65] fixed a few errors reported by valgrind --- libretroshare/src/pgp/openpgpsdkhandler.cc | 2 ++ libretroshare/src/tor/PendingOperation.cpp | 4 +++- libretroshare/src/tor/TorControl.cpp | 1 + 3 files changed, 6 insertions(+), 1 deletion(-) diff --git a/libretroshare/src/pgp/openpgpsdkhandler.cc b/libretroshare/src/pgp/openpgpsdkhandler.cc index 4b587563d..c6d6da764 100644 --- a/libretroshare/src/pgp/openpgpsdkhandler.cc +++ b/libretroshare/src/pgp/openpgpsdkhandler.cc @@ -161,6 +161,8 @@ OpenPGPSDKHandler::OpenPGPSDKHandler(const std::string& pubring, const std::stri ++i ; } _pubring_last_update_time = time(NULL) ; + _pubring_changed = false; + RsErr() << "Pubring read successfully." ; if(secring_exist) diff --git a/libretroshare/src/tor/PendingOperation.cpp b/libretroshare/src/tor/PendingOperation.cpp index cbfb8897c..197a4871b 100644 --- a/libretroshare/src/tor/PendingOperation.cpp +++ b/libretroshare/src/tor/PendingOperation.cpp @@ -78,9 +78,11 @@ void PendingOperation::finishWithSuccess() if (!m_finished) { m_finished = true; - mFinishedCallback(); + if (isSuccess()) mSuccessCallback(); + + mFinishedCallback(); } } diff --git a/libretroshare/src/tor/TorControl.cpp b/libretroshare/src/tor/TorControl.cpp index b1803dd4e..3ef879e35 100644 --- a/libretroshare/src/tor/TorControl.cpp +++ b/libretroshare/src/tor/TorControl.cpp @@ -65,6 +65,7 @@ static std::ostream& torctrldebug() using namespace Tor; TorControl::TorControl() + : mControlPort(0),mSocksPort(0),mStatus(NotConnected), mTorStatus(TorOffline),mHasOwnership(false) { mSocket = new TorControlSocket(this); } From 49d8a851c5c714dd05b90b86b6952b62e9bf5d90 Mon Sep 17 00:00:00 2001 From: csoler Date: Wed, 22 Dec 2021 22:26:47 +0100 Subject: [PATCH 43/65] moved faulty line causing early deletion of this at the end of the function --- libretroshare/src/tor/PendingOperation.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libretroshare/src/tor/PendingOperation.cpp b/libretroshare/src/tor/PendingOperation.cpp index 197a4871b..ec6a9b6fd 100644 --- a/libretroshare/src/tor/PendingOperation.cpp +++ b/libretroshare/src/tor/PendingOperation.cpp @@ -67,8 +67,8 @@ void PendingOperation::finishWithError(const std::string &message) if (!m_finished) { m_finished = true; - mFinishedCallback(); mErrorCallback(m_errorMessage); + mFinishedCallback(); } } From 59d11b71ce5666d6780b7bc8f1769f1c16b0d299 Mon Sep 17 00:00:00 2001 From: thunder2 Date: Tue, 21 Dec 2021 06:54:00 +0100 Subject: [PATCH 44/65] Changed uint to ByteArray::size_type in StrUtil.cpp --- libretroshare/src/tor/StrUtil.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/libretroshare/src/tor/StrUtil.cpp b/libretroshare/src/tor/StrUtil.cpp index 8e4ac9d20..558013fef 100644 --- a/libretroshare/src/tor/StrUtil.cpp +++ b/libretroshare/src/tor/StrUtil.cpp @@ -39,7 +39,7 @@ ByteArray quotedString(const ByteArray &string) out.push_back('"'); - for (uint i = 0; i < string.size(); ++i) + for (ByteArray::size_type i = 0; i < string.size(); ++i) { switch (string[i]) { @@ -67,7 +67,7 @@ ByteArray unquotedString(const ByteArray& string) ByteArray out; out.reserve(string.size() - 2); - for (uint i = 1; i < string.size(); ++i) + for (ByteArray::size_type i = 1; i < string.size(); ++i) { switch (string[i]) { @@ -89,9 +89,9 @@ std::list splitQuotedStrings(const ByteArray &input, char separator) { std::list out; bool inquote = false; - uint start = 0; + ByteArray::size_type start = 0; - for (uint i = 0; i < input.size(); ++i) + for (ByteArray::size_type i = 0; i < input.size(); ++i) { switch (input[i]) { From 8d020e7395191ee6de33227bf5f8d3707b2d5e4c Mon Sep 17 00:00:00 2001 From: thunder2 Date: Tue, 21 Dec 2021 07:49:01 +0100 Subject: [PATCH 45/65] Changed ifdef Q_OS_WIN to WINDOWS_SYS --- libretroshare/src/tor/TorManager.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libretroshare/src/tor/TorManager.cpp b/libretroshare/src/tor/TorManager.cpp index ff61acbfc..7b4a80363 100644 --- a/libretroshare/src/tor/TorManager.cpp +++ b/libretroshare/src/tor/TorManager.cpp @@ -623,7 +623,7 @@ std::string TorManagerPrivate::torExecutablePath() const return path; #endif -#ifdef Q_OS_WIN +#ifdef WINDOWS_SYS std::string filename("/tor/tor.exe"); #else std::string filename("/tor"); From 15d56f01ac6232640f2cf992b3c8276ed75ae477 Mon Sep 17 00:00:00 2001 From: thunder2 Date: Tue, 21 Dec 2021 16:33:20 +0100 Subject: [PATCH 46/65] Added missing include to string in PendingOperation.h --- libretroshare/src/tor/PendingOperation.h | 1 + 1 file changed, 1 insertion(+) diff --git a/libretroshare/src/tor/PendingOperation.h b/libretroshare/src/tor/PendingOperation.h index 5115f3252..cec170f9e 100644 --- a/libretroshare/src/tor/PendingOperation.h +++ b/libretroshare/src/tor/PendingOperation.h @@ -33,6 +33,7 @@ #pragma once #include +#include /* Represents an asynchronous operation for reporting status * From 5b8ac7e49b1aae597ecf8f0f7969d4e2edb62fa6 Mon Sep 17 00:00:00 2001 From: thunder2 Date: Tue, 21 Dec 2021 12:44:59 +0100 Subject: [PATCH 47/65] Added missing fclose to TorProcess::tryReadControlPort --- libretroshare/src/tor/TorProcess.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/libretroshare/src/tor/TorProcess.cpp b/libretroshare/src/tor/TorProcess.cpp index 134e542db..908070fe8 100644 --- a/libretroshare/src/tor/TorProcess.cpp +++ b/libretroshare/src/tor/TorProcess.cpp @@ -412,6 +412,8 @@ bool TorProcess::tryReadControlPort() ByteArray data = ByteArray((unsigned char*)line,size).trimmed(); free(line); + fclose(file); + int p; if (data.startsWith("PORT=") && (p = data.lastIndexOf(':')) > 0) { mControlHost = data.mid(5, p - 5).toString(); From 085e102ce1234adf1a3ed02eae81bd7a8de88526 Mon Sep 17 00:00:00 2001 From: thunder2 Date: Tue, 21 Dec 2021 07:34:26 +0100 Subject: [PATCH 48/65] Added RsFileUtil for os specific file functions Added RsFileUtil::set_fd_nonblock to set a file descriptor to non blocking --- libretroshare/src/CMakeLists.txt | 1 + libretroshare/src/libretroshare.pro | 2 ++ libretroshare/src/tor/TorProcess.cpp | 5 +-- libretroshare/src/util/rsfile.cc | 51 ++++++++++++++++++++++++++++ libretroshare/src/util/rsfile.h | 29 ++++++++++++++++ 5 files changed, 86 insertions(+), 2 deletions(-) create mode 100644 libretroshare/src/util/rsfile.cc create mode 100644 libretroshare/src/util/rsfile.h diff --git a/libretroshare/src/CMakeLists.txt b/libretroshare/src/CMakeLists.txt index d3ceffecf..c33799d7c 100644 --- a/libretroshare/src/CMakeLists.txt +++ b/libretroshare/src/CMakeLists.txt @@ -347,6 +347,7 @@ list( util/rsurl.cc util/folderiterator.cc util/rsdir.cc + util/rsfile.cc util/dnsresolver.cc util/extaddrfinder.cc util/rsdebug.cc diff --git a/libretroshare/src/libretroshare.pro b/libretroshare/src/libretroshare.pro index 5ebb64290..69dabca79 100644 --- a/libretroshare/src/libretroshare.pro +++ b/libretroshare/src/libretroshare.pro @@ -487,6 +487,7 @@ HEADERS += util/folderiterator.h \ util/rsmemory.h \ util/smallobject.h \ util/rsdir.h \ + util/rsfile.h \ util/argstream.h \ util/rsdiscspace.h \ util/rsnet.h \ @@ -641,6 +642,7 @@ SOURCES += util/folderiterator.cc \ util/rsexpr.cc \ util/smallobject.cc \ util/rsdir.cc \ + util/rsfile.cc \ util/rsdiscspace.cc \ util/rsnet.cc \ util/rsnet_ss.cc \ diff --git a/libretroshare/src/tor/TorProcess.cpp b/libretroshare/src/tor/TorProcess.cpp index 908070fe8..272ddb985 100644 --- a/libretroshare/src/tor/TorProcess.cpp +++ b/libretroshare/src/tor/TorProcess.cpp @@ -35,6 +35,7 @@ #include #include "util/rsdir.h" +#include "util/rsfile.h" #include "pqi/pqifdbin.h" #include "TorProcess.h" @@ -270,8 +271,8 @@ void TorProcess::start() return; // stop the control thread } - unix_fcntl_nonblock(fd[STDOUT_FILENO]); - unix_fcntl_nonblock(fd[STDERR_FILENO]); + RsFileUtil::set_fd_nonblock(fd[STDOUT_FILENO]); + RsFileUtil::set_fd_nonblock(fd[STDERR_FILENO]); mStdOutFD = new RsFdBinInterface(fd[STDOUT_FILENO]); mStdErrFD = new RsFdBinInterface(fd[STDERR_FILENO]); diff --git a/libretroshare/src/util/rsfile.cc b/libretroshare/src/util/rsfile.cc new file mode 100644 index 000000000..fc9f12c21 --- /dev/null +++ b/libretroshare/src/util/rsfile.cc @@ -0,0 +1,51 @@ +/******************************************************************************* + * libretroshare/src/util: rsfile.cc * + * * + * libretroshare: retroshare core library * + * * + * Copyright (C) 2021 Retroshare Team * + * * + * This program is free software: you can redistribute it and/or modify * + * it under the terms of the GNU Lesser General Public License as * + * published by the Free Software Foundation, either version 3 of the * + * License, or (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU Lesser General Public License for more details. * + * * + * You should have received a copy of the GNU Lesser General Public License * + * along with this program. If not, see . * + * * + *******************************************************************************/ + +#include "util/rsfile.h" + +#ifdef WINDOWS_SYS +#include +#include +#include +#else +#include +#endif + +int RsFileUtil::set_fd_nonblock(int fd) +{ + int ret = 0; + +/******************* OS SPECIFIC PART ******************/ +#ifdef WINDOWS_SYS + DWORD mode = PIPE_NOWAIT; + WINBOOL result = SetNamedPipeHandleState((HANDLE) _get_osfhandle(fd), &mode, nullptr, nullptr); + + if (!result) { + ret = -1; + } +#else // ie UNIX + int flags = fcntl(fd, F_GETFL); + ret = fcntl(fd, F_SETFL, flags | O_NONBLOCK); +#endif + + return ret; +} diff --git a/libretroshare/src/util/rsfile.h b/libretroshare/src/util/rsfile.h new file mode 100644 index 000000000..7569b5af5 --- /dev/null +++ b/libretroshare/src/util/rsfile.h @@ -0,0 +1,29 @@ +/******************************************************************************* + * libretroshare/src/util: rsfile.h * + * * + * libretroshare: retroshare core library * + * * + * Copyright (C) 2021 Retroshare Team * + * * + * This program is free software: you can redistribute it and/or modify * + * it under the terms of the GNU Lesser General Public License as * + * published by the Free Software Foundation, either version 3 of the * + * License, or (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU Lesser General Public License for more details. * + * * + * You should have received a copy of the GNU Lesser General Public License * + * along with this program. If not, see . * + * * + *******************************************************************************/ + +#pragma once + +namespace RsFileUtil { + +int set_fd_nonblock(int fd); + +} From 057e872eca9439ce801bb2c4c67e172822cf7a3b Mon Sep 17 00:00:00 2001 From: thunder2 Date: Tue, 21 Dec 2021 18:12:59 +0100 Subject: [PATCH 49/65] Added missing initializations of members in constructor of TorControl --- libretroshare/src/tor/TorControl.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/libretroshare/src/tor/TorControl.cpp b/libretroshare/src/tor/TorControl.cpp index 3ef879e35..5da312613 100644 --- a/libretroshare/src/tor/TorControl.cpp +++ b/libretroshare/src/tor/TorControl.cpp @@ -68,6 +68,11 @@ TorControl::TorControl() : mControlPort(0),mSocksPort(0),mStatus(NotConnected), mTorStatus(TorOffline),mHasOwnership(false) { mSocket = new TorControlSocket(this); + mControlPort = 0; + mSocksPort = 0; + mStatus = NotConnected; + mTorStatus = TorUnknown; + mHasOwnership = false; } static RsTorConnectivityStatus torConnectivityStatus(Tor::TorControl::Status t) From 38b4c5063568935f636c416d398b3bc6ee4e0aab Mon Sep 17 00:00:00 2001 From: thunder2 Date: Tue, 21 Dec 2021 07:43:44 +0100 Subject: [PATCH 50/65] Changed RsFdBinInterface to use recv/send for sockets and read/write for file descriptors on Windows --- libretroshare/src/pqi/pqifdbin.cc | 38 ++++++++++++++++++++++------ libretroshare/src/pqi/pqifdbin.h | 3 ++- libretroshare/src/pqi/rstcpsocket.cc | 4 +-- libretroshare/src/tor/TorProcess.cpp | 4 +-- 4 files changed, 36 insertions(+), 13 deletions(-) diff --git a/libretroshare/src/pqi/pqifdbin.cc b/libretroshare/src/pqi/pqifdbin.cc index b413cf87b..20c2451f0 100644 --- a/libretroshare/src/pqi/pqifdbin.cc +++ b/libretroshare/src/pqi/pqifdbin.cc @@ -21,10 +21,11 @@ ******************************************************************************/ #include "util/rsprint.h" +#include "util/rsfile.h" #include "pqi/pqifdbin.h" -RsFdBinInterface::RsFdBinInterface(int file_descriptor) - : mCLintConnt(file_descriptor),mIsActive(false) +RsFdBinInterface::RsFdBinInterface(int file_descriptor, bool is_socket) + : mCLintConnt(file_descriptor),mIsSocket(is_socket),mIsActive(false) { mTotalReadBytes=0; mTotalInBufferBytes=0; @@ -53,8 +54,11 @@ void RsFdBinInterface::setSocket(int s) #else // On windows, there is no way to determine whether a socket is blocking or not, so we set it to non blocking whatsoever. - unsigned long int on = 1; - ioctlsocket(s, FIONBIO, &on); + if (mIsSocket) { + unix_fcntl_nonblock(s); + } else { + RsFileUtil::set_fd_nonblock(s); + } #endif mCLintConnt = s; @@ -82,8 +86,15 @@ int RsFdBinInterface::read_pending() char inBuffer[1025]; memset(inBuffer,0,1025); - ssize_t readbytes = read(mCLintConnt, inBuffer, sizeof(inBuffer)); // Needs read instead of recv which is only for sockets. - // Sockets should be set to non blocking by the client process. + ssize_t readbytes; +#if WINDOWS_SYS + if (mIsSocket) + // Windows needs recv for sockets + readbytes = recv(mCLintConnt, inBuffer, sizeof(inBuffer), 0); + else +#endif + readbytes = read(mCLintConnt, inBuffer, sizeof(inBuffer)); // Needs read instead of recv which is only for sockets. + // Sockets should be set to non blocking by the client process. if(readbytes == 0) { @@ -95,7 +106,11 @@ int RsFdBinInterface::read_pending() } if(readbytes < 0) { - if(errno != EWOULDBLOCK && errno != EAGAIN) + if(errno != 0 && errno != EWOULDBLOCK && errno != EAGAIN) +#ifdef WINDOWS_SYS + // A non blocking read to file descriptor gets ERROR_NO_DATA for empty data + if (mIsSocket == true || GetLastError() != ERROR_NO_DATA) +#endif RsErr() << "read() failed. Errno=" << errno ; return mTotalInBufferBytes; @@ -138,7 +153,14 @@ int RsFdBinInterface::write_pending() return mTotalOutBufferBytes; auto& p = out_buffer.front(); - int written = write(mCLintConnt, p.first, p.second); + int written; +#if WINDOWS_SYS + if (mIsSocket) + // Windows needs send for sockets + written = send(mCLintConnt, (char*) p.first, p.second, 0); + else +#endif + written = write(mCLintConnt, p.first, p.second); if(written < 0) { diff --git a/libretroshare/src/pqi/pqifdbin.h b/libretroshare/src/pqi/pqifdbin.h index df9af39a5..a3709c22e 100644 --- a/libretroshare/src/pqi/pqifdbin.h +++ b/libretroshare/src/pqi/pqifdbin.h @@ -25,7 +25,7 @@ class RsFdBinInterface: public BinInterface { public: - RsFdBinInterface(int file_descriptor); + RsFdBinInterface(int file_descriptor, bool is_socket); ~RsFdBinInterface(); // Implements BinInterface methods @@ -70,6 +70,7 @@ private: int write_pending(); int mCLintConnt; + bool mIsSocket; bool mIsActive; uint32_t mTotalReadBytes; uint32_t mTotalInBufferBytes; diff --git a/libretroshare/src/pqi/rstcpsocket.cc b/libretroshare/src/pqi/rstcpsocket.cc index ac91414b3..f42f100a2 100644 --- a/libretroshare/src/pqi/rstcpsocket.cc +++ b/libretroshare/src/pqi/rstcpsocket.cc @@ -18,12 +18,12 @@ #include "rstcpsocket.h" 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, true),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) + :RsFdBinInterface(0, true),mState(DISCONNECTED),mConnectAddress("0.0.0.0"),mConnectPort(0),mSocket(0) { } diff --git a/libretroshare/src/tor/TorProcess.cpp b/libretroshare/src/tor/TorProcess.cpp index 272ddb985..04f62a12a 100644 --- a/libretroshare/src/tor/TorProcess.cpp +++ b/libretroshare/src/tor/TorProcess.cpp @@ -274,8 +274,8 @@ void TorProcess::start() RsFileUtil::set_fd_nonblock(fd[STDOUT_FILENO]); RsFileUtil::set_fd_nonblock(fd[STDERR_FILENO]); - mStdOutFD = new RsFdBinInterface(fd[STDOUT_FILENO]); - mStdErrFD = new RsFdBinInterface(fd[STDERR_FILENO]); + mStdOutFD = new RsFdBinInterface(fd[STDOUT_FILENO], false); + mStdErrFD = new RsFdBinInterface(fd[STDERR_FILENO], false); } void TorProcess::tick() From 753250b4e8b05a22ecd72d2cacf092faba15562b Mon Sep 17 00:00:00 2001 From: thunder2 Date: Tue, 21 Dec 2021 09:03:56 +0100 Subject: [PATCH 51/65] Added os specific RsFileUtil::rs_getline --- libretroshare/src/tor/TorProcess.cpp | 2 +- libretroshare/src/util/rsfile.cc | 56 ++++++++++++++++++++++++++++ libretroshare/src/util/rsfile.h | 3 ++ 3 files changed, 60 insertions(+), 1 deletion(-) diff --git a/libretroshare/src/tor/TorProcess.cpp b/libretroshare/src/tor/TorProcess.cpp index 04f62a12a..1836c4f4e 100644 --- a/libretroshare/src/tor/TorProcess.cpp +++ b/libretroshare/src/tor/TorProcess.cpp @@ -409,7 +409,7 @@ bool TorProcess::tryReadControlPort() char *line = nullptr; size_t tmp_buffsize = 0; - size_t size = getline(&line,&tmp_buffsize,file); + size_t size = RsFileUtil::rs_getline(&line,&tmp_buffsize,file); ByteArray data = ByteArray((unsigned char*)line,size).trimmed(); free(line); diff --git a/libretroshare/src/util/rsfile.cc b/libretroshare/src/util/rsfile.cc index fc9f12c21..6d3f7b1ab 100644 --- a/libretroshare/src/util/rsfile.cc +++ b/libretroshare/src/util/rsfile.cc @@ -26,6 +26,7 @@ #include #include #include +#include #else #include #endif @@ -49,3 +50,58 @@ int RsFileUtil::set_fd_nonblock(int fd) return ret; } + +ssize_t RsFileUtil::rs_getline(char **lineptr, size_t *n, FILE *stream) +{ +/******************* OS SPECIFIC PART ******************/ +#ifdef WINDOWS_SYS + if (lineptr == nullptr || n == nullptr || stream == nullptr) { + errno = EINVAL; + return -1; + } + + if (*lineptr == nullptr || *n < 1) { + *n = BUFSIZ; + *lineptr = (char*) malloc(*n); + if (*lineptr == nullptr) { + *n = 0; + return -1; + } + } + + char *ptr = *lineptr; + while (true) { + int c = fgetc(stream); + if (c == -1) { + if (feof(stream)) { + *ptr = '\0'; + return (ssize_t) (ptr - *lineptr); + } + return -1; + } + + *ptr = c; + ++ptr; + + if (c == '\n') { + *ptr = '\0'; + return ptr - *lineptr; + } + if (ptr + 2 >= *lineptr + *n) { + size_t new_size = *n * 2; + ssize_t diff = ptr - *lineptr; + + char *new_lineptr = (char*) realloc(*lineptr, new_size); + if (new_lineptr == nullptr) { + return -1; + } + + *lineptr = new_lineptr; + *n = new_size; + ptr = new_lineptr + diff; + } + } +#else // ie UNIX + return getline(lineptr, n, stream); +#endif +} diff --git a/libretroshare/src/util/rsfile.h b/libretroshare/src/util/rsfile.h index 7569b5af5..9a23b6a4c 100644 --- a/libretroshare/src/util/rsfile.h +++ b/libretroshare/src/util/rsfile.h @@ -22,8 +22,11 @@ #pragma once +#include + namespace RsFileUtil { int set_fd_nonblock(int fd); +ssize_t rs_getline(char **lineptr, size_t *n, FILE *stream); } From 5dfbdc08692c3f4a6727fff81f9ba3594b436d41 Mon Sep 17 00:00:00 2001 From: thunder2 Date: Tue, 21 Dec 2021 09:26:32 +0100 Subject: [PATCH 52/65] Fixed start and stop of tor process on Windows --- libretroshare/src/tor/TorProcess.cpp | 164 ++++++++++++++++++++------- libretroshare/src/tor/TorProcess.h | 8 +- 2 files changed, 128 insertions(+), 44 deletions(-) diff --git a/libretroshare/src/tor/TorProcess.cpp b/libretroshare/src/tor/TorProcess.cpp index 1836c4f4e..5f23a9512 100644 --- a/libretroshare/src/tor/TorProcess.cpp +++ b/libretroshare/src/tor/TorProcess.cpp @@ -41,6 +41,13 @@ #include "TorProcess.h" #include "CryptoKey.h" +#ifdef WINDOWS_SYS +#include "util/rsstring.h" + +#include +#define pipe(fds) _pipe(fds, 1024, _O_BINARY) +#endif + using namespace Tor; static const int INTERVAL_BETWEEN_CONTROL_PORT_READ_TRIES = 5; // try every 5 secs. @@ -111,7 +118,7 @@ std::string TorProcess::errorMessage() const // Does a popen, but dup all file descriptors (STDIN STDOUT and STDERR) to the // FDs supplied by the parent process -int popen3(int fd[3],const char **const cmd,pid_t& pid) +int popen3(int fd[3],const std::vector& args,TorProcessHandle& pid) { RsErr() << "Launching Tor in background..." ; @@ -124,42 +131,120 @@ int popen3(int fd[3],const char **const cmd,pid_t& pid) for(int i=0; i<3; i++) if(pipe(p[i])) goto error; - // and fork - pid = fork(); - if(-1 == pid) - goto error; - // in the parent? - if(pid) - { - // parent - fd[STDIN_FILENO] = p[STDIN_FILENO][1]; - close(p[STDIN_FILENO][0]); - fd[STDOUT_FILENO] = p[STDOUT_FILENO][0]; - close(p[STDOUT_FILENO][1]); - fd[STDERR_FILENO] = p[STDERR_FILENO][0]; - close(p[STDERR_FILENO][1]); - // success - return 0; + +#ifdef WINDOWS_SYS + // Set up members of the PROCESS_INFORMATION structure. + PROCESS_INFORMATION pi; + ZeroMemory(&pi, sizeof(PROCESS_INFORMATION)); + + // Set up members of the STARTUPINFO structure. + // This structure specifies the STDIN and STDOUT handles for redirection. + STARTUPINFO si; + ZeroMemory(&si, sizeof(STARTUPINFO)); + si.cb = sizeof(STARTUPINFO); + si.hStdInput = (HANDLE) _get_osfhandle(p[STDIN_FILENO][0]); + si.hStdOutput = (HANDLE) _get_osfhandle(p[STDOUT_FILENO][1]); + si.hStdError = (HANDLE) _get_osfhandle(p[STDERR_FILENO][1]); + si.dwFlags |= STARTF_USESTDHANDLES; + + if (si.hStdInput != INVALID_HANDLE_VALUE && + si.hStdOutput != INVALID_HANDLE_VALUE && + si.hStdError != INVALID_HANDLE_VALUE) { + // build commandline + std::string cmd; + for (std::vector::const_iterator it = args.begin(); it != args.end(); ++it) { + if (it != args.begin()) { + cmd += " "; + } + cmd += *it; + } + + std::wstring wcmd; + if (!librs::util::ConvertUtf8ToUtf16(cmd, wcmd)) { + goto error; + } + + WINBOOL success = CreateProcess(nullptr, + (LPWSTR) wcmd.c_str(), // command line + nullptr, // process security attributes + nullptr, // primary thread security attributes + TRUE, // handles are inherited + 0, // creation flags + nullptr, // use parent's environment + nullptr, // use parent's current directory + &si, // STARTUPINFO pointer + &pi); // receives PROCESS_INFORMATION + + if (success) { + pid = pi.hProcess; + + CloseHandle(pi.hThread); + + fd[STDIN_FILENO] = p[STDIN_FILENO][1]; + close(p[STDIN_FILENO][0]); + fd[STDOUT_FILENO] = p[STDOUT_FILENO][0]; + close(p[STDOUT_FILENO][1]); + fd[STDERR_FILENO] = p[STDERR_FILENO][0]; + close(p[STDERR_FILENO][1]); + + // success + return 0; + } } - else + + // fall through error + +#else { - RsErr() << "Launching sub-process..." ; - // child - dup2(p[STDIN_FILENO][0],STDIN_FILENO); - close(p[STDIN_FILENO][1]); - dup2(p[STDOUT_FILENO][1],STDOUT_FILENO); - close(p[STDOUT_FILENO][0]); - dup2(p[STDERR_FILENO][1],STDERR_FILENO); - close(p[STDERR_FILENO][0]); + const char *arguments[args.size()+1]; + int n=0; - // here we try and run it + // We first pushed everything into a vector of strings to save the pointers obtained from string returning methods + // by the time the process is launched. - execv(*cmd,const_cast(cmd)); + for(uint32_t i=0;i(arguments)); + + // if we are there, then we failed to launch our program + perror("Could not launch"); + fprintf(stderr," \"%s\"\n",*arguments); + } } +#endif error: e = errno; @@ -251,20 +336,9 @@ void TorProcess::start() for(auto s:mExtraSettings) args.push_back(s); - const char *arguments[args.size()+1]; - int n=0; - - // We first pushed everything into a vector of strings to save the pointers obtained from string returning methods - // by the time the process is launched. - - for(uint32_t i=0;i Date: Mon, 27 Dec 2021 16:38:29 +0100 Subject: [PATCH 53/65] Added flag for CreateProcess to hide the terminal window of Tor on Windows --- libretroshare/src/tor/TorProcess.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/libretroshare/src/tor/TorProcess.cpp b/libretroshare/src/tor/TorProcess.cpp index 5f23a9512..b7b66da90 100644 --- a/libretroshare/src/tor/TorProcess.cpp +++ b/libretroshare/src/tor/TorProcess.cpp @@ -145,7 +145,8 @@ int popen3(int fd[3],const std::vector& args,TorProcessHandle& pid) si.hStdInput = (HANDLE) _get_osfhandle(p[STDIN_FILENO][0]); si.hStdOutput = (HANDLE) _get_osfhandle(p[STDOUT_FILENO][1]); si.hStdError = (HANDLE) _get_osfhandle(p[STDERR_FILENO][1]); - si.dwFlags |= STARTF_USESTDHANDLES; + si.wShowWindow = SW_HIDE; + si.dwFlags = STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW; if (si.hStdInput != INVALID_HANDLE_VALUE && si.hStdOutput != INVALID_HANDLE_VALUE && From 17bce5718513ebd54222c0a4cf47a8a9008443b7 Mon Sep 17 00:00:00 2001 From: thunder2 Date: Mon, 27 Dec 2021 19:10:18 +0100 Subject: [PATCH 54/65] Added compare of Windows like directory separator to rsdir.cc --- libretroshare/src/util/rsdir.cc | 89 ++++++++++++++++++++------------- libretroshare/src/util/rsdir.h | 1 + 2 files changed, 56 insertions(+), 34 deletions(-) diff --git a/libretroshare/src/util/rsdir.cc b/libretroshare/src/util/rsdir.cc index 897a481ee..24bfbd3e3 100644 --- a/libretroshare/src/util/rsdir.cc +++ b/libretroshare/src/util/rsdir.cc @@ -60,6 +60,12 @@ #define canonicalize_file_name(p) realpath(p, NULL) #endif +#ifdef WINDOWS_SYS +#define FIND_OF_DIRECTORY_SEPARATOR "/\\\0" +#else +#define FIND_OF_DIRECTORY_SEPARATOR '/' +#endif + /**** * #define RSDIR_DEBUG 1 ****/ @@ -68,7 +74,7 @@ bool std::filesystem::create_directories(const std::string& path) { for( std::string::size_type lastIndex = 0; lastIndex < std::string::npos; - lastIndex = path.find('/', lastIndex) ) + lastIndex = path.find_first_of(FIND_OF_DIRECTORY_SEPARATOR, lastIndex) ) { std::string&& curDir = path.substr(0, ++lastIndex); if(!RsDirUtil::checkCreateDirectory(curDir)) @@ -86,7 +92,7 @@ bool std::filesystem::create_directories(const std::string& path) std::string RsDirUtil::getFileName(const std::string& full_file_path) { - size_t n = full_file_path.find_last_of('/'); + std::string::size_type n = full_file_path.find_last_of(FIND_OF_DIRECTORY_SEPARATOR); if(n == std::string::npos) return full_file_path; @@ -96,7 +102,7 @@ std::string RsDirUtil::getFileName(const std::string& full_file_path) std::string RsDirUtil::getDirectory(const std::string& full_file_path) { - size_t n = full_file_path.find_last_of('/'); + std::string::size_type n = full_file_path.find_last_of(FIND_OF_DIRECTORY_SEPARATOR); if(n == std::string::npos) return std::string(); @@ -111,10 +117,10 @@ std::string RsDirUtil::getTopDir(const std::string& dir) */ int i,j; int len = dir.length(); - for(j = len - 1; (j > 0) && (dir[j] == '/'); j--) ; - for(i = j; (i > 0) && (dir[i] != '/'); i--) ; + for(j = len - 1; (j > 0) && RsDirUtil::isDirectorySeparator(dir[j]); j--) ; + for(i = j; (i > 0) && !RsDirUtil::isDirectorySeparator(dir[i]); i--) ; - if (dir[i] == '/') + if (RsDirUtil::isDirectorySeparator(dir[i])) i++; for(; i <= j; i++) @@ -144,9 +150,9 @@ const char *RsDirUtil::scanf_string_for_uint(int bytes) bool RsDirUtil::splitDirFromFile(const std::string& full_path,std::string& dir, std::string& file) { - int i = full_path.rfind('/', full_path.size()-1); + std::string::size_type i = full_path.find_last_of(FIND_OF_DIRECTORY_SEPARATOR, full_path.size()-1); - if(i == full_path.size()-1) // '/' not found! + if(i == std::string::npos) // '/' not found! { file = full_path ; dir = "." ; @@ -165,13 +171,13 @@ void RsDirUtil::removeTopDir(const std::string& dir, std::string& path) /* remove the subdir: [/][dir1.../][/] */ - int j = dir.find_last_not_of('/'); - int i = dir.rfind('/', j); + int j = dir.find_last_not_of(FIND_OF_DIRECTORY_SEPARATOR); + int i = dir.find_last_of(FIND_OF_DIRECTORY_SEPARATOR, j); /* remove any more slashes */ if (i > 0) { - i = dir.find_last_not_of('/', i); + i = dir.find_last_not_of(FIND_OF_DIRECTORY_SEPARATOR, i); } if (i > 0) @@ -188,8 +194,8 @@ std::string RsDirUtil::getRootDir(const std::string& dir) */ int i,j; int len = dir.length(); - for(i = 0; (i < len) && (dir[i] == '/'); i++) ; - for(j = i; (j < len) && (dir[j] != '/'); j++) ; + for(i = 0; (i < len) && RsDirUtil::isDirectorySeparator(dir[i]); i++) ; + for(j = i; (j < len) && !RsDirUtil::isDirectorySeparator(dir[j]); j++) ; if (i == j) return root; /* empty */ for(; i < j; i++) @@ -206,12 +212,12 @@ std::string RsDirUtil::removeRootDir(const std::string& path) std::string output; /* chew leading '/'s */ - for(i = 0; (i < len) && (path[i] == '/'); i++) ; + for(i = 0; (i < len) && RsDirUtil::isDirectorySeparator(path[i]); i++) ; if (i == len) return output; /* empty string */ - for(j = i; (j < len) && (path[j] != '/'); j++) ; /* run to next '/' */ - for(; (j < len) && (path[j] == '/'); j++) ; /* chew leading '/'s */ + for(j = i; (j < len) && !RsDirUtil::isDirectorySeparator(path[j]); j++) ; /* run to next '/' */ + for(; (j < len) && RsDirUtil::isDirectorySeparator(path[j]); j++) ; /* chew leading '/'s */ for(; j < len; j++) { @@ -232,7 +238,7 @@ std::string RsDirUtil::removeRootDirs(const std::string& path, const std::string if ((root.length() < 1) || (path.length() < 1)) return notroot; - if ((path[0] == '/') && (root[0] != '/')) + if (RsDirUtil::isDirectorySeparator(path[0]) && !RsDirUtil::isDirectorySeparator(root[0])) { i++; } @@ -251,7 +257,7 @@ std::string RsDirUtil::removeRootDirs(const std::string& path, const std::string return notroot; } - if (path[i] == '/') + if (RsDirUtil::isDirectorySeparator(path[i])) { i++; } @@ -275,7 +281,7 @@ int RsDirUtil::breakupDirList(const std::string& path, unsigned int i; for(i = 0; i < path.length(); i++) { - if (path[i] == '/') + if (RsDirUtil::isDirectorySeparator(path[i])) { if (i - start > 0) { @@ -890,11 +896,26 @@ std::string RsDirUtil::convertPathToUnix(std::string path) return path; } +bool RsDirUtil::isDirectorySeparator(const char &c) +{ + if (c == '/') { + return true; + } + +#ifdef WINDOWS_SYS + if (c == '\\') { + return true; + } +#endif + + return false; +} + std::string RsDirUtil::makePath(const std::string &path1, const std::string &path2) { std::string path = path1; - if (path.empty() == false && *path.rbegin() != '/') { + if (path.empty() == false && !RsDirUtil::isDirectorySeparator(*path.rbegin())) { path += "/"; } path += path2; @@ -1031,10 +1052,10 @@ std::wstring RsDirUtil::getWideTopDir(std::wstring dir) */ int i,j; int len = dir.length(); - for(j = len - 1; (j > 0) && (dir[j] == '/'); j--); - for(i = j; (i > 0) && (dir[i] != '/'); i--); + for(j = len - 1; (j > 0) && RsDirUtil::isDirectorySeparator(dir[j]); j--); + for(i = j; (i > 0) && !RsDirUtil::isDirectorySeparator(dir[i]); i--); - if (dir[i] == '/') + if (RsDirUtil::isDirectorySeparator(dir[i])) i++; for(; i <= j; i++) @@ -1053,11 +1074,11 @@ std::wstring RsDirUtil::removeWideTopDir(std::wstring dir) */ int i,j; int len = dir.length(); - for(j = len - 1; (j > 0) && (dir[j] == '/'); j--); - for(i = j; (i >= 0) && (dir[i] != '/'); i--); + for(j = len - 1; (j > 0) && RsDirUtil::isDirectorySeparator(dir[j]); j--); + for(i = j; (i >= 0) && !RsDirUtil::isDirectorySeparator(dir[i]); i--); /* remove any more slashes */ - for(; (i >= 0) && (dir[i] == '/'); i--); + for(; (i >= 0) && RsDirUtil::isDirectorySeparator(dir[i]); i--); for(j = 0; j <= i; j++) { @@ -1075,8 +1096,8 @@ std::wstring RsDirUtil::getWideRootDir(std::wstring dir) */ int i,j; int len = dir.length(); - for(i = 0; (i < len) && (dir[i] == '/'); i++); - for(j = i; (j < len) && (dir[j] != '/'); j++); + for(i = 0; (i < len) && RsDirUtil::isDirectorySeparator(dir[i]); i++); + for(j = i; (j < len) && !RsDirUtil::isDirectorySeparator(dir[j]); j++); if (i == j) return root; /* empty */ for(; i < j; i++) @@ -1093,12 +1114,12 @@ std::wstring RsDirUtil::removeWideRootDir(std::wstring path) std::wstring output; /* chew leading '/'s */ - for(i = 0; (i < len) && (path[i] == '/'); i++); + for(i = 0; (i < len) && RsDirUtil::isDirectorySeparator(path[i]); i++); if (i == len) return output; /* empty string */ - for(j = i; (j < len) && (path[j] != '/'); j++); /* run to next '/' */ - for(; (j < len) && (path[j] == '/'); j++); /* chew leading '/'s */ + for(j = i; (j < len) && !RsDirUtil::isDirectorySeparator(path[j]); j++); /* run to next '/' */ + for(; (j < len) && RsDirUtil::isDirectorySeparator(path[j]); j++); /* chew leading '/'s */ for(; j < len; j++) { @@ -1119,7 +1140,7 @@ std::wstring RsDirUtil::removeWideRootDirs(std::wstring path, std::wstring root) if ((root.length() < 1) || (path.length() < 1)) return notroot; - if ((path[0] == '/') && (root[0] != '/')) + if (RsDirUtil::isDirectorySeparator(path[0]) && !RsDirUtil::isDirectorySeparator(root[0])) { i++; } @@ -1138,7 +1159,7 @@ std::wstring RsDirUtil::removeWideRootDirs(std::wstring path, std::wstring root) return notroot; } - if (path[i] == '/') + if (RsDirUtil::isDirectorySeparator(path[i])) { i++; } @@ -1162,7 +1183,7 @@ int RsDirUtil::breakupWideDirList(std::wstring path, unsigned int i; for(i = 0; i < path.length(); i++) { - if (path[i] == '/') + if (RsDirUtil::isDirectorySeparator(path[i])) { if (i - start > 0) { diff --git a/libretroshare/src/util/rsdir.h b/libretroshare/src/util/rsdir.h index 457f4c26e..c50caaf87 100644 --- a/libretroshare/src/util/rsdir.h +++ b/libretroshare/src/util/rsdir.h @@ -173,6 +173,7 @@ bool getWideFileHash(std::wstring filepath, RsFileHash &hash, u FILE *rs_fopen(const char* filename, const char* mode); std::string convertPathToUnix(std::string path); +bool isDirectorySeparator(const char &c); /** Concatenate two path pieces putting '/' separator between them only if * needed */ From efe2ec03ff9575af403a19cde2b4e1c42a749763 Mon Sep 17 00:00:00 2001 From: csoler Date: Tue, 28 Dec 2021 18:29:33 +0100 Subject: [PATCH 55/65] fixed a few bugs that may cause the bootstrap process to hang --- libretroshare/src/tor/TorControl.cpp | 28 ++++++++++------------ libretroshare/src/tor/TorControlSocket.cpp | 8 ++++++- libretroshare/src/tor/TorManager.cpp | 5 ++++ 3 files changed, 25 insertions(+), 16 deletions(-) diff --git a/libretroshare/src/tor/TorControl.cpp b/libretroshare/src/tor/TorControl.cpp index 5da312613..d6d16355b 100644 --- a/libretroshare/src/tor/TorControl.cpp +++ b/libretroshare/src/tor/TorControl.cpp @@ -65,14 +65,9 @@ static std::ostream& torctrldebug() using namespace Tor; TorControl::TorControl() - : mControlPort(0),mSocksPort(0),mStatus(NotConnected), mTorStatus(TorOffline),mHasOwnership(false) + : mControlPort(0),mSocksPort(0),mStatus(NotConnected), mTorStatus(TorUnknown),mHasOwnership(false) { mSocket = new TorControlSocket(this); - mControlPort = 0; - mSocksPort = 0; - mStatus = NotConnected; - mTorStatus = TorUnknown; - mHasOwnership = false; } static RsTorConnectivityStatus torConnectivityStatus(Tor::TorControl::Status t) @@ -127,6 +122,7 @@ void TorControl::setTorStatus(TorControl::TorStatus n) if (n == mTorStatus) return; + RsDbg() << "Setting TorStatus=" << n ; mTorStatus = n; if(rsEvents) @@ -216,7 +212,10 @@ void TorControl::connect(const std::string &address, uint16_t port) setStatus(Connecting); if(mSocket->connectToHost(address, port)) + { setStatus(SocketConnected); + setTorStatus(TorOffline); // connected and running, but not yet ready + } } void TorControl::reconnect() @@ -246,8 +245,6 @@ void TorControl::authenticateReply(TorControlCommand *sender) torCtrlDebug() << "torctrl: Authentication successful" << std::endl; setStatus(TorControl::Authenticated); - setTorStatus(TorControl::TorUnknown); - TorControlCommand *clientEvents = new TorControlCommand; clientEvents->set_replyLine_callback([this](int code, const ByteArray &data) { statusEvent(code,data);}); @@ -442,8 +439,8 @@ void TorControl::getTorInfoReply(TorControlCommand *sender) torCtrlDebug() << "torctrl: Tor indicates that circuits have been established; state is TorReady" << std::endl; setTorStatus(TorControl::TorReady); } - else - setTorStatus(TorControl::TorOffline); +// else +// setTorStatus(TorControl::TorOffline); auto bootstrap = command->get("status/bootstrap-phase"); if (!bootstrap.empty()) @@ -562,14 +559,15 @@ void TorControl::statusEvent(int /* code */, const ByteArray &data) if (tokens.size() < 3) return; - torCtrlDebug() << "torctrl: status event:" << data.trimmed().toString() << std::endl; - const ByteArray& tok2 = *(++tokens.begin()); + const ByteArray& tok2 = *(++(++tokens.begin())); + torCtrlDebug() << "torctrl: status event:" << data.trimmed().toString() << " tok2=\"" << tok2.toString() << "\"" << std::endl; - if (tok2 == "CIRCUIT_ESTABLISHED") { + if (tok2 == "CIRCUIT_ESTABLISHED") setTorStatus(TorControl::TorReady); - } else if (tok2 == "CIRCUIT_NOT_ESTABLISHED") { + else if (tok2 == "CIRCUIT_NOT_ESTABLISHED") setTorStatus(TorControl::TorOffline); - } else if (tok2 == "BOOTSTRAP") { + else if (tok2 == "BOOTSTRAP") + { tokens.pop_front(); updateBootstrap(tokens); } diff --git a/libretroshare/src/tor/TorControlSocket.cpp b/libretroshare/src/tor/TorControlSocket.cpp index e9740515a..19b373f67 100644 --- a/libretroshare/src/tor/TorControlSocket.cpp +++ b/libretroshare/src/tor/TorControlSocket.cpp @@ -51,7 +51,7 @@ bool TorControlSocket::connectToHost(const std::string& tcp_address,uint16_t tcp { if(RsTcpSocket::connect(tcp_address,tcp_port)) { - start(); + start("TorControlSocket"); return true; } else @@ -131,6 +131,12 @@ void TorControlSocket::process() ByteArray line = readline(5120); + if(line.empty()) // This happens when the incoming buffer isn't empty yet doesn't have a full line already. + { + std::this_thread::sleep_for(std::chrono::milliseconds(50)); + continue; + } + if (!line.endsWith(ByteArray("\r\n"))) { setError("Invalid control message syntax"); return; diff --git a/libretroshare/src/tor/TorManager.cpp b/libretroshare/src/tor/TorManager.cpp index 7b4a80363..dc1f6e116 100644 --- a/libretroshare/src/tor/TorManager.cpp +++ b/libretroshare/src/tor/TorManager.cpp @@ -502,6 +502,11 @@ void TorManager::threadTick() break; case TorControl::HiddenServiceReady: + if(d->control->torStatus() < TorControl::TorReady) + { + d->control->getTorInfo(); // forces TorControl to check its state. + std::this_thread::sleep_for(std::chrono::seconds(1)); + } break; case TorControl::Error: From e096f2feb1ee05602bff82e0ae11cebae82e26af Mon Sep 17 00:00:00 2001 From: thunder2 Date: Wed, 29 Dec 2021 15:32:28 +0100 Subject: [PATCH 56/65] Added unregisterEventsHandler to destructor of TorControlDialog --- retroshare-gui/src/TorControl/TorControlWindow.cpp | 5 +++++ retroshare-gui/src/TorControl/TorControlWindow.h | 1 + 2 files changed, 6 insertions(+) diff --git a/retroshare-gui/src/TorControl/TorControlWindow.cpp b/retroshare-gui/src/TorControl/TorControlWindow.cpp index f60e121f3..c369a6b12 100644 --- a/retroshare-gui/src/TorControl/TorControlWindow.cpp +++ b/retroshare-gui/src/TorControl/TorControlWindow.cpp @@ -51,6 +51,11 @@ TorControlDialog::TorControlDialog(QWidget *) adjustSize(); } +TorControlDialog::~TorControlDialog() +{ + rsEvents->unregisterEventsHandler(mEventHandlerId); +} + void TorControlDialog::handleEvent_main_thread(std::shared_ptr event) { if(event->mType != RsEventType::TOR_MANAGER) return; diff --git a/retroshare-gui/src/TorControl/TorControlWindow.h b/retroshare-gui/src/TorControl/TorControlWindow.h index 7dc8c8bda..412c08ed5 100644 --- a/retroshare-gui/src/TorControl/TorControlWindow.h +++ b/retroshare-gui/src/TorControl/TorControlWindow.h @@ -15,6 +15,7 @@ class TorControlDialog: public QWidget, public Ui::TorControlDialog public: TorControlDialog(QWidget *parent =NULL); + virtual ~TorControlDialog(); enum TorStatus { TOR_STATUS_UNKNOWN = 0x00, From 1fafaeb909b83f76f1bcb11a92e4e49ea4f5a25f Mon Sep 17 00:00:00 2001 From: thunder2 Date: Wed, 29 Dec 2021 16:00:02 +0100 Subject: [PATCH 57/65] Added delete of member TorControlSocket in destructor of TorControl --- libretroshare/src/tor/TorControl.cpp | 5 +++++ libretroshare/src/tor/TorControl.h | 1 + 2 files changed, 6 insertions(+) diff --git a/libretroshare/src/tor/TorControl.cpp b/libretroshare/src/tor/TorControl.cpp index d6d16355b..06d517efc 100644 --- a/libretroshare/src/tor/TorControl.cpp +++ b/libretroshare/src/tor/TorControl.cpp @@ -70,6 +70,11 @@ TorControl::TorControl() mSocket = new TorControlSocket(this); } +TorControl::~TorControl() +{ + delete(mSocket); +} + static RsTorConnectivityStatus torConnectivityStatus(Tor::TorControl::Status t) { switch(t) diff --git a/libretroshare/src/tor/TorControl.h b/libretroshare/src/tor/TorControl.h index 941c088d2..b15c4e047 100644 --- a/libretroshare/src/tor/TorControl.h +++ b/libretroshare/src/tor/TorControl.h @@ -68,6 +68,7 @@ public: }; explicit TorControl(); + virtual ~TorControl(); /* Information */ Status status() const; From 8d3046d157cb448debc3876d82d7567a6d451f92 Mon Sep 17 00:00:00 2001 From: thunder2 Date: Wed, 29 Dec 2021 16:08:20 +0100 Subject: [PATCH 58/65] Removed global variable "Tor::TorControl *torControl" --- libretroshare/src/tor/TorControl.cpp | 2 -- libretroshare/src/tor/TorControl.h | 2 -- 2 files changed, 4 deletions(-) diff --git a/libretroshare/src/tor/TorControl.cpp b/libretroshare/src/tor/TorControl.cpp index 06d517efc..caf4576fa 100644 --- a/libretroshare/src/tor/TorControl.cpp +++ b/libretroshare/src/tor/TorControl.cpp @@ -46,8 +46,6 @@ #include "StrUtil.h" #include "PendingOperation.h" -Tor::TorControl *torControl = 0; - class nullstream: public std::ostream {}; static std::ostream& torctrldebug() diff --git a/libretroshare/src/tor/TorControl.h b/libretroshare/src/tor/TorControl.h index b15c4e047..568a1aaf2 100644 --- a/libretroshare/src/tor/TorControl.h +++ b/libretroshare/src/tor/TorControl.h @@ -149,5 +149,3 @@ private: }; } - -extern Tor::TorControl *torControl; From 97f7e0f93666671b7248df81ea74604c37ad9cf0 Mon Sep 17 00:00:00 2001 From: thunder2 Date: Wed, 29 Dec 2021 16:14:48 +0100 Subject: [PATCH 59/65] Added delete of TorControl in destructor of TorManagerPrivate --- libretroshare/src/tor/TorManager.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/libretroshare/src/tor/TorManager.cpp b/libretroshare/src/tor/TorManager.cpp index dc1f6e116..4e0a5986d 100644 --- a/libretroshare/src/tor/TorManager.cpp +++ b/libretroshare/src/tor/TorManager.cpp @@ -71,6 +71,7 @@ public: HiddenService *hiddenService ; explicit TorManagerPrivate(TorManager *parent = 0); + virtual ~TorManagerPrivate(); std::string torExecutablePath() const; bool createDataDir(const std::string &path); @@ -104,6 +105,11 @@ TorManagerPrivate::TorManagerPrivate(TorManager *parent) control->set_statusChanged_callback([this](int new_status,int /*old_status*/) { controlStatusChanged(new_status); }); } +TorManagerPrivate::~TorManagerPrivate() +{ + delete(control); +} + TorManager *TorManager::instance() { static TorManager *p = 0; From 02afc9062f03236b28866c628bef4fc204b1384d Mon Sep 17 00:00:00 2001 From: thunder2 Date: Wed, 29 Dec 2021 16:31:30 +0100 Subject: [PATCH 60/65] Added delete of TorManagerPrivate in destructor of TorManager --- libretroshare/src/tor/TorManager.cpp | 5 +++++ libretroshare/src/tor/TorManager.h | 1 + 2 files changed, 6 insertions(+) diff --git a/libretroshare/src/tor/TorManager.cpp b/libretroshare/src/tor/TorManager.cpp index 4e0a5986d..bd768af68 100644 --- a/libretroshare/src/tor/TorManager.cpp +++ b/libretroshare/src/tor/TorManager.cpp @@ -95,6 +95,11 @@ TorManager::TorManager() { } +TorManager::~TorManager() +{ + delete(d); +} + TorManagerPrivate::TorManagerPrivate(TorManager *parent) : q(parent) , process(0) diff --git a/libretroshare/src/tor/TorManager.h b/libretroshare/src/tor/TorManager.h index 5a62f6d00..a96370bc7 100644 --- a/libretroshare/src/tor/TorManager.h +++ b/libretroshare/src/tor/TorManager.h @@ -51,6 +51,7 @@ class TorManager : public HiddenServiceClient, public RsThread, public RsTor { public: static TorManager *instance(); + virtual ~TorManager(); TorProcess *process(); TorControl *control(); From 72e52b998c7e7f9dbdc36d54be0217d959fe0fe6 Mon Sep 17 00:00:00 2001 From: thunder2 Date: Wed, 29 Dec 2021 16:41:46 +0100 Subject: [PATCH 61/65] Added check of shouldStop in RsThreadedTcpSocket::run --- libretroshare/src/pqi/rstcpsocket.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libretroshare/src/pqi/rstcpsocket.cc b/libretroshare/src/pqi/rstcpsocket.cc index f42f100a2..f9bf03483 100644 --- a/libretroshare/src/pqi/rstcpsocket.cc +++ b/libretroshare/src/pqi/rstcpsocket.cc @@ -84,7 +84,7 @@ RsThreadedTcpSocket::RsThreadedTcpSocket() : RsTcpSocket() } void RsThreadedTcpSocket::run() { - while(connectionState() == CONNECTED) + while(!shouldStop() && connectionState() == CONNECTED) { tick(); std::this_thread::sleep_for(std::chrono::milliseconds(200)); From 72eb21bbca8600bc2bf4428878c52e60884bfd48 Mon Sep 17 00:00:00 2001 From: thunder2 Date: Wed, 29 Dec 2021 17:56:11 +0100 Subject: [PATCH 62/65] Use shutdownSync instead of shutdown in TorManager::run to stop tor --- libretroshare/src/tor/TorManager.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libretroshare/src/tor/TorManager.cpp b/libretroshare/src/tor/TorManager.cpp index bd768af68..628f35733 100644 --- a/libretroshare/src/tor/TorManager.cpp +++ b/libretroshare/src/tor/TorManager.cpp @@ -462,7 +462,7 @@ void TorManager::run() std::this_thread::sleep_for(std::chrono::milliseconds(50)); } - d->control->shutdown(); + d->control->shutdownSync(); d->process->stop(); if(rsEvents) From 460dbdcdc82499317ff5d500d89290040d995c5e Mon Sep 17 00:00:00 2001 From: thunder2 Date: Wed, 29 Dec 2021 17:23:25 +0100 Subject: [PATCH 63/65] Added shutdown of tor management threads --- libretroshare/src/retroshare/rstor.h | 6 ++++++ libretroshare/src/tor/TorManager.cpp | 15 +++++++++++++-- retroshare-gui/src/main.cpp | 4 ++++ 3 files changed, 23 insertions(+), 2 deletions(-) diff --git a/libretroshare/src/retroshare/rstor.h b/libretroshare/src/retroshare/rstor.h index 0ae966a7e..8eaa4a352 100644 --- a/libretroshare/src/retroshare/rstor.h +++ b/libretroshare/src/retroshare/rstor.h @@ -141,6 +141,12 @@ public: */ static bool start(); + /*! + * \brief stop + * Stop the Tor management threads. + */ + static void stop(); + /*! * \brief getHiddenServiceInfo * Gets information about the hidden service setup by RS to run. diff --git a/libretroshare/src/tor/TorManager.cpp b/libretroshare/src/tor/TorManager.cpp index 628f35733..ff2d53ced 100644 --- a/libretroshare/src/tor/TorManager.cpp +++ b/libretroshare/src/tor/TorManager.cpp @@ -53,6 +53,8 @@ using namespace Tor; +static TorManager *rsTor = nullptr; + namespace Tor { @@ -840,6 +842,17 @@ bool RsTor::start() return instance()->startTorManager(); } +void RsTor::stop() +{ + if (rsTor) { + if (rsTor->isRunning()) { + rsTor->fullstop(); + } + delete(rsTor); + rsTor= nullptr; + } +} + void RsTor::setTorDataDirectory(const std::string& dir) { instance()->setTorDataDirectory(dir); @@ -855,8 +868,6 @@ TorManager *RsTor::instance() assert(getpid() == syscall(SYS_gettid));// make sure we're not in a thread #endif - static TorManager *rsTor = nullptr; - if(rsTor == nullptr) rsTor = new TorManager; diff --git a/retroshare-gui/src/main.cpp b/retroshare-gui/src/main.cpp index d8818db0c..82d78d2b2 100644 --- a/retroshare-gui/src/main.cpp +++ b/retroshare-gui/src/main.cpp @@ -591,6 +591,10 @@ feenableexcept(FE_INVALID | FE_DIVBYZERO); RsGxsUpdateBroadcast::cleanup(); #endif + if (is_auto_tor) { + RsTor::stop(); + } + RsControl::instance()->rsGlobalShutDown(); delete(soundManager); From fb1e0bc81c75b21216f9fb7fa5d2f0a796406ba7 Mon Sep 17 00:00:00 2001 From: csoler Date: Thu, 30 Dec 2021 19:51:20 +0100 Subject: [PATCH 64/65] using random port to link Tor to local node and check that the port is available --- libretroshare/src/tor/TorManager.cpp | 19 +++++++++---------- .../src/TorControl/TorControlWindow.cpp | 9 --------- 2 files changed, 9 insertions(+), 19 deletions(-) diff --git a/libretroshare/src/tor/TorManager.cpp b/libretroshare/src/tor/TorManager.cpp index dc1f6e116..0004fed9f 100644 --- a/libretroshare/src/tor/TorManager.cpp +++ b/libretroshare/src/tor/TorManager.cpp @@ -232,21 +232,20 @@ bool TorManager::setupHiddenService() // for an automatic (and portable) selection. std::string address = "127.0.0.1"; // we only listen from localhost - unsigned short port = 7934;//(quint16)m_settings->read("localListenPort").toInt(); + unsigned short hidden_service_port = 7934;//(quint16)m_settings->read("localListenPort").toInt(); - std::cerr << "Testing host address: " << address << ":" << port ; - - if(!test_listening_port(address,port)) + do { - // XXX error case - std::cerr << " Failed to open incoming socket" << std::endl; - return false; + hidden_service_port = 1025 + (RsRandom::random_u32() >> 17); + + std::cerr << "Testing listening address:port " << address << ":" << hidden_service_port ; + std::cerr.flush(); } + while(!test_listening_port(address,hidden_service_port)); - 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, "127.0.0.1",7934); + d->hiddenService->addTarget(9878, "127.0.0.1",hidden_service_port); control()->addHiddenService(d->hiddenService); return true ; diff --git a/retroshare-gui/src/TorControl/TorControlWindow.cpp b/retroshare-gui/src/TorControl/TorControlWindow.cpp index f60e121f3..ae30027e0 100644 --- a/retroshare-gui/src/TorControl/TorControlWindow.cpp +++ b/retroshare-gui/src/TorControl/TorControlWindow.cpp @@ -26,15 +26,6 @@ TorControlDialog::TorControlDialog(QWidget *) RsQThreadUtils::postToObject([=](){ handleEvent_main_thread(event); }, this ); }, mEventHandlerId, RsEventType::TOR_MANAGER ); - // 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())); - // QObject::connect(tm ,SIGNAL(errorChanged()),this,SLOT(statusChanged())); - - //QTimer::singleShot(2000,this,SLOT(checkForHiddenService())) ; - mIncomingServer = new QTcpServer(this) ; connect(mIncomingServer, SIGNAL(QTcpServer::newConnection()), this, SLOT(onIncomingConnection())); From 281076d6b7262bffc408aa9ccc5c49740b2a8187 Mon Sep 17 00:00:00 2001 From: csoler Date: Thu, 30 Dec 2021 22:14:34 +0100 Subject: [PATCH 65/65] fixed a few errors in TorManager event handling --- libretroshare/src/retroshare/rsevents.h | 2 +- libretroshare/src/retroshare/rstor.h | 9 +++++---- libretroshare/src/tor/TorControl.cpp | 16 +++++++++++----- libretroshare/src/tor/TorControl.h | 15 ++++++++------- libretroshare/src/tor/TorManager.cpp | 9 ++++++--- .../src/TorControl/TorControlWindow.cpp | 15 ++++++++++++--- 6 files changed, 43 insertions(+), 23 deletions(-) diff --git a/libretroshare/src/retroshare/rsevents.h b/libretroshare/src/retroshare/rsevents.h index 80823dd56..9a53ab833 100644 --- a/libretroshare/src/retroshare/rsevents.h +++ b/libretroshare/src/retroshare/rsevents.h @@ -107,7 +107,7 @@ enum class RsEventType : uint32_t FILE_HASHING_COMPLETED = 20, /// @see rspeers.h - TOR_MANAGER = 17, + TOR_MANAGER = 21, __MAX /// Used internally, keep last }; diff --git a/libretroshare/src/retroshare/rstor.h b/libretroshare/src/retroshare/rstor.h index 8eaa4a352..654b79938 100644 --- a/libretroshare/src/retroshare/rstor.h +++ b/libretroshare/src/retroshare/rstor.h @@ -56,10 +56,11 @@ enum class RsTorConnectivityStatus: uint8_t { ERROR = 0x00, NOT_CONNECTED = 0x01, CONNECTING = 0x02, - AUTHENTICATING = 0x03, - AUTHENTICATED = 0x04, - HIDDEN_SERVICE_READY = 0x05, - UNKNOWN = 0x06 + SOCKET_CONNECTED = 0x03, + AUTHENTICATING = 0x04, + AUTHENTICATED = 0x05, + HIDDEN_SERVICE_READY = 0x06, + UNKNOWN = 0x07 }; // Status of the Tor service with which RS is talking. diff --git a/libretroshare/src/tor/TorControl.cpp b/libretroshare/src/tor/TorControl.cpp index caf4576fa..9b456036b 100644 --- a/libretroshare/src/tor/TorControl.cpp +++ b/libretroshare/src/tor/TorControl.cpp @@ -78,11 +78,14 @@ static RsTorConnectivityStatus torConnectivityStatus(Tor::TorControl::Status t) switch(t) { default: - case TorControl::Error: return RsTorConnectivityStatus::ERROR; - case TorControl::NotConnected: return RsTorConnectivityStatus::NOT_CONNECTED; - case TorControl::Connecting: return RsTorConnectivityStatus::CONNECTING; - case TorControl::Authenticating: return RsTorConnectivityStatus::AUTHENTICATING; + case TorControl::Error: return RsTorConnectivityStatus::ERROR; + case TorControl::NotConnected: return RsTorConnectivityStatus::NOT_CONNECTED; + case TorControl::Connecting: return RsTorConnectivityStatus::CONNECTING; + case TorControl::SocketConnected: return RsTorConnectivityStatus::SOCKET_CONNECTED; + case TorControl::Authenticating: return RsTorConnectivityStatus::AUTHENTICATING; case TorControl::Authenticated: return RsTorConnectivityStatus::AUTHENTICATED; + case TorControl::HiddenServiceReady: return RsTorConnectivityStatus::HIDDEN_SERVICE_READY; + case TorControl::Unknown: return RsTorConnectivityStatus::UNKNOWN; } } static RsTorStatus torStatus(Tor::TorControl::TorStatus t) @@ -107,6 +110,8 @@ void TorControl::setStatus(TorControl::Status n) if (old == TorControl::Error) mErrorMessage.clear(); + std::cerr << "Setting status to s=" << mStatus << " val=" << (int)torConnectivityStatus(mStatus) << std::endl; + if(rsEvents) { auto ev = std::make_shared(); @@ -133,8 +138,9 @@ void TorControl::setTorStatus(TorControl::TorStatus n) auto ev = std::make_shared(); ev->mTorManagerEventType = RsTorManagerEventCode::TOR_STATUS_CHANGED; - ev->mTorConnectivityStatus = torConnectivityStatus(mStatus); ev->mTorStatus = ::torStatus(mTorStatus); + ev->mTorConnectivityStatus = torConnectivityStatus(mStatus); + rsEvents->sendEvent(ev); } } diff --git a/libretroshare/src/tor/TorControl.h b/libretroshare/src/tor/TorControl.h index 568a1aaf2..be73aa3f4 100644 --- a/libretroshare/src/tor/TorControl.h +++ b/libretroshare/src/tor/TorControl.h @@ -51,13 +51,14 @@ class TorControl : public TorControlSocketClient public: enum Status { - Error = -1, - NotConnected = 0x00, - Connecting = 0x01, - SocketConnected = 0x02, - Authenticating = 0x03, - Authenticated = 0x04, - HiddenServiceReady = 0x05 + Error = 0x00, + NotConnected = 0x01, + Connecting = 0x02, + SocketConnected = 0x03, + Authenticating = 0x04, + Authenticated = 0x05, + HiddenServiceReady = 0x06, + Unknown = 0x07 }; enum TorStatus diff --git a/libretroshare/src/tor/TorManager.cpp b/libretroshare/src/tor/TorManager.cpp index 4f3cf19c2..0b0f59cef 100644 --- a/libretroshare/src/tor/TorManager.cpp +++ b/libretroshare/src/tor/TorManager.cpp @@ -239,8 +239,6 @@ bool TorManager::setupHiddenService() assert(d->hiddenService); - // connect(d->hiddenService, SIGNAL(statusChanged(int,int)), this, SLOT(hiddenServiceStatusChanged(int,int))); - // Generally, these are not used, and we bind to localhost and port 0 // for an automatic (and portable) selection. @@ -258,6 +256,9 @@ bool TorManager::setupHiddenService() std::cerr << ": OK - Adding hidden service to TorControl." << std::endl; + // Note: 9878 is quite arbitrary, but since each RS node generates its own hidden service, all of them + // can use the same port without any conflict. + d->hiddenService->addTarget(9878, "127.0.0.1",hidden_service_port); control()->addHiddenService(d->hiddenService); @@ -483,6 +484,7 @@ void TorManager::threadTick() switch(d->control->status()) { + case TorControl::Unknown: case TorControl::Connecting: break; @@ -618,12 +620,13 @@ void TorManagerPrivate::getConfFinished(TorControlCommand *sender) if(RsUtil::StringToInt(str,n) && n==1 && !configNeeded) { configNeeded = true; - //emit q->configurationNeededChanged(); if(rsEvents) { auto ev = std::make_shared(); ev->mTorManagerEventType = RsTorManagerEventCode::CONFIGURATION_NEEDED; + ev->mTorConnectivityStatus = RsTorConnectivityStatus::UNKNOWN; + ev->mTorStatus = RsTorStatus::UNKNOWN; rsEvents->sendEvent(ev); } } diff --git a/retroshare-gui/src/TorControl/TorControlWindow.cpp b/retroshare-gui/src/TorControl/TorControlWindow.cpp index 2330c555b..ddab3f281 100644 --- a/retroshare-gui/src/TorControl/TorControlWindow.cpp +++ b/retroshare-gui/src/TorControl/TorControlWindow.cpp @@ -55,7 +55,13 @@ void TorControlDialog::handleEvent_main_thread(std::shared_ptr ev if(!fe) return; - statusChanged(fe->mTorStatus,fe->mTorConnectivityStatus); + switch(fe->mTorManagerEventType) + { + case RsTorManagerEventCode::TOR_STATUS_CHANGED: + case RsTorManagerEventCode::TOR_CONNECTIVITY_CHANGED: statusChanged(fe->mTorStatus,fe->mTorConnectivityStatus); + break; + default: ; + } } void TorControlDialog::onIncomingConnection() @@ -73,12 +79,15 @@ void TorControlDialog::statusChanged(RsTorStatus torstatus, RsTorConnectivitySta switch(tor_control_status) { default: - case RsTorConnectivityStatus::ERROR : tor_control_status_str = tr("Error") ; break ; + case RsTorConnectivityStatus::ERROR: tor_control_status_str = tr("Error") ; break ; case RsTorConnectivityStatus::NOT_CONNECTED: tor_control_status_str = tr("Not connected") ; break ; case RsTorConnectivityStatus::CONNECTING: tor_control_status_str = tr("Connecting") ; break ; + case RsTorConnectivityStatus::SOCKET_CONNECTED: tor_control_status_str = tr("Socket connected") ; break ; case RsTorConnectivityStatus::AUTHENTICATING: tor_control_status_str = tr("Authenticating") ; break ; case RsTorConnectivityStatus::AUTHENTICATED: tor_control_status_str = tr("Authenticated") ; break ; - } + case RsTorConnectivityStatus::HIDDEN_SERVICE_READY: tor_control_status_str = tr("Hidden service ready") ; break ; + case RsTorConnectivityStatus::UNKNOWN: tor_control_status_str = tr("Unknown") ; break ; + } switch(torstatus) {