From d7fb3d8bf4622be397462a18631828278f177385 Mon Sep 17 00:00:00 2001 From: csoler Date: Sat, 19 Jun 2021 15:34:46 +0200 Subject: [PATCH 001/113] 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 002/113] 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 003/113] 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 004/113] 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 005/113] 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 006/113] 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 007/113] 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 008/113] 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 009/113] 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 010/113] 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 011/113] 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 012/113] 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 4db6ac92e77a977c330ad3263db940d79217d90a Mon Sep 17 00:00:00 2001 From: csoler Date: Wed, 11 Aug 2021 16:01:45 +0200 Subject: [PATCH 013/113] initial split of PHPHandler into two classes --- libretroshare/src/libretroshare.pro | 2 + libretroshare/src/pgp/pgphandler.cc | 1742 --------------------------- libretroshare/src/pgp/pgphandler.h | 183 ++- libretroshare/src/pqi/authgpg.cc | 2 +- libretroshare/src/pqi/authgpg.h | 6 +- 5 files changed, 84 insertions(+), 1851 deletions(-) diff --git a/libretroshare/src/libretroshare.pro b/libretroshare/src/libretroshare.pro index 84d18944e..89d9e5d9a 100644 --- a/libretroshare/src/libretroshare.pro +++ b/libretroshare/src/libretroshare.pro @@ -364,6 +364,7 @@ HEADERS += chat/distantchat.h \ HEADERS += pqi/authssl.h \ pqi/authgpg.h \ pgp/pgphandler.h \ + pgp/openpgpsdkhandler.h \ pgp/pgpkeyutil.h \ pgp/rscertificate.h \ pgp/pgpauxutils.h \ @@ -538,6 +539,7 @@ SOURCES += chat/distantchat.cc \ SOURCES += pqi/authgpg.cc \ pqi/authssl.cc \ pgp/pgphandler.cc \ + pgp/openpgpsdkhandler.cc \ pgp/pgpkeyutil.cc \ pgp/rscertificate.cc \ pgp/pgpauxutils.cc \ diff --git a/libretroshare/src/pgp/pgphandler.cc b/libretroshare/src/pgp/pgphandler.cc index b1e96b00b..3a5eaf837 100644 --- a/libretroshare/src/pgp/pgphandler.cc +++ b/libretroshare/src/pgp/pgphandler.cc @@ -33,15 +33,6 @@ #include "util/rswin.h" #endif -extern "C" { -#include -#include -#include -#include -#include -#include -#include -} #include "pgphandler.h" #include "retroshare/rsiface.h" // For rsicontrol. #include "retroshare/rspeers.h" // For rsicontrol. @@ -59,56 +50,6 @@ static const uint32_t PGP_CERTIFICATE_LIMIT_MAX_PASSWD_SIZE = 1024 ; PassphraseCallback PGPHandler::_passphrase_callback = NULL ; -ops_keyring_t *PGPHandler::allocateOPSKeyring() -{ - ops_keyring_t *kr = (ops_keyring_t*)rs_malloc(sizeof(ops_keyring_t)) ; - - if(kr == NULL) - return NULL ; - - kr->nkeys = 0 ; - kr->nkeys_allocated = 0 ; - kr->keys = 0 ; - - return kr ; -} - -ops_parse_cb_return_t cb_get_passphrase(const ops_parser_content_t *content_,ops_parse_cb_info_t *cbinfo)// __attribute__((unused))) -{ - const ops_parser_content_union_t *content=&content_->content; - bool prev_was_bad = false ; - - switch(content_->tag) - { - case OPS_PARSER_CMD_GET_SK_PASSPHRASE_PREV_WAS_BAD: prev_was_bad = true ; - /* fallthrough */ - case OPS_PARSER_CMD_GET_SK_PASSPHRASE: - { - std::string passwd; - std::string uid_hint ; - - if(cbinfo->cryptinfo.keydata->nuids > 0) - uid_hint = std::string((const char *)cbinfo->cryptinfo.keydata->uids[0].user_id) ; - uid_hint += "(" + RsPgpId(cbinfo->cryptinfo.keydata->key_id).toStdString()+")" ; - - bool cancelled = false ; - passwd = PGPHandler::passphraseCallback()(NULL,"",uid_hint.c_str(),NULL,prev_was_bad,&cancelled) ; - - if(cancelled) - *(unsigned char *)cbinfo->arg = 1; - - *(content->secret_key_passphrase.passphrase)= (char *)ops_mallocz(passwd.length()+1) ; - memcpy(*(content->secret_key_passphrase.passphrase),passwd.c_str(),passwd.length()) ; - return OPS_KEEP_MEMORY; - } - break; - - default: - break; - } - - return OPS_RELEASE_MEMORY; -} void PGPHandler::setPassphraseCallback(PassphraseCallback cb) { _passphrase_callback = cb ; @@ -117,195 +58,10 @@ void PGPHandler::setPassphraseCallback(PassphraseCallback cb) PGPHandler::PGPHandler(const std::string& pubring, const std::string& secring,const std::string& trustdb,const std::string& pgp_lock_filename) : pgphandlerMtx(std::string("PGPHandler")), _pubring_path(pubring),_secring_path(secring),_trustdb_path(trustdb),_pgp_lock_filename(pgp_lock_filename) { - RsStackMutex mtx(pgphandlerMtx) ; // lock access to PGP memory structures. - - _pubring_changed = false ; - _trustdb_changed = false ; - - RsStackFileLock flck(_pgp_lock_filename) ; // lock access to PGP directory. - - if(_passphrase_callback == NULL) - std::cerr << "WARNING: before created a PGPHandler, you need to init the passphrase callback using PGPHandler::setPassphraseCallback()" << std::endl; - - // Allocate public and secret keyrings. - // - _pubring = allocateOPSKeyring() ; - _secring = allocateOPSKeyring() ; - - // Check that the file exists. If not, create a void keyring. - - FILE *ftest ; - ftest = RsDirUtil::rs_fopen(pubring.c_str(),"rb") ; - bool pubring_exist = (ftest != NULL) ; - if(ftest != NULL) - fclose(ftest) ; - ftest = RsDirUtil::rs_fopen(secring.c_str(),"rb") ; - bool secring_exist = (ftest != NULL) ; - if(ftest != NULL) - fclose(ftest) ; - - // Read public and secret keyrings from supplied files. - // - if(pubring_exist) - { - if(ops_false == ops_keyring_read_from_file(_pubring, false, pubring.c_str())) - throw std::runtime_error("PGPHandler::readKeyRing(): cannot read pubring. File corrupted.") ; - } - else - std::cerr << "pubring file \"" << pubring << "\" not found. Creating a void keyring." << std::endl; - - const ops_keydata_t *keydata ; - int i=0 ; - while( (keydata = ops_keyring_get_key_by_index(_pubring,i)) != NULL ) - { - PGPCertificateInfo& cert(_public_keyring_map[ RsPgpId(keydata->key_id) ]) ; - - // Init all certificates. - - initCertificateInfo(cert,keydata,i) ; - - // Validate signatures. - - validateAndUpdateSignatures(cert,keydata) ; - - ++i ; - } - _pubring_last_update_time = time(NULL) ; - std::cerr << "Pubring read successfully." << std::endl; - - if(secring_exist) - { - if(ops_false == ops_keyring_read_from_file(_secring, false, secring.c_str())) - throw std::runtime_error("PGPHandler::readKeyRing(): cannot read secring. File corrupted.") ; - } - else - std::cerr << "secring file \"" << secring << "\" not found. Creating a void keyring." << std::endl; - - i=0 ; - while( (keydata = ops_keyring_get_key_by_index(_secring,i)) != NULL ) - { - initCertificateInfo(_secret_keyring_map[ RsPgpId(keydata->key_id) ],keydata,i) ; - ++i ; - } - _secring_last_update_time = time(NULL) ; - - std::cerr << "Secring read successfully." << std::endl; - - locked_readPrivateTrustDatabase() ; - _trustdb_last_update_time = time(NULL) ; -} - -void PGPHandler::initCertificateInfo(PGPCertificateInfo& cert,const ops_keydata_t *keydata,uint32_t index) -{ - // Parse certificate name - // - - if(keydata->uids != NULL) - { - std::string namestring( (char *)keydata->uids[0].user_id ) ; - - cert._name = "" ; - uint32_t i=0; - while(i < namestring.length() && namestring[i] != '(' && namestring[i] != '<') { cert._name += namestring[i] ; ++i ;} - - // trim right spaces - std::string::size_type found = cert._name.find_last_not_of(' '); - if (found != std::string::npos) - cert._name.erase(found + 1); - else - cert._name.clear(); // all whitespace - - std::string& next = (namestring[i] == '(')?cert._comment:cert._email ; - ++i ; - next = "" ; - while(i < namestring.length() && namestring[i] != ')' && namestring[i] != '>') { next += namestring[i] ; ++i ;} - - while(i < namestring.length() && namestring[i] != '(' && namestring[i] != '<') { next += namestring[i] ; ++i ;} - - if(i< namestring.length()) - { - std::string& next2 = (namestring[i] == '(')?cert._comment:cert._email ; - ++i ; - next2 = "" ; - while(i < namestring.length() && namestring[i] != ')' && namestring[i] != '>') { next2 += namestring[i] ; ++i ;} - } - } - - cert._trustLvl = 1 ; // to be setup accordingly - cert._validLvl = 1 ; // to be setup accordingly - cert._key_index = index ; - cert._flags = 0 ; - cert._time_stamp = 0 ;// "never" by default. Will be updated by trust database, and effective key usage. - - switch(keydata->key.pkey.algorithm) - { - case OPS_PKA_RSA: cert._type = PGPCertificateInfo::PGP_CERTIFICATE_TYPE_RSA ; - break ; - case OPS_PKA_DSA: cert._type = PGPCertificateInfo::PGP_CERTIFICATE_TYPE_DSA ; - cert._flags |= PGPCertificateInfo::PGP_CERTIFICATE_FLAG_UNSUPPORTED_ALGORITHM ; - break ; - default: cert._type = PGPCertificateInfo::PGP_CERTIFICATE_TYPE_UNKNOWN ; - cert._flags |= PGPCertificateInfo::PGP_CERTIFICATE_FLAG_UNSUPPORTED_ALGORITHM ; - break ; - } - - ops_fingerprint_t f ; - ops_fingerprint(&f,&keydata->key.pkey) ; - - cert._fpr = PGPFingerprintType(f.fingerprint) ; -} - -bool PGPHandler::validateAndUpdateSignatures(PGPCertificateInfo& cert,const ops_keydata_t *keydata) -{ - ops_validate_result_t* result=(ops_validate_result_t*)ops_mallocz(sizeof *result); - ops_boolean_t res = ops_validate_key_signatures(result,keydata,_pubring,cb_get_passphrase) ; - - if(res == ops_false) - { - static ops_boolean_t already = 0 ; - if(!already) - { - std::cerr << "(WW) Error in PGPHandler::validateAndUpdateSignatures(). Validation failed for at least some signatures." << std::endl; - already = 1 ; - } - } - - bool ret = false ; - - // Parse signers. - // - - if(result != NULL) - for(size_t i=0;ivalid_count;++i) - { - RsPgpId signer_id(result->valid_sigs[i].signer_id); - - if(cert.signers.find(signer_id) == cert.signers.end()) - { - cert.signers.insert(signer_id) ; - ret = true ; - } - } - - ops_validate_result_free(result) ; - - return ret ; } PGPHandler::~PGPHandler() { - RsStackMutex mtx(pgphandlerMtx) ; // lock access to PGP memory structures. -#ifdef DEBUG_PGPHANDLER - std::cerr << "Freeing PGPHandler. Deleting keyrings." << std::endl; -#endif - - // no need to free the the _map_ elements. They will be freed by the following calls: - // - ops_keyring_free(_pubring) ; - ops_keyring_free(_secring) ; - - free(_pubring) ; - free(_secring) ; } bool PGPHandler::printKeys() const @@ -340,19 +96,9 @@ bool PGPHandler::printKeys() const std::cerr << std::endl ; } } - std::cerr << "Public keyring list from OPS:" << std::endl; - ops_keyring_list(_pubring) ; - return true ; } -bool PGPHandler::haveSecretKey(const RsPgpId& id) const -{ - RsStackMutex mtx(pgphandlerMtx) ; // lock access to PGP memory structures. - - return locked_getSecretKey(id) != NULL ; -} - const PGPCertificateInfo *PGPHandler::getCertificateInfo(const RsPgpId& id) const { RsStackMutex mtx(pgphandlerMtx) ; // lock access to PGP memory structures. @@ -365,1186 +111,6 @@ const PGPCertificateInfo *PGPHandler::getCertificateInfo(const RsPgpId& id) cons return NULL ; } -bool PGPHandler::availableGPGCertificatesWithPrivateKeys(std::list& ids) -{ - RsStackMutex mtx(pgphandlerMtx) ; // lock access to PGP memory structures. - // go through secret keyring, and check that we have the pubkey as well. - // - - const ops_keydata_t *keydata = NULL ; - int i=0 ; - - while( (keydata = ops_keyring_get_key_by_index(_secring,i++)) != NULL ) - if(ops_keyring_find_key_by_id(_pubring,keydata->key_id) != NULL) // check that the key is in the pubring as well - { -#ifdef PGPHANDLER_DSA_SUPPORT - if(keydata->key.pkey.algorithm == OPS_PKA_RSA || keydata->key.pkey.algorithm == OPS_PKA_DSA) -#else - if(keydata->key.pkey.algorithm == OPS_PKA_RSA) -#endif - ids.push_back(RsPgpId(keydata->key_id)) ; -#ifdef DEBUG_PGPHANDLER - else - std::cerr << "Skipping keypair " << RsPgpId(keydata->key_id).toStdString() << ", unsupported algorithm: " << keydata->key.pkey.algorithm << std::endl; -#endif - } - - return true ; -} - -bool PGPHandler::GeneratePGPCertificate(const std::string& name, const std::string& email, const std::string& passphrase, RsPgpId& pgpId, const int keynumbits, std::string& errString) -{ - // Some basic checks - - if(!RsDiscSpace::checkForDiscSpace(RS_PGP_DIRECTORY)) - { - errString = std::string("(EE) low disc space in pgp directory. Can't write safely to keyring.") ; - return false ; - } - if(name.length() > PGP_CERTIFICATE_LIMIT_MAX_NAME_SIZE) - { - errString = std::string("(EE) name in certificate exceeds the maximum allowed name size") ; - return false ; - } - if(email.length() > PGP_CERTIFICATE_LIMIT_MAX_EMAIL_SIZE) - { - errString = std::string("(EE) email in certificate exceeds the maximum allowed email size") ; - return false ; - } - if(passphrase.length() > PGP_CERTIFICATE_LIMIT_MAX_PASSWD_SIZE) - { - errString = std::string("(EE) passphrase in certificate exceeds the maximum allowed passphrase size") ; - return false ; - } - if(keynumbits % 1024 != 0) - { - errString = std::string("(EE) RSA key length is not a multiple of 1024") ; - return false ; - } - - // Now the real thing - RsStackMutex mtx(pgphandlerMtx) ; // lock access to PGP memory structures. - RsStackFileLock flck(_pgp_lock_filename) ; // lock access to PGP directory. - - // 1 - generate keypair - RSA-2048 - // - ops_user_id_t uid ; - char *s = strdup((name + " (Generated by RetroShare) <" + email + ">" ).c_str()) ; - uid.user_id = (unsigned char *)s ; - unsigned long int e = 65537 ; // some prime number - - ops_keydata_t *key = ops_rsa_create_selfsigned_keypair(keynumbits, e, &uid) ; - - free(s) ; - - if(!key) - return false ; - - // 2 - save the private key encrypted to a temporary memory buffer, so as to read an encrypted key to memory - - ops_create_info_t *cinfo = NULL ; - ops_memory_t *buf = NULL ; - ops_setup_memory_write(&cinfo, &buf, 0); - - if(!ops_write_transferable_secret_key(key,(unsigned char *)passphrase.c_str(),passphrase.length(),ops_false,cinfo)) - { - errString = std::string("(EE) Cannot encode secret key to memory!!") ; - return false ; - } - - // 3 - read the memory chunk into an encrypted keyring - - ops_keyring_t *tmp_secring = allocateOPSKeyring() ; - - if(! ops_keyring_read_from_mem(tmp_secring, ops_false, buf)) - { - errString = std::string("(EE) Cannot re-read key from memory!!") ; - return false ; - } - ops_teardown_memory_write(cinfo,buf); // cleanup memory - - // 4 - copy the encrypted private key to the private keyring - - pgpId = RsPgpId(tmp_secring->keys[0].key_id) ; - addNewKeyToOPSKeyring(_secring,tmp_secring->keys[0]) ; - initCertificateInfo(_secret_keyring_map[ pgpId ],&tmp_secring->keys[0],_secring->nkeys-1) ; - -#ifdef DEBUG_PGPHANDLER - std::cerr << "Added new secret key with id " << pgpId.toStdString() << " to secret keyring." << std::endl; -#endif - ops_keyring_free(tmp_secring) ; - free(tmp_secring) ; - - // 5 - add key to secret keyring on disk. - - cinfo = NULL ; - std::string secring_path_tmp = _secring_path + ".tmp" ; - - if(RsDirUtil::fileExists(_secring_path) && !RsDirUtil::copyFile(_secring_path,secring_path_tmp)) - { - errString= std::string("Cannot copy secret keyring !! Disk full? Out of disk quota?") ; - return false ; - } - int fd=ops_setup_file_append(&cinfo, secring_path_tmp.c_str()); - - if(!ops_write_transferable_secret_key(key,(unsigned char *)passphrase.c_str(),passphrase.length(),ops_false,cinfo)) - { - errString= std::string("Cannot encode secret key to disk!! Disk full? Out of disk quota?") ; - return false ; - } - ops_teardown_file_write(cinfo,fd) ; - - if(!RsDirUtil::renameFile(secring_path_tmp,_secring_path)) - { - errString= std::string("Cannot rename tmp secret key file ") + secring_path_tmp + " into " + _secring_path +". Disk error?" ; - return false ; - } - - // 6 - copy the public key to the public keyring on disk - - cinfo = NULL ; - std::string pubring_path_tmp = _pubring_path + ".tmp" ; - - if(RsDirUtil::fileExists(_pubring_path) && !RsDirUtil::copyFile(_pubring_path,pubring_path_tmp)) - { - errString= std::string("Cannot encode secret key to disk!! Disk full? Out of disk quota?") ; - return false ; - } - fd=ops_setup_file_append(&cinfo, pubring_path_tmp.c_str()); - - if(!ops_write_transferable_public_key(key, ops_false, cinfo)) - { - errString=std::string("Cannot encode secret key to memory!!") ; - return false ; - } - ops_teardown_file_write(cinfo,fd) ; - - if(!RsDirUtil::renameFile(pubring_path_tmp,_pubring_path)) - { - errString= std::string("Cannot rename tmp public key file ") + pubring_path_tmp + " into " + _pubring_path +". Disk error?" ; - return false ; - } - // 7 - clean - ops_keydata_free(key) ; - - // 8 - re-read the key from the public keyring, and add it to memory. - - _pubring_last_update_time = 0 ; // force update pubring from disk. - locked_syncPublicKeyring() ; - -#ifdef DEBUG_PGPHANDLER - std::cerr << "Added new public key with id " << pgpId.toStdString() << " to public keyring." << std::endl; -#endif - - // 9 - Update some flags. - - privateTrustCertificate(pgpId,PGPCertificateInfo::PGP_CERTIFICATE_TRUST_ULTIMATE) ; - - return true ; -} - -std::string PGPHandler::makeRadixEncodedPGPKey(const ops_keydata_t *key,bool include_signatures) -{ - ops_create_info_t* cinfo; - ops_memory_t *buf = NULL ; - ops_setup_memory_write(&cinfo, &buf, 0); - ops_boolean_t armoured = ops_true ; - - if(key->type == OPS_PTAG_CT_PUBLIC_KEY) - { - if(ops_write_transferable_public_key_from_packet_data(key,armoured,cinfo) != ops_true) - return "ERROR: This key cannot be processed by RetroShare because\nDSA certificates are not yet handled." ; - } - else if(key->type == OPS_PTAG_CT_ENCRYPTED_SECRET_KEY) - { - if(ops_write_transferable_secret_key_from_packet_data(key,armoured,cinfo) != ops_true) - return "ERROR: This key cannot be processed by RetroShare because\nDSA certificates are not yet handled." ; - } - else - { - ops_create_info_delete(cinfo); - std::cerr << "Unhandled key type " << key->type << std::endl; - return "ERROR: Cannot write key. Unhandled key type. " ; - } - - ops_writer_close(cinfo) ; - - std::string res((char *)ops_memory_get_data(buf),ops_memory_get_length(buf)) ; - ops_teardown_memory_write(cinfo,buf); - - if(!include_signatures) - { - std::string tmp ; - if(PGPKeyManagement::createMinimalKey(res,tmp) ) - res = tmp ; - } - - return res ; -} - -const ops_keydata_t *PGPHandler::locked_getSecretKey(const RsPgpId& id) const -{ - std::map::const_iterator res = _secret_keyring_map.find(id) ; - - if(res == _secret_keyring_map.end()) - return NULL ; - else - return ops_keyring_get_key_by_index(_secring,res->second._key_index) ; -} -const ops_keydata_t *PGPHandler::locked_getPublicKey(const RsPgpId& id,bool stamp_the_key) const -{ - std::map::const_iterator res = _public_keyring_map.find(id) ; - - if(res == _public_keyring_map.end()) - return NULL ; - else - { - if(stamp_the_key) // Should we stamp the key as used? - { - static rstime_t last_update_db_because_of_stamp = 0 ; - rstime_t now = time(NULL) ; - - res->second._time_stamp = now ; - - if(now > last_update_db_because_of_stamp + 3600) // only update database once every hour. No need to do it more often. - { - _trustdb_changed = true ; - last_update_db_because_of_stamp = now ; - } - } - return ops_keyring_get_key_by_index(_pubring,res->second._key_index) ; - } -} - -std::string PGPHandler::SaveCertificateToString(const RsPgpId& id,bool include_signatures) const -{ - RsStackMutex mtx(pgphandlerMtx) ; // lock access to PGP memory structures. - const ops_keydata_t *key = locked_getPublicKey(id,false) ; - - if(key == NULL) - { - std::cerr << "Cannot output key " << id.toStdString() << ": not found in keyring." << std::endl; - return "" ; - } - - return makeRadixEncodedPGPKey(key,include_signatures) ; -} - -bool PGPHandler::exportPublicKey( - const RsPgpId& id, - unsigned char*& mem_block, size_t& mem_size, - bool armoured, bool include_signatures ) const -{ - mem_block = nullptr; mem_size = 0; // clear just in case - - if(armoured) - { - RsErr() << __PRETTY_FUNCTION__ << " should not be used with " - << "armoured=true, because there's a bug in the armoured export" - << " of OPS" << std::endl; - print_stacktrace(); - return false; - } - - RS_STACK_MUTEX(pgphandlerMtx); - const ops_keydata_t* key = locked_getPublicKey(id,false); - - if(!key) - { - RsErr() << __PRETTY_FUNCTION__ << " key id: " << id - << " not found in keyring." << std::endl; - return false; - } - - ops_create_info_t* cinfo; - ops_memory_t *buf = nullptr; - ops_setup_memory_write(&cinfo, &buf, 0); - - if(ops_write_transferable_public_key_from_packet_data( - key, armoured, cinfo ) != ops_true) - { - RsErr() << __PRETTY_FUNCTION__ << " This key id " << id - << " cannot be processed by RetroShare because DSA certificates" - << " support is not implemented yet." << std::endl; - return false; - } - - ops_writer_close(cinfo); - - mem_size = ops_memory_get_length(buf); - mem_block = reinterpret_cast(malloc(mem_size)); - memcpy(mem_block,ops_memory_get_data(buf),mem_size); - - ops_teardown_memory_write(cinfo,buf); - - if(!include_signatures) - { - size_t new_size; - PGPKeyManagement::findLengthOfMinimalKey(mem_block, mem_size, new_size); - mem_size = new_size; - } - - return true; -} - -bool PGPHandler::exportGPGKeyPair(const std::string& filename,const RsPgpId& exported_key_id) const -{ - RsStackMutex mtx(pgphandlerMtx) ; // lock access to PGP memory structures. - - const ops_keydata_t *pubkey = locked_getPublicKey(exported_key_id,false) ; - - if(pubkey == NULL) - { - std::cerr << "Cannot output key " << exported_key_id.toStdString() << ": not found in public keyring." << std::endl; - return false ; - } - const ops_keydata_t *seckey = locked_getSecretKey(exported_key_id) ; - - if(seckey == NULL) - { - std::cerr << "Cannot output key " << exported_key_id.toStdString() << ": not found in secret keyring." << std::endl; - return false ; - } - - FILE *f = RsDirUtil::rs_fopen(filename.c_str(),"w") ; - if(f == NULL) - { - std::cerr << "Cannot output key " << exported_key_id.toStdString() << ": file " << filename << " cannot be written. Please check for permissions, quotas, disk space." << std::endl; - return false ; - } - - fprintf(f,"%s\n", makeRadixEncodedPGPKey(pubkey,true).c_str()) ; - fprintf(f,"%s\n", makeRadixEncodedPGPKey(seckey,true).c_str()) ; - - fclose(f) ; - return true ; -} - -bool PGPHandler::exportGPGKeyPairToString( - std::string& data, const RsPgpId& exportedKeyId, - bool includeSignatures, std::string& errorMsg ) const -{ - RS_STACK_MUTEX(pgphandlerMtx); - - const ops_keydata_t *pubkey = locked_getPublicKey(exportedKeyId,false); - - if(!pubkey) - { - errorMsg = "Cannot output key " + exportedKeyId.toStdString() + - ": not found in public keyring."; - return false; - } - const ops_keydata_t *seckey = locked_getSecretKey(exportedKeyId); - - if(!seckey) - { - errorMsg = "Cannot output key " + exportedKeyId.toStdString() + - ": not found in secret keyring."; - return false; - } - - data = makeRadixEncodedPGPKey(pubkey, includeSignatures); - data += "\n"; - data += makeRadixEncodedPGPKey(seckey, includeSignatures); - data += "\n"; - return true; -} - -bool PGPHandler::getGPGDetailsFromBinaryBlock(const unsigned char *mem_block,size_t mem_size,RsPgpId& key_id, std::string& name, std::list& signers) const -{ - ops_keyring_t *tmp_keyring = allocateOPSKeyring(); - ops_memory_t *mem = ops_memory_new() ; - ops_memory_add(mem,mem_block,mem_size); - - if(!ops_keyring_read_from_mem(tmp_keyring,ops_false,mem)) - { - ops_keyring_free(tmp_keyring) ; - free(tmp_keyring) ; - ops_memory_release(mem) ; - free(mem) ; - - std::cerr << "Could not read key. Format error?" << std::endl; - //error_string = std::string("Could not read key. Format error?") ; - return false ; - } - ops_memory_release(mem) ; - free(mem) ; - //error_string.clear() ; - - if(tmp_keyring->nkeys != 1) - { - std::cerr << "No or incomplete/invalid key in supplied pgp block." << std::endl; - return false ; - } - if(tmp_keyring->keys[0].uids == NULL) - { - std::cerr << "No uid in supplied key." << std::endl; - return false ; - } - - key_id = RsPgpId(tmp_keyring->keys[0].key_id) ; - name = std::string((char *)tmp_keyring->keys[0].uids[0].user_id) ; - - // now parse signatures. - // - ops_validate_result_t* result=(ops_validate_result_t*)ops_mallocz(sizeof *result); - ops_boolean_t res ; - - { - RsStackMutex mtx(pgphandlerMtx) ; // lock access to PGP memory structures. - res = ops_validate_key_signatures(result,&tmp_keyring->keys[0],_pubring,cb_get_passphrase) ; - } - - if(res == ops_false) - std::cerr << "(WW) Error in PGPHandler::validateAndUpdateSignatures(). Validation failed for at least some signatures." << std::endl; - - // also add self-signature if any (there should be!). - // - res = ops_validate_key_signatures(result,&tmp_keyring->keys[0],tmp_keyring,cb_get_passphrase) ; - - if(res == ops_false) - std::cerr << "(WW) Error in PGPHandler::validateAndUpdateSignatures(). Validation failed for at least some signatures." << std::endl; - - // Parse signers. - // - - std::set signers_set ; // Use a set to remove duplicates. - - if(result != NULL) - for(size_t i=0;ivalid_count;++i) - signers_set.insert(RsPgpId(result->valid_sigs[i].signer_id)) ; - - ops_validate_result_free(result) ; - - ops_keyring_free(tmp_keyring) ; - free(tmp_keyring) ; - - // write to the output variable - - signers.clear() ; - - for(std::set::const_iterator it(signers_set.begin());it!=signers_set.end();++it) - signers.push_back(*it) ; - - return true ; -} - -bool PGPHandler::importGPGKeyPair(const std::string& filename,RsPgpId& imported_key_id,std::string& import_error) -{ - import_error = "" ; - - // 1 - Test for file existance - // - FILE *ftest = RsDirUtil::rs_fopen(filename.c_str(),"r") ; - - if(ftest == NULL) - { - import_error = "Cannot open file " + filename + " for read. Please check access permissions." ; - return false ; - } - - fclose(ftest) ; - - // 2 - Read keyring from supplied file. - // - ops_keyring_t *tmp_keyring = allocateOPSKeyring(); - - if(ops_false == ops_keyring_read_from_file(tmp_keyring, ops_true, filename.c_str())) - { - import_error = "PGPHandler::readKeyRing(): cannot read key file. File corrupted?" ; - free(tmp_keyring); - return false ; - } - - return checkAndImportKeyPair(tmp_keyring, imported_key_id, import_error); -} - -bool PGPHandler::importGPGKeyPairFromString(const std::string &data, RsPgpId &imported_key_id, std::string &import_error) -{ - import_error = "" ; - - ops_memory_t* mem = ops_memory_new(); - ops_memory_add(mem, (unsigned char*)data.data(), data.length()); - - ops_keyring_t *tmp_keyring = allocateOPSKeyring(); - - if(ops_false == ops_keyring_read_from_mem(tmp_keyring, ops_true, mem)) - { - import_error = "PGPHandler::importGPGKeyPairFromString(): cannot parse key data" ; - free(tmp_keyring); - return false ; - } - return checkAndImportKeyPair(tmp_keyring, imported_key_id, import_error); -} - -bool PGPHandler::checkAndImportKeyPair(ops_keyring_t *tmp_keyring, RsPgpId &imported_key_id, std::string &import_error) -{ - if(tmp_keyring == 0) - { - import_error = "PGPHandler::checkAndImportKey(): keyring is null" ; - return false; - } - - if(tmp_keyring->nkeys != 2) - { - import_error = "PGPHandler::importKeyPair(): file does not contain a valid keypair." ; - if(tmp_keyring->nkeys > 2) - import_error += "\nMake sure that your key is a RSA key (DSA is not yet supported) and does not contain subkeys (not supported yet)."; - return false ; - } - - // 3 - Test that keyring contains a valid keypair. - // - const ops_keydata_t *pubkey = NULL ; - const ops_keydata_t *seckey = NULL ; - - if(tmp_keyring->keys[0].type == OPS_PTAG_CT_PUBLIC_KEY) - pubkey = &tmp_keyring->keys[0] ; - else if(tmp_keyring->keys[0].type == OPS_PTAG_CT_ENCRYPTED_SECRET_KEY) - seckey = &tmp_keyring->keys[0] ; - else - { - import_error = "Unrecognised key type in key file for key #0. Giving up." ; - std::cerr << "Unrecognised key type " << tmp_keyring->keys[0].type << " in key file for key #0. Giving up." << std::endl; - return false ; - } - if(tmp_keyring->keys[1].type == OPS_PTAG_CT_PUBLIC_KEY) - pubkey = &tmp_keyring->keys[1] ; - else if(tmp_keyring->keys[1].type == OPS_PTAG_CT_ENCRYPTED_SECRET_KEY) - seckey = &tmp_keyring->keys[1] ; - else - { - import_error = "Unrecognised key type in key file for key #1. Giving up." ; - std::cerr << "Unrecognised key type " << tmp_keyring->keys[1].type << " in key file for key #1. Giving up." << std::endl; - return false ; - } - - if(pubkey == nullptr || seckey == nullptr || pubkey == seckey) - { - import_error = "File does not contain a public and a private key. Sorry." ; - return false ; - } - if(memcmp( pubkey->fingerprint.fingerprint, - seckey->fingerprint.fingerprint, - RsPgpFingerprint::SIZE_IN_BYTES ) != 0) - { - import_error = "Public and private keys do nt have the same fingerprint. Sorry!" ; - return false ; - } - if(pubkey->key.pkey.version != 4) - { - import_error = "Public key is not version 4. Rejected!" ; - return false ; - } - - // 4 - now check self-signature for this keypair. For this we build a dummy keyring containing only the key. - // - ops_validate_result_t *result=(ops_validate_result_t*)ops_mallocz(sizeof *result); - - ops_keyring_t dummy_keyring ; - dummy_keyring.nkeys=1 ; - dummy_keyring.nkeys_allocated=1 ; - dummy_keyring.keys=const_cast(pubkey) ; - - ops_validate_key_signatures(result, const_cast(pubkey), &dummy_keyring, cb_get_passphrase) ; - - // Check that signatures contain at least one certification from the user id. - // - bool found = false ; - - for(uint32_t i=0;ivalid_count;++i) - if(!memcmp( - static_cast(result->valid_sigs[i].signer_id), - pubkey->key_id, - RsPgpId::SIZE_IN_BYTES )) - { - found = true ; - break ; - } - - if(!found) - { - import_error = "Cannot validate self signature for the imported key. Sorry." ; - return false ; - } - ops_validate_result_free(result); - - if(!RsDiscSpace::checkForDiscSpace(RS_PGP_DIRECTORY)) - { - import_error = std::string("(EE) low disc space in pgp directory. Can't write safely to keyring.") ; - return false ; - } - // 5 - All test passed. Adding key to keyring. - // - { - RsStackMutex mtx(pgphandlerMtx) ; // lock access to PGP memory structures. - - imported_key_id = RsPgpId(pubkey->key_id) ; - - if(locked_getSecretKey(imported_key_id) == NULL) - { - RsStackFileLock flck(_pgp_lock_filename) ; // lock access to PGP directory. - - ops_create_info_t *cinfo = NULL ; - - // Make a copy of the secret keyring - // - std::string secring_path_tmp = _secring_path + ".tmp" ; - if(RsDirUtil::fileExists(_secring_path) && !RsDirUtil::copyFile(_secring_path,secring_path_tmp)) - { - import_error = "(EE) Cannot write secret key to disk!! Disk full? Out of disk quota. Keyring will be left untouched." ; - return false ; - } - - // Append the new key - - int fd=ops_setup_file_append(&cinfo, secring_path_tmp.c_str()); - - if(!ops_write_transferable_secret_key_from_packet_data(seckey,ops_false,cinfo)) - { - import_error = "(EE) Cannot encode secret key to disk!! Disk full? Out of disk quota?" ; - return false ; - } - ops_teardown_file_write(cinfo,fd) ; - - // Rename the new keyring to overwrite the old one. - // - if(!RsDirUtil::renameFile(secring_path_tmp,_secring_path)) - { - import_error = " (EE) Cannot move temp file " + secring_path_tmp + ". Bad write permissions?" ; - return false ; - } - - addNewKeyToOPSKeyring(_secring,*seckey) ; - initCertificateInfo(_secret_keyring_map[ imported_key_id ],seckey,_secring->nkeys-1) ; - } - else - import_error = "Private key already exists! Not importing it again." ; - - if(locked_addOrMergeKey(_pubring,_public_keyring_map,pubkey)) - _pubring_changed = true ; - } - - // 6 - clean - // - ops_keyring_free(tmp_keyring) ; - free(tmp_keyring); - - // write public key to disk - syncDatabase(); - - return true ; -} - -void PGPHandler::addNewKeyToOPSKeyring(ops_keyring_t *kr,const ops_keydata_t& key) -{ - if(kr->nkeys >= kr->nkeys_allocated) - { - kr->keys = (ops_keydata_t *)realloc(kr->keys,(kr->nkeys+1)*sizeof(ops_keydata_t)) ; - kr->nkeys_allocated = kr->nkeys+1; - } - memset(&kr->keys[kr->nkeys],0,sizeof(ops_keydata_t)) ; - ops_keydata_copy(&kr->keys[kr->nkeys],&key) ; - kr->nkeys++ ; -} - -bool PGPHandler::LoadCertificateFromBinaryData(const unsigned char *data,uint32_t data_len,RsPgpId& id,std::string& error_string) -{ - return LoadCertificate(data,data_len,ops_false,id,error_string); -} - -bool PGPHandler::LoadCertificateFromString(const std::string& pgp_cert,RsPgpId& id,std::string& error_string) -{ - return LoadCertificate((unsigned char*)(pgp_cert.c_str()),pgp_cert.length(),ops_true,id,error_string); -} - -bool PGPHandler::LoadCertificate(const unsigned char *data,uint32_t data_len,bool armoured,RsPgpId& id,std::string& error_string) -{ - RsStackMutex mtx(pgphandlerMtx) ; // lock access to PGP memory structures. -#ifdef DEBUG_PGPHANDLER - std::cerr << "Reading new key from string: " << std::endl; -#endif - - ops_keyring_t *tmp_keyring = allocateOPSKeyring(); - ops_memory_t *mem = ops_memory_new() ; - ops_memory_add(mem,data,data_len) ; - - if(!ops_keyring_read_from_mem(tmp_keyring,armoured,mem)) - { - ops_keyring_free(tmp_keyring) ; - free(tmp_keyring) ; - ops_memory_release(mem) ; - free(mem) ; - - std::cerr << "Could not read key. Format error?" << std::endl; - error_string = std::string("Could not read key. Format error?") ; - return false ; - } - ops_memory_release(mem) ; - free(mem) ; - error_string.clear() ; - - // Check that there is exactly one key in this data packet. - // - if(tmp_keyring->nkeys != 1) - { - std::cerr << "Loaded certificate contains more than one PGP key. This is not allowed." << std::endl; - error_string = "Loaded certificate contains more than one PGP key. This is not allowed." ; - return false ; - } - - const ops_keydata_t *keydata = ops_keyring_get_key_by_index(tmp_keyring,0); - - // Check that the key is a version 4 key - // - if(keydata->key.pkey.version != 4) - { - error_string = "Public key is not version 4. Rejected!" ; - std::cerr << "Received a key with unhandled version number (" << keydata->key.pkey.version << ")" << std::endl; - return false ; - } - - // Check that the key is correctly self-signed. - // - ops_validate_result_t* result=(ops_validate_result_t*)ops_mallocz(sizeof *result); - - ops_validate_key_signatures(result,keydata,tmp_keyring,cb_get_passphrase) ; - - bool found = false ; - - for(uint32_t i=0;ivalid_count;++i) - if(!memcmp( - static_cast(result->valid_sigs[i].signer_id), - keydata->key_id, - RsPgpId::SIZE_IN_BYTES )) - { - found = true ; - break ; - } - - if(!found) - { - error_string = "This key is not self-signed. This is required by Retroshare." ; - std::cerr << "This key is not self-signed. This is required by Retroshare." << std::endl; - ops_validate_result_free(result); - return false ; - } - ops_validate_result_free(result); - -#ifdef DEBUG_PGPHANDLER - std::cerr << " Key read correctly: " << std::endl; - ops_keyring_list(tmp_keyring) ; -#endif - - int i=0 ; - - while( (keydata = ops_keyring_get_key_by_index(tmp_keyring,i++)) != NULL ) - if(locked_addOrMergeKey(_pubring,_public_keyring_map,keydata)) - { - _pubring_changed = true ; -#ifdef DEBUG_PGPHANDLER - std::cerr << " Added the key in the main public keyring." << std::endl; -#endif - } - else - std::cerr << "Key already in public keyring." << std::endl; - - if(tmp_keyring->nkeys > 0) - id = RsPgpId(tmp_keyring->keys[0].key_id) ; - else - return false ; - - ops_keyring_free(tmp_keyring) ; - free(tmp_keyring) ; - - _pubring_changed = true ; - - return true ; -} - -bool PGPHandler::locked_addOrMergeKey(ops_keyring_t *keyring,std::map& kmap,const ops_keydata_t *keydata) -{ - bool ret = false ; - RsPgpId id(keydata->key_id) ; - -#ifdef DEBUG_PGPHANDLER - std::cerr << "AddOrMergeKey():" << std::endl; - std::cerr << " id: " << id.toStdString() << std::endl; -#endif - - // See if the key is already in the keyring - const ops_keydata_t *existing_key = NULL; - std::map::const_iterator res = kmap.find(id) ; - - // Checks that - // - the key is referenced by keyid - // - the map is initialized - // - the fingerprint matches! - // - if(res == kmap.end() || (existing_key = ops_keyring_get_key_by_index(keyring,res->second._key_index)) == NULL) - { -#ifdef DEBUG_PGPHANDLER - std::cerr << " Key is new. Adding it to keyring" << std::endl; -#endif - addNewKeyToOPSKeyring(keyring,*keydata) ; // the key is new. - initCertificateInfo(kmap[id],keydata,keyring->nkeys-1) ; - existing_key = &(keyring->keys[keyring->nkeys-1]) ; - ret = true ; - } - else - { - if(memcmp( existing_key->fingerprint.fingerprint, - keydata->fingerprint.fingerprint, - RsPgpFingerprint::SIZE_IN_BYTES )) - { - std::cerr << "(EE) attempt to merge key with identical id, but different fingerprint!" << std::endl; - return false ; - } - -#ifdef DEBUG_PGPHANDLER - std::cerr << " Key exists. Merging signatures." << std::endl; -#endif - ret = mergeKeySignatures(const_cast(existing_key),keydata) ; - - if(ret) - initCertificateInfo(kmap[id],existing_key,res->second._key_index) ; - } - - if(ret) - { - validateAndUpdateSignatures(kmap[id],existing_key) ; - kmap[id]._time_stamp = time(NULL) ; - } - - return ret ; -} - -bool PGPHandler::encryptTextToFile(const RsPgpId& key_id,const std::string& text,const std::string& outfile) -{ - RsStackMutex mtx(pgphandlerMtx) ; // lock access to PGP memory structures. - - const ops_keydata_t *public_key = locked_getPublicKey(key_id,true) ; - - if(public_key == NULL) - { - std::cerr << "Cannot get public key of id " << key_id.toStdString() << std::endl; - return false ; - } - - if(public_key->type != OPS_PTAG_CT_PUBLIC_KEY) - { - std::cerr << "PGPHandler::encryptTextToFile(): ERROR: supplied id did not return a public key!" << std::endl; - return false ; - } - - std::string outfile_tmp = outfile + ".tmp" ; - - ops_create_info_t *info; - int fd = ops_setup_file_write(&info, outfile_tmp.c_str(), ops_true); - - if (fd < 0) - { - std::cerr << "PGPHandler::encryptTextToFile(): ERROR: Cannot write to " << outfile_tmp << std::endl; - return false ; - } - - if(!ops_encrypt_stream(info, public_key, NULL, ops_false, ops_true)) - { - std::cerr << "PGPHandler::encryptTextToFile(): ERROR: encryption failed." << std::endl; - return false ; - } - - ops_write(text.c_str(), text.length(), info); - ops_teardown_file_write(info, fd); - - if(!RsDirUtil::renameFile(outfile_tmp,outfile)) - { - std::cerr << "PGPHandler::encryptTextToFile(): ERROR: Cannot rename " + outfile_tmp + " to " + outfile + ". Disk error?" << std::endl; - return false ; - } - - return true ; -} - -bool PGPHandler::encryptDataBin(const RsPgpId& key_id,const void *data, const uint32_t len, unsigned char *encrypted_data, unsigned int *encrypted_data_len) -{ - RsStackMutex mtx(pgphandlerMtx) ; // lock access to PGP memory structures. - - const ops_keydata_t *public_key = locked_getPublicKey(key_id,true) ; - - if(public_key == NULL) - { - std::cerr << "Cannot get public key of id " << key_id.toStdString() << std::endl; - return false ; - } - - if(public_key->type != OPS_PTAG_CT_PUBLIC_KEY) - { - std::cerr << "PGPHandler::encryptTextToFile(): ERROR: supplied id did not return a public key!" << std::endl; - return false ; - } - if(public_key->key.pkey.algorithm != OPS_PKA_RSA) - { - std::cerr << "PGPHandler::encryptTextToFile(): ERROR: supplied key id " << key_id.toStdString() << " is not an RSA key (DSA for instance, is not supported)!" << std::endl; - return false ; - } - ops_create_info_t *info; - ops_memory_t *buf = NULL ; - ops_setup_memory_write(&info, &buf, 0); - bool res = true; - - if(!ops_encrypt_stream(info, public_key, NULL, ops_false, ops_false)) - { - std::cerr << "Encryption failed." << std::endl; - res = false ; - } - - ops_write(data,len,info); - ops_writer_close(info); - ops_create_info_delete(info); - - int tlen = ops_memory_get_length(buf) ; - - if( (int)*encrypted_data_len >= tlen) - { - if(res) - { - memcpy(encrypted_data,ops_memory_get_data(buf),tlen) ; - *encrypted_data_len = tlen ; - res = true ; - } - } - else - { - std::cerr << "Not enough room to fit encrypted data. Size given=" << *encrypted_data_len << ", required=" << tlen << std::endl; - res = false ; - } - - ops_memory_release(buf) ; - free(buf) ; - - return res ; -} - -bool PGPHandler::decryptDataBin(const RsPgpId& /*key_id*/,const void *encrypted_data, const uint32_t encrypted_len, unsigned char *data, unsigned int *data_len) -{ - int out_length ; - unsigned char *out ; - ops_boolean_t res = ops_decrypt_memory((const unsigned char *)encrypted_data,encrypted_len,&out,&out_length,_secring,ops_false,cb_get_passphrase) ; - - if(*data_len < (unsigned int)out_length) - { - std::cerr << "Not enough room to store decrypted data! Please give more."<< std::endl; - return false ; - } - - *data_len = (unsigned int)out_length ; - memcpy(data,out,out_length) ; - free(out) ; - - return (bool)res ; -} - -bool PGPHandler::decryptTextFromFile(const RsPgpId&,std::string& text,const std::string& inputfile) -{ - RsStackMutex mtx(pgphandlerMtx) ; // lock access to PGP memory structures. - - unsigned char *out_buf = NULL ; - std::string buf ; - - FILE *f = RsDirUtil::rs_fopen(inputfile.c_str(),"rb") ; - - if (f == NULL) - { - std::cerr << "Cannot open file " << inputfile << " for read." << std::endl; - return false; - } - - int c ; - while( (c = fgetc(f))!= EOF) - buf += (unsigned char)c; - - fclose(f) ; - -#ifdef DEBUG_PGPHANDLER - std::cerr << "PGPHandler::decryptTextFromFile: read a file of length " << std::dec << buf.length() << std::endl; - std::cerr << "buf=\"" << buf << "\"" << std::endl; -#endif - - int out_length ; - ops_boolean_t res = ops_decrypt_memory((const unsigned char *)buf.c_str(),buf.length(),&out_buf,&out_length,_secring,ops_true,cb_get_passphrase) ; - - text = std::string((char *)out_buf,out_length) ; - free (out_buf); - return (bool)res ; -} - -bool PGPHandler::SignDataBin(const RsPgpId& id,const void *data, const uint32_t len, unsigned char *sign, unsigned int *signlen,bool use_raw_signature, std::string reason /* = "" */) -{ - RsStackMutex mtx(pgphandlerMtx) ; // lock access to PGP memory structures. - // need to find the key and to decrypt it. - - const ops_keydata_t *key = locked_getSecretKey(id) ; - - if(!key) - { - std::cerr << "Cannot sign: no secret key with id " << id.toStdString() << std::endl; - return false ; - } - - std::string uid_hint ; - if(key->nuids > 0) - uid_hint = std::string((const char *)key->uids[0].user_id) ; - uid_hint += "(" + RsPgpId(key->key_id).toStdString()+")" ; - -#ifdef DEBUG_PGPHANDLER - ops_fingerprint_t f ; - ops_fingerprint(&f,&key->key.pkey) ; - - PGPFingerprintType fp(f.fingerprint) ; -#endif - - bool last_passwd_was_wrong = false ; -ops_secret_key_t *secret_key = NULL ; - - for(int i=0;i<3;++i) - { - bool cancelled =false; - std::string passphrase = _passphrase_callback(NULL,reason.c_str(),uid_hint.c_str(),"Please enter passwd for encrypting your key : ",last_passwd_was_wrong,&cancelled) ;//TODO reason - - secret_key = ops_decrypt_secret_key_from_data(key,passphrase.c_str()) ; - - if(cancelled) - { - std::cerr << "Key entering cancelled" << std::endl; - return false ; - } - if(secret_key) - break ; - - std::cerr << "Key decryption went wrong. Wrong passwd?" << std::endl; - last_passwd_was_wrong = true ; - } - if(!secret_key) - { - std::cerr << "Could not obtain secret key. Signature cancelled." << std::endl; - return false ; - } - - // then do the signature. - - ops_boolean_t not_raw = !use_raw_signature ; -#ifdef V07_NON_BACKWARD_COMPATIBLE_CHANGE_002 - ops_memory_t *memres = ops_sign_buf(data,len,OPS_SIG_BINARY,OPS_HASH_SHA256,secret_key,ops_false,ops_false,not_raw,not_raw) ; -#else - ops_memory_t *memres = ops_sign_buf(data,len,OPS_SIG_BINARY,OPS_HASH_SHA1,secret_key,ops_false,ops_false,not_raw,not_raw) ; -#endif - - if(!memres) - return false ; - - bool res ; - uint32_t slen = (uint32_t)ops_memory_get_length(memres); - - if(*signlen >= slen) - { - *signlen = slen ; - - memcpy(sign,ops_memory_get_data(memres),*signlen) ; - res = true ; - } - else - { - std::cerr << "(EE) memory chunk is not large enough for signature packet. Requred size: " << slen << " bytes." << std::endl; - res = false ; - } - - ops_memory_release(memres) ; - free(memres) ; - ops_secret_key_free(secret_key) ; - free(secret_key) ; - -#ifdef DEBUG_PGPHANDLER - std::cerr << "Signed with fingerprint " << fp.toStdString() << ", length " << std::dec << *signlen << ", literal data length = " << len << std::endl; - std::cerr << "Signature body: " << std::endl; - hexdump( (unsigned char *)data, len) ; - std::cerr << std::endl; - std::cerr << "Data: " << std::endl; - hexdump( (unsigned char *)sign,*signlen) ; - std::cerr << std::endl; -#endif - return res ; -} - -bool PGPHandler::privateSignCertificate(const RsPgpId& ownId,const RsPgpId& id_of_key_to_sign) -{ - RsStackMutex mtx(pgphandlerMtx) ; // lock access to PGP memory structures. - - ops_keydata_t *key_to_sign = const_cast(locked_getPublicKey(id_of_key_to_sign,true)) ; - - if(key_to_sign == NULL) - { - std::cerr << "Cannot sign: no public key with id " << id_of_key_to_sign.toStdString() << std::endl; - return false ; - } - - // 1 - get decrypted secret key - // - const ops_keydata_t *skey = locked_getSecretKey(ownId) ; - - if(!skey) - { - std::cerr << "Cannot sign: no secret key with id " << ownId.toStdString() << std::endl; - return false ; - } - const ops_keydata_t *pkey = locked_getPublicKey(ownId,true) ; - - if(!pkey) - { - std::cerr << "Cannot sign: no public key with id " << ownId.toStdString() << std::endl; - return false ; - } - - bool cancelled = false; - std::string passphrase = _passphrase_callback(NULL,"",RsPgpId(skey->key_id).toStdString().c_str(),"Please enter passwd for encrypting your key : ",false,&cancelled) ; - - ops_secret_key_t *secret_key = ops_decrypt_secret_key_from_data(skey,passphrase.c_str()) ; - - if(cancelled) - { - std::cerr << "Key cancelled by used." << std::endl; - return false ; - } - if(!secret_key) - { - std::cerr << "Key decryption went wrong. Wrong passwd?" << std::endl; - return false ; - } - - // 2 - then do the signature. - - if(!ops_sign_key(key_to_sign,pkey->key_id,secret_key)) - { - std::cerr << "Key signature went wrong. Wrong passwd?" << std::endl; - return false ; - } - - // 3 - free memory - // - ops_secret_key_free(secret_key) ; - free(secret_key) ; - - _pubring_changed = true ; - - // 4 - update signatures. - // - PGPCertificateInfo& cert(_public_keyring_map[ id_of_key_to_sign ]) ; - validateAndUpdateSignatures(cert,key_to_sign) ; - cert._flags |= PGPCertificateInfo::PGP_CERTIFICATE_FLAG_HAS_OWN_SIGNATURE ; - - return true ; -} - void PGPHandler::updateOwnSignatureFlag(const RsPgpId& own_id) { RsStackMutex mtx(pgphandlerMtx) ; // lock access to PGP memory structures. @@ -1599,59 +165,6 @@ void PGPHandler::locked_updateOwnSignatureFlag(PGPCertificateInfo& cert,const Rs RsPgpFingerprint::SIZE_IN_BYTES - RsPgpId::SIZE_IN_BYTES ); } -bool PGPHandler::getKeyFingerprint(const RsPgpId& id, RsPgpFingerprint& fp) const -{ - RS_STACK_MUTEX(pgphandlerMtx); - - const ops_keydata_t *key = locked_getPublicKey(id,false) ; - - if(!key) return false; - - ops_fingerprint_t f ; - ops_fingerprint(&f,&key->key.pkey) ; - - fp = RsPgpFingerprint::fromBufferUnsafe(f.fingerprint); - - return true ; -} - -bool PGPHandler::VerifySignBin(const void *literal_data, uint32_t literal_data_length, unsigned char *sign, unsigned int sign_len, const PGPFingerprintType& key_fingerprint) -{ - RsStackMutex mtx(pgphandlerMtx) ; // lock access to PGP memory structures. - - RsPgpId id = RsPgpId(key_fingerprint.toByteArray() + PGPFingerprintType::SIZE_IN_BYTES - RsPgpId::SIZE_IN_BYTES) ; - const ops_keydata_t *key = locked_getPublicKey(id,true) ; - - if(key == NULL) - { - std::cerr << "No key returned by fingerprint " << key_fingerprint.toStdString() << ", and ID " << id.toStdString() << ", signature verification failed!" << std::endl; - return false ; - } - - // Check that fingerprint is the same. - const ops_public_key_t *pkey = &key->key.pkey ; - ops_fingerprint_t fp ; - ops_fingerprint(&fp,pkey) ; - - if(key_fingerprint != PGPFingerprintType(fp.fingerprint)) - { - std::cerr << "Key fingerprint does not match " << key_fingerprint.toStdString() << ", for ID " << id.toStdString() << ", signature verification failed!" << std::endl; - return false ; - } - -#ifdef DEBUG_PGPHANDLER - std::cerr << "Verifying signature from fingerprint " << key_fingerprint.toStdString() << ", length " << std::dec << sign_len << ", literal data length = " << literal_data_length << std::endl; - std::cerr << "Signature body: " << std::endl; - hexdump( (unsigned char *)sign,sign_len) ; - std::cerr << std::endl; - std::cerr << "Signed data: " << std::endl; - hexdump( (unsigned char *)literal_data, literal_data_length) ; - std::cerr << std::endl; -#endif - - return ops_validate_detached_signature(literal_data,literal_data_length,sign,sign_len,key) ; -} - void PGPHandler::setAcceptConnexion(const RsPgpId& id,bool b) { RsStackMutex mtx(pgphandlerMtx) ; // lock access to PGP memory structures. @@ -1699,65 +212,6 @@ bool PGPHandler::isGPGAccepted(const RsPgpId &id) return (res != _public_keyring_map.end()) && (res->second._flags & PGPCertificateInfo::PGP_CERTIFICATE_FLAG_ACCEPT_CONNEXION) ; } -// Lexicographic order on signature packets -// -bool operator<(const ops_packet_t& p1,const ops_packet_t& p2) -{ - if(p1.length < p2.length) - return true ; - if(p1.length > p2.length) - return false ; - - for(uint32_t i=0;i p2.raw[i]) - return false ; - } - return false ; -} - -bool PGPHandler::mergeKeySignatures(ops_keydata_t *dst,const ops_keydata_t *src) -{ - // First sort all signatures into lists to see which is new, which is not new - -#ifdef DEBUG_PGPHANDLER - std::cerr << "Merging signatures for key " << RsPgpId(dst->key_id).toStdString() << std::endl; -#endif - std::set dst_packets ; - - for(uint32_t i=0;inpackets;++i) dst_packets.insert(dst->packets[i]) ; - - std::set to_add ; - - for(uint32_t i=0;inpackets;++i) - if(dst_packets.find(src->packets[i]) == dst_packets.end()) - { - uint8_t tag ; - uint32_t length ; - unsigned char *tmp_data = src->packets[i].raw ; // put it in a tmp variable because read_packetHeader() will modify it!! - - PGPKeyParser::read_packetHeader(tmp_data,tag,length) ; - - if(tag == PGPKeyParser::PGP_PACKET_TAG_SIGNATURE) - to_add.insert(src->packets[i]) ; -#ifdef DEBUG_PGPHANDLER - else - std::cerr << " Packet with tag 0x" << std::hex << (int)(src->packets[i].raw[0]) << std::dec << " not merged, because it is not a signature." << std::endl; -#endif - } - - for(std::set::const_iterator it(to_add.begin());it!=to_add.end();++it) - { -#ifdef DEBUG_PGPHANDLER - std::cerr << " Adding packet with tag 0x" << std::hex << (int)(*it).raw[0] << std::dec << std::endl; -#endif - ops_add_packet_to_keydata(dst,&*it) ; - } - return to_add.size() > 0 ; -} - bool PGPHandler::parseSignature(unsigned char *sign, unsigned int signlen,RsPgpId& issuer_id) { PGPSignatureInfo info ; @@ -1895,71 +349,6 @@ bool PGPHandler::locked_writePrivateTrustDatabase() return true ; } -bool PGPHandler::syncDatabase() -{ - RsStackMutex mtx(pgphandlerMtx) ; // lock access to PGP memory structures. - RsStackFileLock flck(_pgp_lock_filename) ; // lock access to PGP directory. - -#ifdef DEBUG_PGPHANDLER - std::cerr << "Sync-ing keyrings." << std::endl; -#endif - locked_syncPublicKeyring() ; - //locked_syncSecretKeyring() ; - - // Now sync the trust database as well. - // - locked_syncTrustDatabase() ; - -#ifdef DEBUG_PGPHANDLER - std::cerr << "Done. " << std::endl; -#endif - return true ; -} - -bool PGPHandler::locked_syncPublicKeyring() -{ - struct stat64 buf ; -#ifdef WINDOWS_SYS - std::wstring wfullname; - librs::util::ConvertUtf8ToUtf16(_pubring_path, wfullname); - if(-1 == _wstati64(wfullname.c_str(), &buf)) -#else - if(-1 == stat64(_pubring_path.c_str(), &buf)) -#endif - std::cerr << "PGPHandler::syncDatabase(): can't stat file " << _pubring_path << ". Can't sync public keyring." << std::endl; - - if(_pubring_last_update_time < buf.st_mtime) - { - std::cerr << "Detected change on disk of public keyring. Merging!" << std::endl ; - - locked_mergeKeyringFromDisk(_pubring,_public_keyring_map,_pubring_path) ; - _pubring_last_update_time = buf.st_mtime ; - } - - // Now check if the pubring was locally modified, which needs saving it again - if(_pubring_changed && RsDiscSpace::checkForDiscSpace(RS_PGP_DIRECTORY)) - { - std::string tmp_keyring_file = _pubring_path + ".tmp" ; - - std::cerr << "Local changes in public keyring. Writing to disk..." << std::endl; - if(!ops_write_keyring_to_file(_pubring,ops_false,tmp_keyring_file.c_str(),ops_true)) - { - std::cerr << "Cannot write public keyring tmp file. Disk full? Disk quota exceeded?" << std::endl; - return false ; - } - if(!RsDirUtil::renameFile(tmp_keyring_file,_pubring_path)) - { - std::cerr << "Cannot rename tmp pubring file " << tmp_keyring_file << " into actual pubring file " << _pubring_path << ". Check writing permissions?!?" << std::endl; - return false ; - } - - std::cerr << "Done." << std::endl; - _pubring_last_update_time = time(NULL) ; // should we get this value from the disk instead?? - _pubring_changed = false ; - } - return true ; -} - bool PGPHandler::locked_syncTrustDatabase() { struct stat64 buf ; @@ -1997,137 +386,6 @@ bool PGPHandler::locked_syncTrustDatabase() } return true ; } -void PGPHandler::locked_mergeKeyringFromDisk( ops_keyring_t *keyring, - std::map& kmap, - const std::string& keyring_file) -{ -#ifdef DEBUG_PGPHANDLER - std::cerr << "Merging keyring " << keyring_file << " from disk to memory." << std::endl; -#endif - // 1 - load keyring into a temporary keyring list. - ops_keyring_t *tmp_keyring = PGPHandler::allocateOPSKeyring() ; - if(ops_false == ops_keyring_read_from_file(tmp_keyring, false, keyring_file.c_str())) - { - std::cerr << "PGPHandler::locked_mergeKeyringFromDisk(): cannot read keyring. File corrupted?" ; - ops_keyring_free(tmp_keyring) ; - return ; - } - // 2 - load new keys and merge existing key signatures - - for(int i=0;inkeys;++i) - locked_addOrMergeKey(keyring,kmap,&tmp_keyring->keys[i]) ;// we dont' account for the return value. This is disk merging, not local changes. - - // 4 - clean - ops_keyring_free(tmp_keyring) ; -} - -bool PGPHandler::removeKeysFromPGPKeyring(const std::set& keys_to_remove,std::string& backup_file,uint32_t& error_code) -{ - // 1 - lock everything. - // - RsStackMutex mtx(pgphandlerMtx) ; // lock access to PGP memory structures. - RsStackFileLock flck(_pgp_lock_filename) ; // lock access to PGP directory. - - error_code = PGP_KEYRING_REMOVAL_ERROR_NO_ERROR ; - - for(std::set::const_iterator it(keys_to_remove.begin());it!=keys_to_remove.end();++it) - if(locked_getSecretKey(*it) != NULL) - { - std::cerr << "(EE) PGPHandler:: can't remove key " << (*it).toStdString() << " since its shared by a secret key! Operation cancelled." << std::endl; - error_code = PGP_KEYRING_REMOVAL_ERROR_CANT_REMOVE_SECRET_KEYS ; - return false ; - } - - // 2 - sync everything. - // - locked_syncPublicKeyring() ; - - // 3 - make a backup of the public keyring - // - char template_name[_pubring_path.length()+8] ; - sprintf(template_name,"%s.XXXXXX",_pubring_path.c_str()) ; - -#if defined __USE_XOPEN_EXTENDED || defined __USE_XOPEN2K8 - int fd_keyring_backup(mkstemp(template_name)); - if (fd_keyring_backup == -1) -#else - if(mktemp(template_name) == NULL) -#endif - { - std::cerr << "PGPHandler::removeKeysFromPGPKeyring(): cannot create keyring backup file. Giving up." << std::endl; - error_code = PGP_KEYRING_REMOVAL_ERROR_CANNOT_CREATE_BACKUP ; - return false ; - } -#if defined __USE_XOPEN_EXTENDED || defined __USE_XOPEN2K8 - close(fd_keyring_backup); // TODO: keep the file open and use the fd -#endif - - if(!ops_write_keyring_to_file(_pubring,ops_false,template_name,ops_true)) - { - std::cerr << "PGPHandler::removeKeysFromPGPKeyring(): cannot write keyring backup file. Giving up." << std::endl; - error_code = PGP_KEYRING_REMOVAL_ERROR_CANNOT_WRITE_BACKUP ; - return false ; - } - backup_file = std::string(template_name,_pubring_path.length()+7) ; - - std::cerr << "Keyring was backed up to file " << backup_file << std::endl; - - // Remove keys from the keyring, and update the keyring map. - // - for(std::set::const_iterator it(keys_to_remove.begin());it!=keys_to_remove.end();++it) - { - if(locked_getSecretKey(*it) != NULL) - { - std::cerr << "(EE) PGPHandler:: can't remove key " << (*it).toStdString() << " since its shared by a secret key!" << std::endl; - continue ; - } - - std::map::iterator res = _public_keyring_map.find(*it) ; - - if(res == _public_keyring_map.end()) - { - std::cerr << "(EE) PGPHandler:: can't remove key " << (*it).toStdString() << " from keyring: key not found." << std::endl; - continue ; - } - - if(res->second._key_index >= (unsigned int)_pubring->nkeys || RsPgpId(_pubring->keys[res->second._key_index].key_id) != *it) - { - std::cerr << "(EE) PGPHandler:: can't remove key " << (*it).toStdString() << ". Inconsistency found." << std::endl; - error_code = PGP_KEYRING_REMOVAL_ERROR_DATA_INCONSISTENCY ; - return false ; - } - - // Move the last key to the freed place. This deletes the key in place. - // - ops_keyring_remove_key(_pubring,res->second._key_index) ; - - // Erase the info from the keyring map. - // - _public_keyring_map.erase(res) ; - - // now update all indices back. This internal look is very costly, but it avoids deleting the wrong keys, since the keyring structure is - // changed by ops_keyring_remove_key and therefore indices don't point to the correct location anymore. - - int i=0 ; - const ops_keydata_t *keydata ; - while( (keydata = ops_keyring_get_key_by_index(_pubring,i)) != NULL ) - { - PGPCertificateInfo& cert(_public_keyring_map[ RsPgpId(keydata->key_id) ]) ; - cert._key_index = i ; - ++i ; - } - } - - // Everything went well, sync back the keyring on disk - - _pubring_changed = true ; - _trustdb_changed = true ; - - locked_syncPublicKeyring() ; - locked_syncTrustDatabase() ; - - return true ; -} diff --git a/libretroshare/src/pgp/pgphandler.h b/libretroshare/src/pgp/pgphandler.h index 5d7eb82f8..07b02325c 100644 --- a/libretroshare/src/pgp/pgphandler.h +++ b/libretroshare/src/pgp/pgphandler.h @@ -29,12 +29,6 @@ #include #include -extern "C" { -#include -#include -#include -} - typedef std::string (*PassphraseCallback)(void *data, const char *uid_title, const char *uid_hint, const char *passphrase_info, int prev_was_bad,bool *cancelled) ; class PGPCertificateInfo @@ -56,9 +50,11 @@ class PGPCertificateInfo mutable rstime_t _time_stamp ; // last time the key was used (received, used for signature verification, etc) PGPFingerprintType _fpr; /* fingerprint */ - // RsPgpId _key_id ; - uint32_t _key_index ; // index to array of keys in the public keyring + // Index to array of keys in the public keyring. Dependign on the specific implementation + // of how the keyring is stored, this may be used differently. + + uint32_t _key_index ; static const uint32_t PGP_CERTIFICATE_FLAG_ACCEPT_CONNEXION = 0x0001 ; static const uint32_t PGP_CERTIFICATE_FLAG_HAS_OWN_SIGNATURE = 0x0002 ; @@ -80,53 +76,87 @@ class PGPCertificateInfo class PGPHandler { public: - PGPHandler( const std::string& path_to_public_keyring, + PGPHandler( const std::string& path_to_public_keyring, const std::string& path_to_secret_keyring, const std::string& path_to_trust_database, const std::string& pgp_lock_file) ; virtual ~PGPHandler() ; - /** + //=======================================================================================// + // Methods that needs to be derived depending on how PGP is implemented // + //=======================================================================================// + + // Removes the given keys from the keyring. Also backup the keyring to a file which name is automatically generated + // and given pack for proper display. + // + virtual bool removeKeysFromPGPKeyring(const std::set& key_ids,std::string& backup_file,uint32_t& error_code) =0; + virtual std::string makeRadixEncodedPGPKey(uint32_t key_index,bool include_signatures) =0; + + virtual bool availableGPGCertificatesWithPrivateKeys(std::list& ids)=0; + virtual bool GeneratePGPCertificate(const std::string& name, const std::string& email, const std::string& passwd, RsPgpId& pgpId, const int keynumbits, std::string& errString) =0; + + virtual std::string SaveCertificateToString(const RsPgpId& id,bool include_signatures) const=0; + + /** The caller is in charge of freeing `mem` once finished */ + virtual bool exportPublicKey( const RsPgpId& id, unsigned char*& mem_block, size_t& mem_size, bool armoured, bool include_signatures ) const =0; + + virtual bool exportGPGKeyPair(const std::string& filename,const RsPgpId& exported_key_id) const=0; + virtual bool exportGPGKeyPairToString( std::string& data, const RsPgpId& exportedKeyId, bool includeSignatures, std::string& errorMsg ) const =0; + + // Gets info about the key. Who are the signers, what's the owner's name, etc. + // + virtual bool getGPGDetailsFromBinaryBlock(const unsigned char *mem,size_t mem_size,RsPgpId& key_id, std::string& name, std::list& signers) const =0; + + virtual bool importGPGKeyPair(const std::string& filename,RsPgpId& imported_id,std::string& import_error) =0; + /** * @param ids list of gpg certificate ids (note, not the actual certificates) */ + + virtual bool importGPGKeyPairFromString(const std::string& data,RsPgpId& imported_id,std::string& import_error) =0; + + virtual bool LoadCertificateFromString(const std::string& pem, RsPgpId& gpg_id, std::string& error_string)=0; + virtual bool LoadCertificateFromBinaryData(const unsigned char *bin_data,uint32_t bin_data_len, RsPgpId& gpg_id, std::string& error_string)=0; + + virtual bool encryptTextToFile(const RsPgpId& key_id,const std::string& text,const std::string& outfile) =0; + virtual bool decryptTextFromFile(const RsPgpId& key_id,std::string& text,const std::string& encrypted_inputfile) =0; + + // The client should supply a memory chunk to store the data. The length will be updated to the real length of the data. + // + virtual bool encryptDataBin(const RsPgpId& key_id,const void *data, const uint32_t len , unsigned char *encrypted_data, unsigned int *encrypted_data_len) =0; + virtual bool decryptDataBin(const RsPgpId& key_id,const void *encrypted_data, const uint32_t encrypted_len , unsigned char *data, unsigned int *data_len) =0; + + virtual bool SignDataBin(const RsPgpId& id, const void *data, const uint32_t len, unsigned char *sign, unsigned int *signlen, bool make_raw_signature=false, std::string reason = "") =0; + virtual bool privateSignCertificate(const RsPgpId& own_id,const RsPgpId& id_of_key_to_sign) =0; + virtual bool VerifySignBin(const void *data, uint32_t data_len, unsigned char *sign, unsigned int sign_len, const PGPFingerprintType& withfingerprint) =0; + /** + * @brief Get PGP fingerprint for the given key + * @param id PGP 64bit key id + * @param fp storage for the retrived key fingerpring, the contained value + * is meaningfull only if true is returned + * @return true if the key was found, false if not + */ + virtual bool getKeyFingerprint(const RsPgpId& id, RsPgpFingerprint& fp) const=0; + + virtual bool haveSecretKey(const RsPgpId& id) const =0; + + // Syncs the keyrings and trust database between memory and disk. The algorithm is: + // 1 - lock the keyrings + // 2 - compare file modification dates with last writing date + // - if file is modified, load it, and merge with memory + // 3 - look into memory modification flags + // - if flag says keyring has changed, write to disk + // + virtual bool syncDatabase() =0; + + + //=======================================================================================// + // Common methods to PGPHandler // + //=======================================================================================// + bool getGPGFilteredList(std::list& list,bool (*filter)(const PGPCertificateInfo&) = NULL) const ; - bool haveSecretKey(const RsPgpId& id) const ; - bool importGPGKeyPair(const std::string& filename,RsPgpId& imported_id,std::string& import_error) ; - bool importGPGKeyPairFromString(const std::string& data,RsPgpId& imported_id,std::string& import_error) ; - bool exportGPGKeyPair(const std::string& filename,const RsPgpId& exported_id) const ; - bool exportGPGKeyPairToString( - std::string& data, const RsPgpId& exportedKeyId, - bool includeSignatures, std::string& errorMsg ) const; - - bool availableGPGCertificatesWithPrivateKeys(std::list& ids); - bool GeneratePGPCertificate(const std::string& name, const std::string& email, const std::string& passwd, RsPgpId& pgpId, const int keynumbits, std::string& errString) ; - - bool LoadCertificateFromString(const std::string& pem, RsPgpId& gpg_id, std::string& error_string); - bool LoadCertificateFromBinaryData(const unsigned char *bin_data,uint32_t bin_data_len, RsPgpId& gpg_id, std::string& error_string); - - std::string SaveCertificateToString(const RsPgpId& id,bool include_signatures) const ; - - /** The caller is in charge of freeing `mem` once finished */ - bool exportPublicKey( const RsPgpId& id, - unsigned char*& mem, size_t& mem_size, - bool armoured, bool include_signatures) const; - - bool parseSignature(unsigned char *sign, unsigned int signlen,RsPgpId& issuer_id) ; - bool SignDataBin(const RsPgpId& id, const void *data, const uint32_t len, unsigned char *sign, unsigned int *signlen, bool make_raw_signature=false, std::string reason = "") ; - bool VerifySignBin(const void *data, uint32_t data_len, unsigned char *sign, unsigned int sign_len, const PGPFingerprintType& withfingerprint) ; - bool privateSignCertificate(const RsPgpId& own_id,const RsPgpId& id_of_key_to_sign) ; - - // The client should supply a memory chunk to store the data. The length will be updated to the real length of the data. - // - bool encryptDataBin(const RsPgpId& key_id,const void *data, const uint32_t len - , unsigned char *encrypted_data, unsigned int *encrypted_data_len) ; - bool decryptDataBin(const RsPgpId& key_id,const void *encrypted_data, const uint32_t encrypted_len - , unsigned char *data, unsigned int *data_len) ; - - bool encryptTextToFile(const RsPgpId& key_id,const std::string& text,const std::string& outfile) ; - bool decryptTextFromFile(const RsPgpId& key_id,std::string& text,const std::string& encrypted_inputfile) ; + bool parseSignature(unsigned char *sign, unsigned int signlen,RsPgpId& issuer_id) ; void setAcceptConnexion(const RsPgpId&,bool) ; @@ -135,11 +165,6 @@ public: void locked_updateOwnSignatureFlag(PGPCertificateInfo&, const RsPgpId&, PGPCertificateInfo&, const RsPgpId&) ; - // Removes the given keys from the keyring. Also backup the keyring to a file which name is automatically generated - // and given pack for proper display. - // - bool removeKeysFromPGPKeyring(const std::set& key_ids,std::string& backup_file,uint32_t& error_code) ; - //bool isKeySupported(const RsPgpId& id) const ; bool privateTrustCertificate(const RsPgpId& id,int valid_level) ; @@ -174,66 +199,18 @@ public: */ static RsPgpId pgpIdFromFingerprint(const RsPgpFingerprint& f); - /** - * @brief Get PGP fingerprint for the given key - * @param id PGP 64bit key id - * @param fp storage for the retrived key fingerpring, the contained value - * is meaningfull only if true is returned - * @return true if the key was found, false if not - */ - bool getKeyFingerprint(const RsPgpId& id, RsPgpFingerprint& fp) const; - - // Gets info about the key. Who are the signers, what's the owner's name, etc. - // - bool getGPGDetailsFromBinaryBlock(const unsigned char *mem,size_t mem_size,RsPgpId& key_id, std::string& name, std::list& signers) const ; - // Debug stuff. virtual bool printKeys() const ; - // Syncs the keyrings and trust database between memory and disk. The algorithm is: - // 1 - lock the keyrings - // 2 - compare file modification dates with last writing date - // - if file is modified, load it, and merge with memory - // 3 - look into memory modification flags - // - if flag says keyring has changed, write to disk - // - bool syncDatabase() ; - - private: - bool LoadCertificate(const unsigned char *bin_data,uint32_t bin_data_len, bool armoured, RsPgpId& gpg_id, std::string& error_string); - void initCertificateInfo(PGPCertificateInfo& cert,const ops_keydata_t *keydata,uint32_t i) ; - - // Returns true if the signatures have been updated - // - bool validateAndUpdateSignatures(PGPCertificateInfo& cert,const ops_keydata_t *keydata) ; - - /** Check public/private key and import them into the keyring - * @param keyring keyring with the new public/private key pair. Will be freed by the function. - * @param imported_key_id PGP id of the imported key - * @param import_error human readbale error message - * @returns true on success - * */ - bool checkAndImportKeyPair(ops_keyring_t *keyring, RsPgpId& imported_key_id,std::string& import_error); - - const ops_keydata_t *locked_getPublicKey(const RsPgpId&,bool stamp_the_key) const; - const ops_keydata_t *locked_getSecretKey(const RsPgpId&) const ; - + protected: void locked_readPrivateTrustDatabase() ; bool locked_writePrivateTrustDatabase() ; - - bool locked_syncPublicKeyring() ; - bool locked_syncTrustDatabase() ; - - void locked_mergeKeyringFromDisk(ops_keyring_t *keyring, std::map& kmap, const std::string& keyring_file) ; - bool locked_addOrMergeKey(ops_keyring_t *keyring,std::map& kmap,const ops_keydata_t *keydata) ; + bool locked_syncTrustDatabase() ; // Members. // mutable RsMutex pgphandlerMtx ; - ops_keyring_t *_pubring ; - ops_keyring_t *_secring ; - std::map _public_keyring_map ; // used for fast access to keys. Gives the index in the keyring. std::map _secret_keyring_map ; @@ -249,11 +226,5 @@ public: rstime_t _secring_last_update_time ; rstime_t _trustdb_last_update_time ; - // Helper functions. - // - static std::string makeRadixEncodedPGPKey(const ops_keydata_t *key,bool include_signatures) ; - static ops_keyring_t *allocateOPSKeyring() ; - static void addNewKeyToOPSKeyring(ops_keyring_t*, const ops_keydata_t&) ; static PassphraseCallback _passphrase_callback ; - static bool mergeKeySignatures(ops_keydata_t *dst,const ops_keydata_t *src) ; // returns true if signature lists are different }; diff --git a/libretroshare/src/pqi/authgpg.cc b/libretroshare/src/pqi/authgpg.cc index b41084cf0..2d29fbb65 100644 --- a/libretroshare/src/pqi/authgpg.cc +++ b/libretroshare/src/pqi/authgpg.cc @@ -126,7 +126,7 @@ void AuthGPG::exit() AuthGPG::AuthGPG(const std::string& path_to_public_keyring,const std::string& path_to_secret_keyring,const std::string& path_to_trustdb,const std::string& pgp_lock_file) :p3Config(), - PGPHandler(path_to_public_keyring,path_to_secret_keyring,path_to_trustdb,pgp_lock_file), + OpenPGPSDKHandler(path_to_public_keyring,path_to_secret_keyring,path_to_trustdb,pgp_lock_file), gpgMtxService("AuthGPG-service"), gpgMtxEngine("AuthGPG-engine"), gpgMtxData("AuthGPG-data"), diff --git a/libretroshare/src/pqi/authgpg.h b/libretroshare/src/pqi/authgpg.h index 4fe76194c..a6023f436 100644 --- a/libretroshare/src/pqi/authgpg.h +++ b/libretroshare/src/pqi/authgpg.h @@ -34,7 +34,7 @@ #include "util/rsthreads.h" #include "pqi/p3cfgmgr.h" -#include "pgp/pgphandler.h" +#include "pgp/openpgpsdkhandler.h" #define MAX_GPG_SIGNATURE_SIZE 4096 @@ -89,7 +89,9 @@ public: virtual void setGPGOperation(AuthGPGOperation *operation) = 0; }; -class AuthGPG: public p3Config, public RsTickingThread, public PGPHandler +// Note: replace OpenPGPSDKHandler with your own PGP handler class when needed. + +class AuthGPG: public p3Config, public RsTickingThread, public OpenPGPSDKHandler { public: static void init(const std::string& path_to_pubring, From b8f4e6439374b3e96e3993d571c872caf5f6e6ac Mon Sep 17 00:00:00 2001 From: csoler Date: Wed, 11 Aug 2021 16:02:02 +0200 Subject: [PATCH 014/113] initial split of PHPHandler into two classes --- libretroshare/src/pgp/openpgpsdkhandler.cc | 1801 ++++++++++++++++++++ libretroshare/src/pgp/openpgpsdkhandler.h | 116 ++ 2 files changed, 1917 insertions(+) create mode 100644 libretroshare/src/pgp/openpgpsdkhandler.cc create mode 100644 libretroshare/src/pgp/openpgpsdkhandler.h diff --git a/libretroshare/src/pgp/openpgpsdkhandler.cc b/libretroshare/src/pgp/openpgpsdkhandler.cc new file mode 100644 index 000000000..87f3c3343 --- /dev/null +++ b/libretroshare/src/pgp/openpgpsdkhandler.cc @@ -0,0 +1,1801 @@ +/******************************************************************************* + * libretroshare/src/pgp: pgphandler.cc * + * * + * libretroshare: retroshare core library * + * * + * Copyright 2018 Cyril Soler * + * * + * 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 +#include +#include +#include +#include +#include +#include + +#ifdef WINDOWS_SYS +#include +#include "util/rsstring.h" +#include "util/rswin.h" +#endif + +extern "C" { +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +} +#include "openpgpsdkhandler.h" + +#include "util/rsdir.h" +#include "util/rsdiscspace.h" +#include "util/rsmemory.h" +#include "pgp/pgpkeyutil.h" +#include "retroshare/rspeers.h" + +static const uint32_t PGP_CERTIFICATE_LIMIT_MAX_NAME_SIZE = 64 ; +static const uint32_t PGP_CERTIFICATE_LIMIT_MAX_EMAIL_SIZE = 64 ; +static const uint32_t PGP_CERTIFICATE_LIMIT_MAX_PASSWD_SIZE = 1024 ; + +//#define DEBUG_PGPHANDLER 1 +//#define PGPHANDLER_DSA_SUPPORT + +PassphraseCallback PGPHandler::_passphrase_callback = NULL ; + +ops_keyring_t *OpenPGPSDKHandler::allocateOPSKeyring() +{ + ops_keyring_t *kr = (ops_keyring_t*)rs_malloc(sizeof(ops_keyring_t)) ; + + if(kr == NULL) + return NULL ; + + kr->nkeys = 0 ; + kr->nkeys_allocated = 0 ; + kr->keys = 0 ; + + return kr ; +} + +ops_parse_cb_return_t cb_get_passphrase(const ops_parser_content_t *content_,ops_parse_cb_info_t *cbinfo)// __attribute__((unused))) +{ + const ops_parser_content_union_t *content=&content_->content; + bool prev_was_bad = false ; + + switch(content_->tag) + { + case OPS_PARSER_CMD_GET_SK_PASSPHRASE_PREV_WAS_BAD: prev_was_bad = true ; + /* fallthrough */ + case OPS_PARSER_CMD_GET_SK_PASSPHRASE: + { + std::string passwd; + std::string uid_hint ; + + if(cbinfo->cryptinfo.keydata->nuids > 0) + uid_hint = std::string((const char *)cbinfo->cryptinfo.keydata->uids[0].user_id) ; + uid_hint += "(" + RsPgpId(cbinfo->cryptinfo.keydata->key_id).toStdString()+")" ; + + bool cancelled = false ; + passwd = PGPHandler::passphraseCallback()(NULL,"",uid_hint.c_str(),NULL,prev_was_bad,&cancelled) ; + + if(cancelled) + *(unsigned char *)cbinfo->arg = 1; + + *(content->secret_key_passphrase.passphrase)= (char *)ops_mallocz(passwd.length()+1) ; + memcpy(*(content->secret_key_passphrase.passphrase),passwd.c_str(),passwd.length()) ; + return OPS_KEEP_MEMORY; + } + break; + + default: + break; + } + + return OPS_RELEASE_MEMORY; +} + +OpenPGPSDKHandler::OpenPGPSDKHandler(const std::string& pubring, const std::string& secring,const std::string& trustdb,const std::string& pgp_lock_filename) + : PGPHandler(pubring,secring,trustdb,pgp_lock_filename) +{ + RsStackMutex mtx(pgphandlerMtx) ; // lock access to PGP memory structures. + + // Allocate public and secret keyrings. + // + _pubring = allocateOPSKeyring() ; + _secring = allocateOPSKeyring() ; + + // Check that the file exists. If not, create a void keyring. + + FILE *ftest ; + ftest = RsDirUtil::rs_fopen(pubring.c_str(),"rb") ; + bool pubring_exist = (ftest != NULL) ; + if(ftest != NULL) + fclose(ftest) ; + ftest = RsDirUtil::rs_fopen(secring.c_str(),"rb") ; + bool secring_exist = (ftest != NULL) ; + if(ftest != NULL) + fclose(ftest) ; + + // Read public and secret keyrings from supplied files. + // + if(pubring_exist) + { + if(ops_false == ops_keyring_read_from_file(_pubring, false, pubring.c_str())) + throw std::runtime_error("OpenPGPSDKHandler::readKeyRing(): cannot read pubring. File corrupted.") ; + } + else + std::cerr << "pubring file \"" << pubring << "\" not found. Creating a void keyring." << std::endl; + + const ops_keydata_t *keydata ; + int i=0 ; + while( (keydata = ops_keyring_get_key_by_index(_pubring,i)) != NULL ) + { + PGPCertificateInfo& cert(_public_keyring_map[ RsPgpId(keydata->key_id) ]) ; + + // Init all certificates. + + initCertificateInfo(cert,keydata,i) ; + + // Validate signatures. + + validateAndUpdateSignatures(cert,keydata) ; + + ++i ; + } + _pubring_last_update_time = time(NULL) ; + std::cerr << "Pubring read successfully." << std::endl; + + if(secring_exist) + { + if(ops_false == ops_keyring_read_from_file(_secring, false, secring.c_str())) + throw std::runtime_error("OpenPGPSDKHandler::readKeyRing(): cannot read secring. File corrupted.") ; + } + else + std::cerr << "secring file \"" << secring << "\" not found. Creating a void keyring." << std::endl; + + i=0 ; + while( (keydata = ops_keyring_get_key_by_index(_secring,i)) != NULL ) + { + initCertificateInfo(_secret_keyring_map[ RsPgpId(keydata->key_id) ],keydata,i) ; + ++i ; + } + _secring_last_update_time = time(NULL) ; + + std::cerr << "Secring read successfully." << std::endl; + + locked_readPrivateTrustDatabase() ; + _trustdb_last_update_time = time(NULL) ; +} + +void OpenPGPSDKHandler::initCertificateInfo(PGPCertificateInfo& cert,const ops_keydata_t *keydata,uint32_t index) +{ + // Parse certificate name + // + + if(keydata->uids != NULL) + { + std::string namestring( (char *)keydata->uids[0].user_id ) ; + + cert._name = "" ; + uint32_t i=0; + while(i < namestring.length() && namestring[i] != '(' && namestring[i] != '<') { cert._name += namestring[i] ; ++i ;} + + // trim right spaces + std::string::size_type found = cert._name.find_last_not_of(' '); + if (found != std::string::npos) + cert._name.erase(found + 1); + else + cert._name.clear(); // all whitespace + + std::string& next = (namestring[i] == '(')?cert._comment:cert._email ; + ++i ; + next = "" ; + while(i < namestring.length() && namestring[i] != ')' && namestring[i] != '>') { next += namestring[i] ; ++i ;} + + while(i < namestring.length() && namestring[i] != '(' && namestring[i] != '<') { next += namestring[i] ; ++i ;} + + if(i< namestring.length()) + { + std::string& next2 = (namestring[i] == '(')?cert._comment:cert._email ; + ++i ; + next2 = "" ; + while(i < namestring.length() && namestring[i] != ')' && namestring[i] != '>') { next2 += namestring[i] ; ++i ;} + } + } + + cert._trustLvl = 1 ; // to be setup accordingly + cert._validLvl = 1 ; // to be setup accordingly + cert._key_index = index ; + cert._flags = 0 ; + cert._time_stamp = 0 ;// "never" by default. Will be updated by trust database, and effective key usage. + + switch(keydata->key.pkey.algorithm) + { + case OPS_PKA_RSA: cert._type = PGPCertificateInfo::PGP_CERTIFICATE_TYPE_RSA ; + break ; + case OPS_PKA_DSA: cert._type = PGPCertificateInfo::PGP_CERTIFICATE_TYPE_DSA ; + cert._flags |= PGPCertificateInfo::PGP_CERTIFICATE_FLAG_UNSUPPORTED_ALGORITHM ; + break ; + default: cert._type = PGPCertificateInfo::PGP_CERTIFICATE_TYPE_UNKNOWN ; + cert._flags |= PGPCertificateInfo::PGP_CERTIFICATE_FLAG_UNSUPPORTED_ALGORITHM ; + break ; + } + + ops_fingerprint_t f ; + ops_fingerprint(&f,&keydata->key.pkey) ; + + cert._fpr = PGPFingerprintType(f.fingerprint) ; +} + +bool OpenPGPSDKHandler::validateAndUpdateSignatures(PGPCertificateInfo& cert,const ops_keydata_t *keydata) +{ + ops_validate_result_t* result=(ops_validate_result_t*)ops_mallocz(sizeof *result); + ops_boolean_t res = ops_validate_key_signatures(result,keydata,_pubring,cb_get_passphrase) ; + + if(res == ops_false) + { + static ops_boolean_t already = 0 ; + if(!already) + { + std::cerr << "(WW) Error in OpenPGPSDKHandler::validateAndUpdateSignatures(). Validation failed for at least some signatures." << std::endl; + already = 1 ; + } + } + + bool ret = false ; + + // Parse signers. + // + + if(result != NULL) + for(size_t i=0;ivalid_count;++i) + { + RsPgpId signer_id(result->valid_sigs[i].signer_id); + + if(cert.signers.find(signer_id) == cert.signers.end()) + { + cert.signers.insert(signer_id) ; + ret = true ; + } + } + + ops_validate_result_free(result) ; + + return ret ; +} + +OpenPGPSDKHandler::~OpenPGPSDKHandler() +{ + RsStackMutex mtx(pgphandlerMtx) ; // lock access to PGP memory structures. +#ifdef DEBUG_PGPHANDLER + std::cerr << "Freeing OpenPGPSDKHandler. Deleting keyrings." << std::endl; +#endif + + // no need to free the the _map_ elements. They will be freed by the following calls: + // + ops_keyring_free(_pubring) ; + ops_keyring_free(_secring) ; + + free(_pubring) ; + free(_secring) ; +} + +void OpenPGPSDKHandler::printOPSKeys() const +{ + std::cerr << "Public keyring list from OPS:" << std::endl; + ops_keyring_list(_pubring) ; +} + +bool OpenPGPSDKHandler::haveSecretKey(const RsPgpId& id) const +{ + RsStackMutex mtx(pgphandlerMtx) ; // lock access to PGP memory structures. + + return locked_getSecretKey(id) != NULL ; +} + +bool OpenPGPSDKHandler::availableGPGCertificatesWithPrivateKeys(std::list& ids) +{ + RsStackMutex mtx(pgphandlerMtx) ; // lock access to PGP memory structures. + // go through secret keyring, and check that we have the pubkey as well. + // + + const ops_keydata_t *keydata = NULL ; + int i=0 ; + + while( (keydata = ops_keyring_get_key_by_index(_secring,i++)) != NULL ) + if(ops_keyring_find_key_by_id(_pubring,keydata->key_id) != NULL) // check that the key is in the pubring as well + { +#ifdef PGPHANDLER_DSA_SUPPORT + if(keydata->key.pkey.algorithm == OPS_PKA_RSA || keydata->key.pkey.algorithm == OPS_PKA_DSA) +#else + if(keydata->key.pkey.algorithm == OPS_PKA_RSA) +#endif + ids.push_back(RsPgpId(keydata->key_id)) ; +#ifdef DEBUG_PGPHANDLER + else + std::cerr << "Skipping keypair " << RsPgpId(keydata->key_id).toStdString() << ", unsupported algorithm: " << keydata->key.pkey.algorithm << std::endl; +#endif + } + + return true ; +} + +bool OpenPGPSDKHandler::GeneratePGPCertificate(const std::string& name, const std::string& email, const std::string& passphrase, RsPgpId& pgpId, const int keynumbits, std::string& errString) +{ + // Some basic checks + + if(!RsDiscSpace::checkForDiscSpace(RS_PGP_DIRECTORY)) + { + errString = std::string("(EE) low disc space in pgp directory. Can't write safely to keyring.") ; + return false ; + } + if(name.length() > PGP_CERTIFICATE_LIMIT_MAX_NAME_SIZE) + { + errString = std::string("(EE) name in certificate exceeds the maximum allowed name size") ; + return false ; + } + if(email.length() > PGP_CERTIFICATE_LIMIT_MAX_EMAIL_SIZE) + { + errString = std::string("(EE) email in certificate exceeds the maximum allowed email size") ; + return false ; + } + if(passphrase.length() > PGP_CERTIFICATE_LIMIT_MAX_PASSWD_SIZE) + { + errString = std::string("(EE) passphrase in certificate exceeds the maximum allowed passphrase size") ; + return false ; + } + if(keynumbits % 1024 != 0) + { + errString = std::string("(EE) RSA key length is not a multiple of 1024") ; + return false ; + } + + // Now the real thing + RsStackMutex mtx(pgphandlerMtx) ; // lock access to PGP memory structures. + RsStackFileLock flck(_pgp_lock_filename) ; // lock access to PGP directory. + + // 1 - generate keypair - RSA-2048 + // + ops_user_id_t uid ; + char *s = strdup((name + " (Generated by RetroShare) <" + email + ">" ).c_str()) ; + uid.user_id = (unsigned char *)s ; + unsigned long int e = 65537 ; // some prime number + + ops_keydata_t *key = ops_rsa_create_selfsigned_keypair(keynumbits, e, &uid) ; + + free(s) ; + + if(!key) + return false ; + + // 2 - save the private key encrypted to a temporary memory buffer, so as to read an encrypted key to memory + + ops_create_info_t *cinfo = NULL ; + ops_memory_t *buf = NULL ; + ops_setup_memory_write(&cinfo, &buf, 0); + + if(!ops_write_transferable_secret_key(key,(unsigned char *)passphrase.c_str(),passphrase.length(),ops_false,cinfo)) + { + errString = std::string("(EE) Cannot encode secret key to memory!!") ; + return false ; + } + + // 3 - read the memory chunk into an encrypted keyring + + ops_keyring_t *tmp_secring = allocateOPSKeyring() ; + + if(! ops_keyring_read_from_mem(tmp_secring, ops_false, buf)) + { + errString = std::string("(EE) Cannot re-read key from memory!!") ; + return false ; + } + ops_teardown_memory_write(cinfo,buf); // cleanup memory + + // 4 - copy the encrypted private key to the private keyring + + pgpId = RsPgpId(tmp_secring->keys[0].key_id) ; + addNewKeyToOPSKeyring(_secring,tmp_secring->keys[0]) ; + initCertificateInfo(_secret_keyring_map[ pgpId ],&tmp_secring->keys[0],_secring->nkeys-1) ; + +#ifdef DEBUG_PGPHANDLER + std::cerr << "Added new secret key with id " << pgpId.toStdString() << " to secret keyring." << std::endl; +#endif + ops_keyring_free(tmp_secring) ; + free(tmp_secring) ; + + // 5 - add key to secret keyring on disk. + + cinfo = NULL ; + std::string secring_path_tmp = _secring_path + ".tmp" ; + + if(RsDirUtil::fileExists(_secring_path) && !RsDirUtil::copyFile(_secring_path,secring_path_tmp)) + { + errString= std::string("Cannot copy secret keyring !! Disk full? Out of disk quota?") ; + return false ; + } + int fd=ops_setup_file_append(&cinfo, secring_path_tmp.c_str()); + + if(!ops_write_transferable_secret_key(key,(unsigned char *)passphrase.c_str(),passphrase.length(),ops_false,cinfo)) + { + errString= std::string("Cannot encode secret key to disk!! Disk full? Out of disk quota?") ; + return false ; + } + ops_teardown_file_write(cinfo,fd) ; + + if(!RsDirUtil::renameFile(secring_path_tmp,_secring_path)) + { + errString= std::string("Cannot rename tmp secret key file ") + secring_path_tmp + " into " + _secring_path +". Disk error?" ; + return false ; + } + + // 6 - copy the public key to the public keyring on disk + + cinfo = NULL ; + std::string pubring_path_tmp = _pubring_path + ".tmp" ; + + if(RsDirUtil::fileExists(_pubring_path) && !RsDirUtil::copyFile(_pubring_path,pubring_path_tmp)) + { + errString= std::string("Cannot encode secret key to disk!! Disk full? Out of disk quota?") ; + return false ; + } + fd=ops_setup_file_append(&cinfo, pubring_path_tmp.c_str()); + + if(!ops_write_transferable_public_key(key, ops_false, cinfo)) + { + errString=std::string("Cannot encode secret key to memory!!") ; + return false ; + } + ops_teardown_file_write(cinfo,fd) ; + + if(!RsDirUtil::renameFile(pubring_path_tmp,_pubring_path)) + { + errString= std::string("Cannot rename tmp public key file ") + pubring_path_tmp + " into " + _pubring_path +". Disk error?" ; + return false ; + } + // 7 - clean + ops_keydata_free(key) ; + + // 8 - re-read the key from the public keyring, and add it to memory. + + _pubring_last_update_time = 0 ; // force update pubring from disk. + locked_syncPublicKeyring() ; + +#ifdef DEBUG_PGPHANDLER + std::cerr << "Added new public key with id " << pgpId.toStdString() << " to public keyring." << std::endl; +#endif + + // 9 - Update some flags. + + privateTrustCertificate(pgpId,PGPCertificateInfo::PGP_CERTIFICATE_TRUST_ULTIMATE) ; + + return true ; +} + +std::string OpenPGPSDKHandler::makeRadixEncodedPGPKey(const ops_keydata_t *key,bool include_signatures) +{ + ops_create_info_t* cinfo; + ops_memory_t *buf = NULL ; + ops_setup_memory_write(&cinfo, &buf, 0); + ops_boolean_t armoured = ops_true ; + + if(key->type == OPS_PTAG_CT_PUBLIC_KEY) + { + if(ops_write_transferable_public_key_from_packet_data(key,armoured,cinfo) != ops_true) + return "ERROR: This key cannot be processed by RetroShare because\nDSA certificates are not yet handled." ; + } + else if(key->type == OPS_PTAG_CT_ENCRYPTED_SECRET_KEY) + { + if(ops_write_transferable_secret_key_from_packet_data(key,armoured,cinfo) != ops_true) + return "ERROR: This key cannot be processed by RetroShare because\nDSA certificates are not yet handled." ; + } + else + { + ops_create_info_delete(cinfo); + std::cerr << "Unhandled key type " << key->type << std::endl; + return "ERROR: Cannot write key. Unhandled key type. " ; + } + + ops_writer_close(cinfo) ; + + std::string res((char *)ops_memory_get_data(buf),ops_memory_get_length(buf)) ; + ops_teardown_memory_write(cinfo,buf); + + if(!include_signatures) + { + std::string tmp ; + if(PGPKeyManagement::createMinimalKey(res,tmp) ) + res = tmp ; + } + + return res ; +} + +const ops_keydata_t *OpenPGPSDKHandler::locked_getSecretKey(const RsPgpId& id) const +{ + std::map::const_iterator res = _secret_keyring_map.find(id) ; + + if(res == _secret_keyring_map.end()) + return NULL ; + else + return ops_keyring_get_key_by_index(_secring,res->second._key_index) ; +} +const ops_keydata_t *OpenPGPSDKHandler::locked_getPublicKey(const RsPgpId& id,bool stamp_the_key) const +{ + std::map::const_iterator res = _public_keyring_map.find(id) ; + + if(res == _public_keyring_map.end()) + return NULL ; + else + { + if(stamp_the_key) // Should we stamp the key as used? + { + static rstime_t last_update_db_because_of_stamp = 0 ; + rstime_t now = time(NULL) ; + + res->second._time_stamp = now ; + + if(now > last_update_db_because_of_stamp + 3600) // only update database once every hour. No need to do it more often. + { + _trustdb_changed = true ; + last_update_db_because_of_stamp = now ; + } + } + return ops_keyring_get_key_by_index(_pubring,res->second._key_index) ; + } +} + +std::string OpenPGPSDKHandler::SaveCertificateToString(const RsPgpId& id,bool include_signatures) const +{ + RsStackMutex mtx(pgphandlerMtx) ; // lock access to PGP memory structures. + const ops_keydata_t *key = locked_getPublicKey(id,false) ; + + if(key == NULL) + { + std::cerr << "Cannot output key " << id.toStdString() << ": not found in keyring." << std::endl; + return "" ; + } + + return makeRadixEncodedPGPKey(key,include_signatures) ; +} + +bool OpenPGPSDKHandler::exportPublicKey( const RsPgpId& id, unsigned char*& mem_block, size_t& mem_size, bool armoured, bool include_signatures ) const +{ + mem_block = nullptr; mem_size = 0; // clear just in case + + if(armoured) + { + RsErr() << __PRETTY_FUNCTION__ << " should not be used with " + << "armoured=true, because there's a bug in the armoured export" + << " of OPS" << std::endl; + print_stacktrace(); + return false; + } + + RS_STACK_MUTEX(pgphandlerMtx); + const ops_keydata_t* key = locked_getPublicKey(id,false); + + if(!key) + { + RsErr() << __PRETTY_FUNCTION__ << " key id: " << id + << " not found in keyring." << std::endl; + return false; + } + + ops_create_info_t* cinfo; + ops_memory_t *buf = nullptr; + ops_setup_memory_write(&cinfo, &buf, 0); + + if(ops_write_transferable_public_key_from_packet_data( + key, armoured, cinfo ) != ops_true) + { + RsErr() << __PRETTY_FUNCTION__ << " This key id " << id + << " cannot be processed by RetroShare because DSA certificates" + << " support is not implemented yet." << std::endl; + return false; + } + + ops_writer_close(cinfo); + + mem_size = ops_memory_get_length(buf); + mem_block = reinterpret_cast(malloc(mem_size)); + memcpy(mem_block,ops_memory_get_data(buf),mem_size); + + ops_teardown_memory_write(cinfo,buf); + + if(!include_signatures) + { + size_t new_size; + PGPKeyManagement::findLengthOfMinimalKey(mem_block, mem_size, new_size); + mem_size = new_size; + } + + return true; +} + +bool OpenPGPSDKHandler::exportGPGKeyPair(const std::string& filename,const RsPgpId& exported_key_id) const +{ + RsStackMutex mtx(pgphandlerMtx) ; // lock access to PGP memory structures. + + const ops_keydata_t *pubkey = locked_getPublicKey(exported_key_id,false) ; + + if(pubkey == NULL) + { + std::cerr << "Cannot output key " << exported_key_id.toStdString() << ": not found in public keyring." << std::endl; + return false ; + } + const ops_keydata_t *seckey = locked_getSecretKey(exported_key_id) ; + + if(seckey == NULL) + { + std::cerr << "Cannot output key " << exported_key_id.toStdString() << ": not found in secret keyring." << std::endl; + return false ; + } + + FILE *f = RsDirUtil::rs_fopen(filename.c_str(),"w") ; + if(f == NULL) + { + std::cerr << "Cannot output key " << exported_key_id.toStdString() << ": file " << filename << " cannot be written. Please check for permissions, quotas, disk space." << std::endl; + return false ; + } + + fprintf(f,"%s\n", makeRadixEncodedPGPKey(pubkey,true).c_str()) ; + fprintf(f,"%s\n", makeRadixEncodedPGPKey(seckey,true).c_str()) ; + + fclose(f) ; + return true ; +} + +bool OpenPGPSDKHandler::exportGPGKeyPairToString( std::string& data, const RsPgpId& exportedKeyId, bool includeSignatures, std::string& errorMsg ) const +{ + RS_STACK_MUTEX(pgphandlerMtx); + + const ops_keydata_t *pubkey = locked_getPublicKey(exportedKeyId,false); + + if(!pubkey) + { + errorMsg = "Cannot output key " + exportedKeyId.toStdString() + + ": not found in public keyring."; + return false; + } + const ops_keydata_t *seckey = locked_getSecretKey(exportedKeyId); + + if(!seckey) + { + errorMsg = "Cannot output key " + exportedKeyId.toStdString() + + ": not found in secret keyring."; + return false; + } + + data = makeRadixEncodedPGPKey(pubkey, includeSignatures); + data += "\n"; + data += makeRadixEncodedPGPKey(seckey, includeSignatures); + data += "\n"; + return true; +} + +bool OpenPGPSDKHandler::getGPGDetailsFromBinaryBlock(const unsigned char *mem_block,size_t mem_size,RsPgpId& key_id, std::string& name, std::list& signers) const +{ + ops_keyring_t *tmp_keyring = allocateOPSKeyring(); + ops_memory_t *mem = ops_memory_new() ; + ops_memory_add(mem,mem_block,mem_size); + + if(!ops_keyring_read_from_mem(tmp_keyring,ops_false,mem)) + { + ops_keyring_free(tmp_keyring) ; + free(tmp_keyring) ; + ops_memory_release(mem) ; + free(mem) ; + + std::cerr << "Could not read key. Format error?" << std::endl; + //error_string = std::string("Could not read key. Format error?") ; + return false ; + } + ops_memory_release(mem) ; + free(mem) ; + //error_string.clear() ; + + if(tmp_keyring->nkeys != 1) + { + std::cerr << "No or incomplete/invalid key in supplied pgp block." << std::endl; + return false ; + } + if(tmp_keyring->keys[0].uids == NULL) + { + std::cerr << "No uid in supplied key." << std::endl; + return false ; + } + + key_id = RsPgpId(tmp_keyring->keys[0].key_id) ; + name = std::string((char *)tmp_keyring->keys[0].uids[0].user_id) ; + + // now parse signatures. + // + ops_validate_result_t* result=(ops_validate_result_t*)ops_mallocz(sizeof *result); + ops_boolean_t res ; + + { + RsStackMutex mtx(pgphandlerMtx) ; // lock access to PGP memory structures. + res = ops_validate_key_signatures(result,&tmp_keyring->keys[0],_pubring,cb_get_passphrase) ; + } + + if(res == ops_false) + std::cerr << "(WW) Error in OpenPGPSDKHandler::validateAndUpdateSignatures(). Validation failed for at least some signatures." << std::endl; + + // also add self-signature if any (there should be!). + // + res = ops_validate_key_signatures(result,&tmp_keyring->keys[0],tmp_keyring,cb_get_passphrase) ; + + if(res == ops_false) + std::cerr << "(WW) Error in OpenPGPSDKHandler::validateAndUpdateSignatures(). Validation failed for at least some signatures." << std::endl; + + // Parse signers. + // + + std::set signers_set ; // Use a set to remove duplicates. + + if(result != NULL) + for(size_t i=0;ivalid_count;++i) + signers_set.insert(RsPgpId(result->valid_sigs[i].signer_id)) ; + + ops_validate_result_free(result) ; + + ops_keyring_free(tmp_keyring) ; + free(tmp_keyring) ; + + // write to the output variable + + signers.clear() ; + + for(std::set::const_iterator it(signers_set.begin());it!=signers_set.end();++it) + signers.push_back(*it) ; + + return true ; +} + +bool OpenPGPSDKHandler::importGPGKeyPair(const std::string& filename,RsPgpId& imported_key_id,std::string& import_error) +{ + import_error = "" ; + + // 1 - Test for file existance + // + FILE *ftest = RsDirUtil::rs_fopen(filename.c_str(),"r") ; + + if(ftest == NULL) + { + import_error = "Cannot open file " + filename + " for read. Please check access permissions." ; + return false ; + } + + fclose(ftest) ; + + // 2 - Read keyring from supplied file. + // + ops_keyring_t *tmp_keyring = allocateOPSKeyring(); + + if(ops_false == ops_keyring_read_from_file(tmp_keyring, ops_true, filename.c_str())) + { + import_error = "OpenPGPSDKHandler::readKeyRing(): cannot read key file. File corrupted?" ; + free(tmp_keyring); + return false ; + } + + return checkAndImportKeyPair(tmp_keyring, imported_key_id, import_error); +} + +bool OpenPGPSDKHandler::importGPGKeyPairFromString(const std::string &data, RsPgpId &imported_key_id, std::string &import_error) +{ + import_error = "" ; + + ops_memory_t* mem = ops_memory_new(); + ops_memory_add(mem, (unsigned char*)data.data(), data.length()); + + ops_keyring_t *tmp_keyring = allocateOPSKeyring(); + + if(ops_false == ops_keyring_read_from_mem(tmp_keyring, ops_true, mem)) + { + import_error = "OpenPGPSDKHandler::importGPGKeyPairFromString(): cannot parse key data" ; + free(tmp_keyring); + return false ; + } + return checkAndImportKeyPair(tmp_keyring, imported_key_id, import_error); +} + +bool OpenPGPSDKHandler::checkAndImportKeyPair(ops_keyring_t *tmp_keyring, RsPgpId &imported_key_id, std::string &import_error) +{ + if(tmp_keyring == 0) + { + import_error = "OpenPGPSDKHandler::checkAndImportKey(): keyring is null" ; + return false; + } + + if(tmp_keyring->nkeys != 2) + { + import_error = "OpenPGPSDKHandler::importKeyPair(): file does not contain a valid keypair." ; + if(tmp_keyring->nkeys > 2) + import_error += "\nMake sure that your key is a RSA key (DSA is not yet supported) and does not contain subkeys (not supported yet)."; + return false ; + } + + // 3 - Test that keyring contains a valid keypair. + // + const ops_keydata_t *pubkey = NULL ; + const ops_keydata_t *seckey = NULL ; + + if(tmp_keyring->keys[0].type == OPS_PTAG_CT_PUBLIC_KEY) + pubkey = &tmp_keyring->keys[0] ; + else if(tmp_keyring->keys[0].type == OPS_PTAG_CT_ENCRYPTED_SECRET_KEY) + seckey = &tmp_keyring->keys[0] ; + else + { + import_error = "Unrecognised key type in key file for key #0. Giving up." ; + std::cerr << "Unrecognised key type " << tmp_keyring->keys[0].type << " in key file for key #0. Giving up." << std::endl; + return false ; + } + if(tmp_keyring->keys[1].type == OPS_PTAG_CT_PUBLIC_KEY) + pubkey = &tmp_keyring->keys[1] ; + else if(tmp_keyring->keys[1].type == OPS_PTAG_CT_ENCRYPTED_SECRET_KEY) + seckey = &tmp_keyring->keys[1] ; + else + { + import_error = "Unrecognised key type in key file for key #1. Giving up." ; + std::cerr << "Unrecognised key type " << tmp_keyring->keys[1].type << " in key file for key #1. Giving up." << std::endl; + return false ; + } + + if(pubkey == nullptr || seckey == nullptr || pubkey == seckey) + { + import_error = "File does not contain a public and a private key. Sorry." ; + return false ; + } + if(memcmp( pubkey->fingerprint.fingerprint, + seckey->fingerprint.fingerprint, + RsPgpFingerprint::SIZE_IN_BYTES ) != 0) + { + import_error = "Public and private keys do nt have the same fingerprint. Sorry!" ; + return false ; + } + if(pubkey->key.pkey.version != 4) + { + import_error = "Public key is not version 4. Rejected!" ; + return false ; + } + + // 4 - now check self-signature for this keypair. For this we build a dummy keyring containing only the key. + // + ops_validate_result_t *result=(ops_validate_result_t*)ops_mallocz(sizeof *result); + + ops_keyring_t dummy_keyring ; + dummy_keyring.nkeys=1 ; + dummy_keyring.nkeys_allocated=1 ; + dummy_keyring.keys=const_cast(pubkey) ; + + ops_validate_key_signatures(result, const_cast(pubkey), &dummy_keyring, cb_get_passphrase) ; + + // Check that signatures contain at least one certification from the user id. + // + bool found = false ; + + for(uint32_t i=0;ivalid_count;++i) + if(!memcmp( + static_cast(result->valid_sigs[i].signer_id), + pubkey->key_id, + RsPgpId::SIZE_IN_BYTES )) + { + found = true ; + break ; + } + + if(!found) + { + import_error = "Cannot validate self signature for the imported key. Sorry." ; + return false ; + } + ops_validate_result_free(result); + + if(!RsDiscSpace::checkForDiscSpace(RS_PGP_DIRECTORY)) + { + import_error = std::string("(EE) low disc space in pgp directory. Can't write safely to keyring.") ; + return false ; + } + // 5 - All test passed. Adding key to keyring. + // + { + RsStackMutex mtx(pgphandlerMtx) ; // lock access to PGP memory structures. + + imported_key_id = RsPgpId(pubkey->key_id) ; + + if(locked_getSecretKey(imported_key_id) == NULL) + { + RsStackFileLock flck(_pgp_lock_filename) ; // lock access to PGP directory. + + ops_create_info_t *cinfo = NULL ; + + // Make a copy of the secret keyring + // + std::string secring_path_tmp = _secring_path + ".tmp" ; + if(RsDirUtil::fileExists(_secring_path) && !RsDirUtil::copyFile(_secring_path,secring_path_tmp)) + { + import_error = "(EE) Cannot write secret key to disk!! Disk full? Out of disk quota. Keyring will be left untouched." ; + return false ; + } + + // Append the new key + + int fd=ops_setup_file_append(&cinfo, secring_path_tmp.c_str()); + + if(!ops_write_transferable_secret_key_from_packet_data(seckey,ops_false,cinfo)) + { + import_error = "(EE) Cannot encode secret key to disk!! Disk full? Out of disk quota?" ; + return false ; + } + ops_teardown_file_write(cinfo,fd) ; + + // Rename the new keyring to overwrite the old one. + // + if(!RsDirUtil::renameFile(secring_path_tmp,_secring_path)) + { + import_error = " (EE) Cannot move temp file " + secring_path_tmp + ". Bad write permissions?" ; + return false ; + } + + addNewKeyToOPSKeyring(_secring,*seckey) ; + initCertificateInfo(_secret_keyring_map[ imported_key_id ],seckey,_secring->nkeys-1) ; + } + else + import_error = "Private key already exists! Not importing it again." ; + + if(locked_addOrMergeKey(_pubring,_public_keyring_map,pubkey)) + _pubring_changed = true ; + } + + // 6 - clean + // + ops_keyring_free(tmp_keyring) ; + free(tmp_keyring); + + // write public key to disk + syncDatabase(); + + return true ; +} + +void OpenPGPSDKHandler::addNewKeyToOPSKeyring(ops_keyring_t *kr,const ops_keydata_t& key) +{ + if(kr->nkeys >= kr->nkeys_allocated) + { + kr->keys = (ops_keydata_t *)realloc(kr->keys,(kr->nkeys+1)*sizeof(ops_keydata_t)) ; + kr->nkeys_allocated = kr->nkeys+1; + } + memset(&kr->keys[kr->nkeys],0,sizeof(ops_keydata_t)) ; + ops_keydata_copy(&kr->keys[kr->nkeys],&key) ; + kr->nkeys++ ; +} + +bool OpenPGPSDKHandler::LoadCertificateFromBinaryData(const unsigned char *data,uint32_t data_len,RsPgpId& id,std::string& error_string) +{ + return LoadCertificate(data,data_len,ops_false,id,error_string); +} + +bool OpenPGPSDKHandler::LoadCertificateFromString(const std::string& pgp_cert,RsPgpId& id,std::string& error_string) +{ + return LoadCertificate((unsigned char*)(pgp_cert.c_str()),pgp_cert.length(),ops_true,id,error_string); +} + +bool OpenPGPSDKHandler::LoadCertificate(const unsigned char *data,uint32_t data_len,bool armoured,RsPgpId& id,std::string& error_string) +{ + RsStackMutex mtx(pgphandlerMtx) ; // lock access to PGP memory structures. +#ifdef DEBUG_PGPHANDLER + std::cerr << "Reading new key from string: " << std::endl; +#endif + + ops_keyring_t *tmp_keyring = allocateOPSKeyring(); + ops_memory_t *mem = ops_memory_new() ; + ops_memory_add(mem,data,data_len) ; + + if(!ops_keyring_read_from_mem(tmp_keyring,armoured,mem)) + { + ops_keyring_free(tmp_keyring) ; + free(tmp_keyring) ; + ops_memory_release(mem) ; + free(mem) ; + + std::cerr << "Could not read key. Format error?" << std::endl; + error_string = std::string("Could not read key. Format error?") ; + return false ; + } + ops_memory_release(mem) ; + free(mem) ; + error_string.clear() ; + + // Check that there is exactly one key in this data packet. + // + if(tmp_keyring->nkeys != 1) + { + std::cerr << "Loaded certificate contains more than one PGP key. This is not allowed." << std::endl; + error_string = "Loaded certificate contains more than one PGP key. This is not allowed." ; + return false ; + } + + const ops_keydata_t *keydata = ops_keyring_get_key_by_index(tmp_keyring,0); + + // Check that the key is a version 4 key + // + if(keydata->key.pkey.version != 4) + { + error_string = "Public key is not version 4. Rejected!" ; + std::cerr << "Received a key with unhandled version number (" << keydata->key.pkey.version << ")" << std::endl; + return false ; + } + + // Check that the key is correctly self-signed. + // + ops_validate_result_t* result=(ops_validate_result_t*)ops_mallocz(sizeof *result); + + ops_validate_key_signatures(result,keydata,tmp_keyring,cb_get_passphrase) ; + + bool found = false ; + + for(uint32_t i=0;ivalid_count;++i) + if(!memcmp( + static_cast(result->valid_sigs[i].signer_id), + keydata->key_id, + RsPgpId::SIZE_IN_BYTES )) + { + found = true ; + break ; + } + + if(!found) + { + error_string = "This key is not self-signed. This is required by Retroshare." ; + std::cerr << "This key is not self-signed. This is required by Retroshare." << std::endl; + ops_validate_result_free(result); + return false ; + } + ops_validate_result_free(result); + +#ifdef DEBUG_PGPHANDLER + std::cerr << " Key read correctly: " << std::endl; + ops_keyring_list(tmp_keyring) ; +#endif + + int i=0 ; + + while( (keydata = ops_keyring_get_key_by_index(tmp_keyring,i++)) != NULL ) + if(locked_addOrMergeKey(_pubring,_public_keyring_map,keydata)) + { + _pubring_changed = true ; +#ifdef DEBUG_PGPHANDLER + std::cerr << " Added the key in the main public keyring." << std::endl; +#endif + } + else + std::cerr << "Key already in public keyring." << std::endl; + + if(tmp_keyring->nkeys > 0) + id = RsPgpId(tmp_keyring->keys[0].key_id) ; + else + return false ; + + ops_keyring_free(tmp_keyring) ; + free(tmp_keyring) ; + + _pubring_changed = true ; + + return true ; +} + +bool OpenPGPSDKHandler::locked_addOrMergeKey(ops_keyring_t *keyring,std::map& kmap,const ops_keydata_t *keydata) +{ + bool ret = false ; + RsPgpId id(keydata->key_id) ; + +#ifdef DEBUG_PGPHANDLER + std::cerr << "AddOrMergeKey():" << std::endl; + std::cerr << " id: " << id.toStdString() << std::endl; +#endif + + // See if the key is already in the keyring + const ops_keydata_t *existing_key = NULL; + std::map::const_iterator res = kmap.find(id) ; + + // Checks that + // - the key is referenced by keyid + // - the map is initialized + // - the fingerprint matches! + // + if(res == kmap.end() || (existing_key = ops_keyring_get_key_by_index(keyring,res->second._key_index)) == NULL) + { +#ifdef DEBUG_PGPHANDLER + std::cerr << " Key is new. Adding it to keyring" << std::endl; +#endif + addNewKeyToOPSKeyring(keyring,*keydata) ; // the key is new. + initCertificateInfo(kmap[id],keydata,keyring->nkeys-1) ; + existing_key = &(keyring->keys[keyring->nkeys-1]) ; + ret = true ; + } + else + { + if(memcmp( existing_key->fingerprint.fingerprint, + keydata->fingerprint.fingerprint, + RsPgpFingerprint::SIZE_IN_BYTES )) + { + std::cerr << "(EE) attempt to merge key with identical id, but different fingerprint!" << std::endl; + return false ; + } + +#ifdef DEBUG_PGPHANDLER + std::cerr << " Key exists. Merging signatures." << std::endl; +#endif + ret = mergeKeySignatures(const_cast(existing_key),keydata) ; + + if(ret) + initCertificateInfo(kmap[id],existing_key,res->second._key_index) ; + } + + if(ret) + { + validateAndUpdateSignatures(kmap[id],existing_key) ; + kmap[id]._time_stamp = time(NULL) ; + } + + return ret ; +} + +bool OpenPGPSDKHandler::encryptTextToFile(const RsPgpId& key_id,const std::string& text,const std::string& outfile) +{ + RsStackMutex mtx(pgphandlerMtx) ; // lock access to PGP memory structures. + + const ops_keydata_t *public_key = locked_getPublicKey(key_id,true) ; + + if(public_key == NULL) + { + std::cerr << "Cannot get public key of id " << key_id.toStdString() << std::endl; + return false ; + } + + if(public_key->type != OPS_PTAG_CT_PUBLIC_KEY) + { + std::cerr << "OpenPGPSDKHandler::encryptTextToFile(): ERROR: supplied id did not return a public key!" << std::endl; + return false ; + } + + std::string outfile_tmp = outfile + ".tmp" ; + + ops_create_info_t *info; + int fd = ops_setup_file_write(&info, outfile_tmp.c_str(), ops_true); + + if (fd < 0) + { + std::cerr << "OpenPGPSDKHandler::encryptTextToFile(): ERROR: Cannot write to " << outfile_tmp << std::endl; + return false ; + } + + if(!ops_encrypt_stream(info, public_key, NULL, ops_false, ops_true)) + { + std::cerr << "OpenPGPSDKHandler::encryptTextToFile(): ERROR: encryption failed." << std::endl; + return false ; + } + + ops_write(text.c_str(), text.length(), info); + ops_teardown_file_write(info, fd); + + if(!RsDirUtil::renameFile(outfile_tmp,outfile)) + { + std::cerr << "OpenPGPSDKHandler::encryptTextToFile(): ERROR: Cannot rename " + outfile_tmp + " to " + outfile + ". Disk error?" << std::endl; + return false ; + } + + return true ; +} + +bool OpenPGPSDKHandler::encryptDataBin(const RsPgpId& key_id,const void *data, const uint32_t len, unsigned char *encrypted_data, unsigned int *encrypted_data_len) +{ + RsStackMutex mtx(pgphandlerMtx) ; // lock access to PGP memory structures. + + const ops_keydata_t *public_key = locked_getPublicKey(key_id,true) ; + + if(public_key == NULL) + { + std::cerr << "Cannot get public key of id " << key_id.toStdString() << std::endl; + return false ; + } + + if(public_key->type != OPS_PTAG_CT_PUBLIC_KEY) + { + std::cerr << "OpenPGPSDKHandler::encryptTextToFile(): ERROR: supplied id did not return a public key!" << std::endl; + return false ; + } + if(public_key->key.pkey.algorithm != OPS_PKA_RSA) + { + std::cerr << "OpenPGPSDKHandler::encryptTextToFile(): ERROR: supplied key id " << key_id.toStdString() << " is not an RSA key (DSA for instance, is not supported)!" << std::endl; + return false ; + } + ops_create_info_t *info; + ops_memory_t *buf = NULL ; + ops_setup_memory_write(&info, &buf, 0); + bool res = true; + + if(!ops_encrypt_stream(info, public_key, NULL, ops_false, ops_false)) + { + std::cerr << "Encryption failed." << std::endl; + res = false ; + } + + ops_write(data,len,info); + ops_writer_close(info); + ops_create_info_delete(info); + + int tlen = ops_memory_get_length(buf) ; + + if( (int)*encrypted_data_len >= tlen) + { + if(res) + { + memcpy(encrypted_data,ops_memory_get_data(buf),tlen) ; + *encrypted_data_len = tlen ; + res = true ; + } + } + else + { + std::cerr << "Not enough room to fit encrypted data. Size given=" << *encrypted_data_len << ", required=" << tlen << std::endl; + res = false ; + } + + ops_memory_release(buf) ; + free(buf) ; + + return res ; +} + +bool OpenPGPSDKHandler::decryptDataBin(const RsPgpId& /*key_id*/,const void *encrypted_data, const uint32_t encrypted_len, unsigned char *data, unsigned int *data_len) +{ + int out_length ; + unsigned char *out ; + ops_boolean_t res = ops_decrypt_memory((const unsigned char *)encrypted_data,encrypted_len,&out,&out_length,_secring,ops_false,cb_get_passphrase) ; + + if(*data_len < (unsigned int)out_length) + { + std::cerr << "Not enough room to store decrypted data! Please give more."<< std::endl; + return false ; + } + + *data_len = (unsigned int)out_length ; + memcpy(data,out,out_length) ; + free(out) ; + + return (bool)res ; +} + +bool OpenPGPSDKHandler::decryptTextFromFile(const RsPgpId&,std::string& text,const std::string& inputfile) +{ + RsStackMutex mtx(pgphandlerMtx) ; // lock access to PGP memory structures. + + unsigned char *out_buf = NULL ; + std::string buf ; + + FILE *f = RsDirUtil::rs_fopen(inputfile.c_str(),"rb") ; + + if (f == NULL) + { + std::cerr << "Cannot open file " << inputfile << " for read." << std::endl; + return false; + } + + int c ; + while( (c = fgetc(f))!= EOF) + buf += (unsigned char)c; + + fclose(f) ; + +#ifdef DEBUG_PGPHANDLER + std::cerr << "OpenPGPSDKHandler::decryptTextFromFile: read a file of length " << std::dec << buf.length() << std::endl; + std::cerr << "buf=\"" << buf << "\"" << std::endl; +#endif + + int out_length ; + ops_boolean_t res = ops_decrypt_memory((const unsigned char *)buf.c_str(),buf.length(),&out_buf,&out_length,_secring,ops_true,cb_get_passphrase) ; + + text = std::string((char *)out_buf,out_length) ; + free (out_buf); + return (bool)res ; +} + +bool OpenPGPSDKHandler::SignDataBin(const RsPgpId& id,const void *data, const uint32_t len, unsigned char *sign, unsigned int *signlen,bool use_raw_signature, std::string reason /* = "" */) +{ + RsStackMutex mtx(pgphandlerMtx) ; // lock access to PGP memory structures. + // need to find the key and to decrypt it. + + const ops_keydata_t *key = locked_getSecretKey(id) ; + + if(!key) + { + std::cerr << "Cannot sign: no secret key with id " << id.toStdString() << std::endl; + return false ; + } + + std::string uid_hint ; + if(key->nuids > 0) + uid_hint = std::string((const char *)key->uids[0].user_id) ; + uid_hint += "(" + RsPgpId(key->key_id).toStdString()+")" ; + +#ifdef DEBUG_PGPHANDLER + ops_fingerprint_t f ; + ops_fingerprint(&f,&key->key.pkey) ; + + PGPFingerprintType fp(f.fingerprint) ; +#endif + + bool last_passwd_was_wrong = false ; +ops_secret_key_t *secret_key = NULL ; + + for(int i=0;i<3;++i) + { + bool cancelled =false; + std::string passphrase = _passphrase_callback(NULL,reason.c_str(),uid_hint.c_str(),"Please enter passwd for encrypting your key : ",last_passwd_was_wrong,&cancelled) ;//TODO reason + + secret_key = ops_decrypt_secret_key_from_data(key,passphrase.c_str()) ; + + if(cancelled) + { + std::cerr << "Key entering cancelled" << std::endl; + return false ; + } + if(secret_key) + break ; + + std::cerr << "Key decryption went wrong. Wrong passwd?" << std::endl; + last_passwd_was_wrong = true ; + } + if(!secret_key) + { + std::cerr << "Could not obtain secret key. Signature cancelled." << std::endl; + return false ; + } + + // then do the signature. + + ops_boolean_t not_raw = !use_raw_signature ; +#ifdef V07_NON_BACKWARD_COMPATIBLE_CHANGE_002 + ops_memory_t *memres = ops_sign_buf(data,len,OPS_SIG_BINARY,OPS_HASH_SHA256,secret_key,ops_false,ops_false,not_raw,not_raw) ; +#else + ops_memory_t *memres = ops_sign_buf(data,len,OPS_SIG_BINARY,OPS_HASH_SHA1,secret_key,ops_false,ops_false,not_raw,not_raw) ; +#endif + + if(!memres) + return false ; + + bool res ; + uint32_t slen = (uint32_t)ops_memory_get_length(memres); + + if(*signlen >= slen) + { + *signlen = slen ; + + memcpy(sign,ops_memory_get_data(memres),*signlen) ; + res = true ; + } + else + { + std::cerr << "(EE) memory chunk is not large enough for signature packet. Requred size: " << slen << " bytes." << std::endl; + res = false ; + } + + ops_memory_release(memres) ; + free(memres) ; + ops_secret_key_free(secret_key) ; + free(secret_key) ; + +#ifdef DEBUG_PGPHANDLER + std::cerr << "Signed with fingerprint " << fp.toStdString() << ", length " << std::dec << *signlen << ", literal data length = " << len << std::endl; + std::cerr << "Signature body: " << std::endl; + hexdump( (unsigned char *)data, len) ; + std::cerr << std::endl; + std::cerr << "Data: " << std::endl; + hexdump( (unsigned char *)sign,*signlen) ; + std::cerr << std::endl; +#endif + return res ; +} + +bool OpenPGPSDKHandler::privateSignCertificate(const RsPgpId& ownId,const RsPgpId& id_of_key_to_sign) +{ + RsStackMutex mtx(pgphandlerMtx) ; // lock access to PGP memory structures. + + ops_keydata_t *key_to_sign = const_cast(locked_getPublicKey(id_of_key_to_sign,true)) ; + + if(key_to_sign == NULL) + { + std::cerr << "Cannot sign: no public key with id " << id_of_key_to_sign.toStdString() << std::endl; + return false ; + } + + // 1 - get decrypted secret key + // + const ops_keydata_t *skey = locked_getSecretKey(ownId) ; + + if(!skey) + { + std::cerr << "Cannot sign: no secret key with id " << ownId.toStdString() << std::endl; + return false ; + } + const ops_keydata_t *pkey = locked_getPublicKey(ownId,true) ; + + if(!pkey) + { + std::cerr << "Cannot sign: no public key with id " << ownId.toStdString() << std::endl; + return false ; + } + + bool cancelled = false; + std::string passphrase = _passphrase_callback(NULL,"",RsPgpId(skey->key_id).toStdString().c_str(),"Please enter passwd for encrypting your key : ",false,&cancelled) ; + + ops_secret_key_t *secret_key = ops_decrypt_secret_key_from_data(skey,passphrase.c_str()) ; + + if(cancelled) + { + std::cerr << "Key cancelled by used." << std::endl; + return false ; + } + if(!secret_key) + { + std::cerr << "Key decryption went wrong. Wrong passwd?" << std::endl; + return false ; + } + + // 2 - then do the signature. + + if(!ops_sign_key(key_to_sign,pkey->key_id,secret_key)) + { + std::cerr << "Key signature went wrong. Wrong passwd?" << std::endl; + return false ; + } + + // 3 - free memory + // + ops_secret_key_free(secret_key) ; + free(secret_key) ; + + _pubring_changed = true ; + + // 4 - update signatures. + // + PGPCertificateInfo& cert(_public_keyring_map[ id_of_key_to_sign ]) ; + validateAndUpdateSignatures(cert,key_to_sign) ; + cert._flags |= PGPCertificateInfo::PGP_CERTIFICATE_FLAG_HAS_OWN_SIGNATURE ; + + return true ; +} + +bool OpenPGPSDKHandler::getKeyFingerprint(const RsPgpId& id, RsPgpFingerprint& fp) const +{ + RS_STACK_MUTEX(pgphandlerMtx); + + const ops_keydata_t *key = locked_getPublicKey(id,false) ; + + if(!key) return false; + + ops_fingerprint_t f ; + ops_fingerprint(&f,&key->key.pkey) ; + + fp = RsPgpFingerprint::fromBufferUnsafe(f.fingerprint); + + return true ; +} + +bool OpenPGPSDKHandler::VerifySignBin(const void *literal_data, uint32_t literal_data_length, unsigned char *sign, unsigned int sign_len, const PGPFingerprintType& key_fingerprint) +{ + RsStackMutex mtx(pgphandlerMtx) ; // lock access to PGP memory structures. + + RsPgpId id = RsPgpId(key_fingerprint.toByteArray() + PGPFingerprintType::SIZE_IN_BYTES - RsPgpId::SIZE_IN_BYTES) ; + const ops_keydata_t *key = locked_getPublicKey(id,true) ; + + if(key == NULL) + { + std::cerr << "No key returned by fingerprint " << key_fingerprint.toStdString() << ", and ID " << id.toStdString() << ", signature verification failed!" << std::endl; + return false ; + } + + // Check that fingerprint is the same. + const ops_public_key_t *pkey = &key->key.pkey ; + ops_fingerprint_t fp ; + ops_fingerprint(&fp,pkey) ; + + if(key_fingerprint != PGPFingerprintType(fp.fingerprint)) + { + std::cerr << "Key fingerprint does not match " << key_fingerprint.toStdString() << ", for ID " << id.toStdString() << ", signature verification failed!" << std::endl; + return false ; + } + +#ifdef DEBUG_PGPHANDLER + std::cerr << "Verifying signature from fingerprint " << key_fingerprint.toStdString() << ", length " << std::dec << sign_len << ", literal data length = " << literal_data_length << std::endl; + std::cerr << "Signature body: " << std::endl; + hexdump( (unsigned char *)sign,sign_len) ; + std::cerr << std::endl; + std::cerr << "Signed data: " << std::endl; + hexdump( (unsigned char *)literal_data, literal_data_length) ; + std::cerr << std::endl; +#endif + + return ops_validate_detached_signature(literal_data,literal_data_length,sign,sign_len,key) ; +} + +// Lexicographic order on signature packets +// +bool operator<(const ops_packet_t& p1,const ops_packet_t& p2) +{ + if(p1.length < p2.length) + return true ; + if(p1.length > p2.length) + return false ; + + for(uint32_t i=0;i p2.raw[i]) + return false ; + } + return false ; +} + +bool OpenPGPSDKHandler::mergeKeySignatures(ops_keydata_t *dst,const ops_keydata_t *src) +{ + // First sort all signatures into lists to see which is new, which is not new + +#ifdef DEBUG_PGPHANDLER + std::cerr << "Merging signatures for key " << RsPgpId(dst->key_id).toStdString() << std::endl; +#endif + std::set dst_packets ; + + for(uint32_t i=0;inpackets;++i) dst_packets.insert(dst->packets[i]) ; + + std::set to_add ; + + for(uint32_t i=0;inpackets;++i) + if(dst_packets.find(src->packets[i]) == dst_packets.end()) + { + uint8_t tag ; + uint32_t length ; + unsigned char *tmp_data = src->packets[i].raw ; // put it in a tmp variable because read_packetHeader() will modify it!! + + PGPKeyParser::read_packetHeader(tmp_data,tag,length) ; + + if(tag == PGPKeyParser::PGP_PACKET_TAG_SIGNATURE) + to_add.insert(src->packets[i]) ; +#ifdef DEBUG_PGPHANDLER + else + std::cerr << " Packet with tag 0x" << std::hex << (int)(src->packets[i].raw[0]) << std::dec << " not merged, because it is not a signature." << std::endl; +#endif + } + + for(std::set::const_iterator it(to_add.begin());it!=to_add.end();++it) + { +#ifdef DEBUG_PGPHANDLER + std::cerr << " Adding packet with tag 0x" << std::hex << (int)(*it).raw[0] << std::dec << std::endl; +#endif + ops_add_packet_to_keydata(dst,&*it) ; + } + return to_add.size() > 0 ; +} + +bool OpenPGPSDKHandler::syncDatabase() +{ + RsStackMutex mtx(pgphandlerMtx) ; // lock access to PGP memory structures. + RsStackFileLock flck(_pgp_lock_filename) ; // lock access to PGP directory. + +#ifdef DEBUG_PGPHANDLER + std::cerr << "Sync-ing keyrings." << std::endl; +#endif + locked_syncPublicKeyring() ; + //locked_syncSecretKeyring() ; + + // Now sync the trust database as well. + // + locked_syncTrustDatabase() ; + +#ifdef DEBUG_PGPHANDLER + std::cerr << "Done. " << std::endl; +#endif + return true ; +} + +bool OpenPGPSDKHandler::locked_syncPublicKeyring() +{ + struct stat64 buf ; +#ifdef WINDOWS_SYS + std::wstring wfullname; + librs::util::ConvertUtf8ToUtf16(_pubring_path, wfullname); + if(-1 == _wstati64(wfullname.c_str(), &buf)) +#else + if(-1 == stat64(_pubring_path.c_str(), &buf)) +#endif + std::cerr << "OpenPGPSDKHandler::syncDatabase(): can't stat file " << _pubring_path << ". Can't sync public keyring." << std::endl; + + if(_pubring_last_update_time < buf.st_mtime) + { + std::cerr << "Detected change on disk of public keyring. Merging!" << std::endl ; + + locked_mergeKeyringFromDisk(_pubring,_public_keyring_map,_pubring_path) ; + _pubring_last_update_time = buf.st_mtime ; + } + + // Now check if the pubring was locally modified, which needs saving it again + if(_pubring_changed && RsDiscSpace::checkForDiscSpace(RS_PGP_DIRECTORY)) + { + std::string tmp_keyring_file = _pubring_path + ".tmp" ; + + std::cerr << "Local changes in public keyring. Writing to disk..." << std::endl; + if(!ops_write_keyring_to_file(_pubring,ops_false,tmp_keyring_file.c_str(),ops_true)) + { + std::cerr << "Cannot write public keyring tmp file. Disk full? Disk quota exceeded?" << std::endl; + return false ; + } + if(!RsDirUtil::renameFile(tmp_keyring_file,_pubring_path)) + { + std::cerr << "Cannot rename tmp pubring file " << tmp_keyring_file << " into actual pubring file " << _pubring_path << ". Check writing permissions?!?" << std::endl; + return false ; + } + + std::cerr << "Done." << std::endl; + _pubring_last_update_time = time(NULL) ; // should we get this value from the disk instead?? + _pubring_changed = false ; + } + return true ; +} + +void OpenPGPSDKHandler::locked_mergeKeyringFromDisk(ops_keyring_t *keyring, + std::map& kmap, + const std::string& keyring_file) +{ +#ifdef DEBUG_PGPHANDLER + std::cerr << "Merging keyring " << keyring_file << " from disk to memory." << std::endl; +#endif + + // 1 - load keyring into a temporary keyring list. + ops_keyring_t *tmp_keyring = OpenPGPSDKHandler::allocateOPSKeyring() ; + + if(ops_false == ops_keyring_read_from_file(tmp_keyring, false, keyring_file.c_str())) + { + std::cerr << "OpenPGPSDKHandler::locked_mergeKeyringFromDisk(): cannot read keyring. File corrupted?" ; + ops_keyring_free(tmp_keyring) ; + return ; + } + + // 2 - load new keys and merge existing key signatures + + for(int i=0;inkeys;++i) + locked_addOrMergeKey(keyring,kmap,&tmp_keyring->keys[i]) ;// we dont' account for the return value. This is disk merging, not local changes. + + // 4 - clean + ops_keyring_free(tmp_keyring) ; +} + +bool OpenPGPSDKHandler::removeKeysFromPGPKeyring(const std::set& keys_to_remove,std::string& backup_file,uint32_t& error_code) +{ + // 1 - lock everything. + // + RsStackMutex mtx(pgphandlerMtx) ; // lock access to PGP memory structures. + RsStackFileLock flck(_pgp_lock_filename) ; // lock access to PGP directory. + + error_code = PGP_KEYRING_REMOVAL_ERROR_NO_ERROR ; + + for(std::set::const_iterator it(keys_to_remove.begin());it!=keys_to_remove.end();++it) + if(locked_getSecretKey(*it) != NULL) + { + std::cerr << "(EE) OpenPGPSDKHandler:: can't remove key " << (*it).toStdString() << " since its shared by a secret key! Operation cancelled." << std::endl; + error_code = PGP_KEYRING_REMOVAL_ERROR_CANT_REMOVE_SECRET_KEYS ; + return false ; + } + + // 2 - sync everything. + // + locked_syncPublicKeyring() ; + + // 3 - make a backup of the public keyring + // + char template_name[_pubring_path.length()+8] ; + sprintf(template_name,"%s.XXXXXX",_pubring_path.c_str()) ; + +#if defined __USE_XOPEN_EXTENDED || defined __USE_XOPEN2K8 + int fd_keyring_backup(mkstemp(template_name)); + if (fd_keyring_backup == -1) +#else + if(mktemp(template_name) == NULL) +#endif + { + std::cerr << "OpenPGPSDKHandler::removeKeysFromPGPKeyring(): cannot create keyring backup file. Giving up." << std::endl; + error_code = PGP_KEYRING_REMOVAL_ERROR_CANNOT_CREATE_BACKUP ; + return false ; + } +#if defined __USE_XOPEN_EXTENDED || defined __USE_XOPEN2K8 + close(fd_keyring_backup); // TODO: keep the file open and use the fd +#endif + + if(!ops_write_keyring_to_file(_pubring,ops_false,template_name,ops_true)) + { + std::cerr << "OpenPGPSDKHandler::removeKeysFromPGPKeyring(): cannot write keyring backup file. Giving up." << std::endl; + error_code = PGP_KEYRING_REMOVAL_ERROR_CANNOT_WRITE_BACKUP ; + return false ; + } + backup_file = std::string(template_name,_pubring_path.length()+7) ; + + std::cerr << "Keyring was backed up to file " << backup_file << std::endl; + + // Remove keys from the keyring, and update the keyring map. + // + for(std::set::const_iterator it(keys_to_remove.begin());it!=keys_to_remove.end();++it) + { + if(locked_getSecretKey(*it) != NULL) + { + std::cerr << "(EE) OpenPGPSDKHandler:: can't remove key " << (*it).toStdString() << " since its shared by a secret key!" << std::endl; + continue ; + } + + std::map::iterator res = _public_keyring_map.find(*it) ; + + if(res == _public_keyring_map.end()) + { + std::cerr << "(EE) OpenPGPSDKHandler:: can't remove key " << (*it).toStdString() << " from keyring: key not found." << std::endl; + continue ; + } + + if(res->second._key_index >= (unsigned int)_pubring->nkeys || RsPgpId(_pubring->keys[res->second._key_index].key_id) != *it) + { + std::cerr << "(EE) OpenPGPSDKHandler:: can't remove key " << (*it).toStdString() << ". Inconsistency found." << std::endl; + error_code = PGP_KEYRING_REMOVAL_ERROR_DATA_INCONSISTENCY ; + return false ; + } + + // Move the last key to the freed place. This deletes the key in place. + // + ops_keyring_remove_key(_pubring,res->second._key_index) ; + + // Erase the info from the keyring map. + // + _public_keyring_map.erase(res) ; + + // now update all indices back. This internal look is very costly, but it avoids deleting the wrong keys, since the keyring structure is + // changed by ops_keyring_remove_key and therefore indices don't point to the correct location anymore. + + int i=0 ; + const ops_keydata_t *keydata ; + while( (keydata = ops_keyring_get_key_by_index(_pubring,i)) != NULL ) + { + PGPCertificateInfo& cert(_public_keyring_map[ RsPgpId(keydata->key_id) ]) ; + cert._key_index = i ; + ++i ; + } + } + + // Everything went well, sync back the keyring on disk + + _pubring_changed = true ; + _trustdb_changed = true ; + + locked_syncPublicKeyring() ; + locked_syncTrustDatabase() ; + + return true ; +} diff --git a/libretroshare/src/pgp/openpgpsdkhandler.h b/libretroshare/src/pgp/openpgpsdkhandler.h new file mode 100644 index 000000000..e6c06ba84 --- /dev/null +++ b/libretroshare/src/pgp/openpgpsdkhandler.h @@ -0,0 +1,116 @@ +/******************************************************************************* + * libretroshare/src/pgp: pgphandler.h * + * * + * libretroshare: retroshare core library * + * * + * Copyright 2018 Cyril Soler * + * * + * 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 + +#include +#include +#include +#include +#include + +#include "util/rsthreads.h" +#include "pgp/pgphandler.h" +#include "retroshare/rstypes.h" + +extern "C" { + // we should make sure later on to get rid of these structures in the .h + #include "openpgpsdk/keyring.h" +} + +/// This class offer an abstract pgp handler to be used in RetroShare. +class OpenPGPSDKHandler: public PGPHandler +{ +public: + OpenPGPSDKHandler( const std::string& path_to_public_keyring, + const std::string& path_to_secret_keyring, + const std::string& path_to_trust_database, + const std::string& pgp_lock_file) ; + + virtual ~OpenPGPSDKHandler() ; + + //================================================================================================// + // Implemented API from PGPHandler // + //================================================================================================// + + virtual std::string makeRadixEncodedPGPKey(uint32_t key_index,bool include_signatures) override; + virtual bool removeKeysFromPGPKeyring(const std::set& key_ids,std::string& backup_file,uint32_t& error_code) override; + virtual bool availableGPGCertificatesWithPrivateKeys(std::list& ids) override; + virtual bool GeneratePGPCertificate(const std::string& name, const std::string& email, const std::string& passphrase, RsPgpId& pgpId, const int keynumbits, std::string& errString) override; + + virtual std::string SaveCertificateToString(const RsPgpId& id,bool include_signatures) const override; + virtual bool exportPublicKey( const RsPgpId& id, unsigned char*& mem_block, size_t& mem_size, bool armoured, bool include_signatures ) const override; + + virtual bool exportGPGKeyPair(const std::string& filename,const RsPgpId& exported_key_id) const override; + virtual bool exportGPGKeyPairToString( std::string& data, const RsPgpId& exportedKeyId, bool includeSignatures, std::string& errorMsg ) const override; + virtual bool getGPGDetailsFromBinaryBlock(const unsigned char *mem_block,size_t mem_size,RsPgpId& key_id, std::string& name, std::list& signers) const override; + virtual bool importGPGKeyPair(const std::string& filename,RsPgpId& imported_key_id,std::string& import_error) override; + virtual bool importGPGKeyPairFromString(const std::string &data, RsPgpId &imported_key_id, std::string &import_error) override; + virtual bool LoadCertificateFromBinaryData(const unsigned char *data,uint32_t data_len,RsPgpId& id,std::string& error_string) override; + virtual bool LoadCertificateFromString(const std::string& pgp_cert,RsPgpId& id,std::string& error_string) override; + virtual bool encryptTextToFile(const RsPgpId& key_id,const std::string& text,const std::string& outfile) override; + virtual bool encryptDataBin(const RsPgpId& key_id,const void *data, const uint32_t len, unsigned char *encrypted_data, unsigned int *encrypted_data_len) override; + virtual bool decryptDataBin(const RsPgpId& /*key_id*/,const void *encrypted_data, const uint32_t encrypted_len, unsigned char *data, unsigned int *data_len) override; + virtual bool decryptTextFromFile(const RsPgpId&,std::string& text,const std::string& inputfile) override; + virtual bool SignDataBin(const RsPgpId& id,const void *data, const uint32_t len, unsigned char *sign, unsigned int *signlen,bool use_raw_signature, std::string reason /* = "" */) override; + virtual bool privateSignCertificate(const RsPgpId& ownId,const RsPgpId& id_of_key_to_sign) override; + virtual bool VerifySignBin(const void *literal_data, uint32_t literal_data_length, unsigned char *sign, unsigned int sign_len, const PGPFingerprintType& key_fingerprint) override; + virtual bool getKeyFingerprint(const RsPgpId& id, RsPgpFingerprint& fp) const override; + virtual bool haveSecretKey(const RsPgpId& id) const override; + virtual bool syncDatabase() override; + private: + bool locked_syncPublicKeyring() ; + + void initCertificateInfo(PGPCertificateInfo& cert,const ops_keydata_t *keydata,uint32_t i) ; + bool LoadCertificate(const unsigned char *data,uint32_t data_len,bool armoured,RsPgpId& id,std::string& error_string) ; + + // Returns true if the signatures have been updated + // + bool validateAndUpdateSignatures(PGPCertificateInfo& cert,const ops_keydata_t *keydata) ; + + /** Check public/private key and import them into the keyring + * @param keyring keyring with the new public/private key pair. Will be freed by the function. + * @param imported_key_id PGP id of the imported key + * @param import_error human readbale error message + * @returns true on success + * */ + bool checkAndImportKeyPair(ops_keyring_t *keyring, RsPgpId& imported_key_id,std::string& import_error); + + const ops_keydata_t *locked_getPublicKey(const RsPgpId&,bool stamp_the_key) const; + const ops_keydata_t *locked_getSecretKey(const RsPgpId&) const ; + + void locked_mergeKeyringFromDisk(ops_keyring_t *keyring, std::map& kmap, const std::string& keyring_file) ; + bool locked_addOrMergeKey(ops_keyring_t *keyring,std::map& kmap,const ops_keydata_t *keydata) ; + + // Members. + // + ops_keyring_t *_pubring ; + ops_keyring_t *_secring ; + + void printOPSKeys() const; + + // Helper functions. + // + static std::string makeRadixEncodedPGPKey(const ops_keydata_t *key,bool include_signatures) ; + static ops_keyring_t *allocateOPSKeyring() ; + static void addNewKeyToOPSKeyring(ops_keyring_t*, const ops_keydata_t&) ; + static bool mergeKeySignatures(ops_keydata_t *dst,const ops_keydata_t *src) ; // returns true if signature lists are different +}; From b084b20280665fcfe1d16beed2c2704f4c194019 Mon Sep 17 00:00:00 2001 From: csoler Date: Sat, 14 Aug 2021 14:56:28 +0200 Subject: [PATCH 015/113] removed getAuthGPG and replaced AuthGPG with a class with static members --- .../src/gossipdiscovery/p3gossipdiscovery.cc | 20 +- libretroshare/src/pgp/pgpauxutils.cc | 10 +- libretroshare/src/pqi/authgpg.cc | 186 +++++++++++------- libretroshare/src/pqi/authgpg.h | 115 ++++++----- libretroshare/src/pqi/authssl.cc | 15 +- libretroshare/src/pqi/p3peermgr.cc | 20 +- libretroshare/src/pqi/pqissl.cc | 3 +- libretroshare/src/pqi/pqissllistener.cc | 3 +- libretroshare/src/rsserver/p3peers.cc | 61 +++--- libretroshare/src/rsserver/p3serverconfig.cc | 2 +- libretroshare/src/rsserver/rsaccounts.cc | 29 +-- libretroshare/src/rsserver/rsinit.cc | 11 +- libretroshare/src/rsserver/rsloginhandler.cc | 5 +- libretroshare/src/services/p3idservice.cc | 4 +- 14 files changed, 266 insertions(+), 218 deletions(-) diff --git a/libretroshare/src/gossipdiscovery/p3gossipdiscovery.cc b/libretroshare/src/gossipdiscovery/p3gossipdiscovery.cc index 732967f44..179a845d7 100644 --- a/libretroshare/src/gossipdiscovery/p3gossipdiscovery.cc +++ b/libretroshare/src/gossipdiscovery/p3gossipdiscovery.cc @@ -107,7 +107,7 @@ p3discovery2::p3discovery2( addSerialType(new RsDiscSerialiser()); // Add self into PGP FriendList. - mFriendList[AuthGPG::getAuthGPG()->getGPGOwnId()] = DiscPgpInfo(); + mFriendList[AuthGPG::getGPGOwnId()] = DiscPgpInfo(); } @@ -219,7 +219,7 @@ void p3discovery2::removeFriend(const RsPeerId &sslId) std::cerr << std::endl; #endif /* pgp peer without any ssl entries -> check if they are still a real friend */ - if (!(AuthGPG::getAuthGPG()->isGPGAccepted(pgpId))) + if (!(AuthGPG::isGPGAccepted(pgpId))) { #ifdef P3DISC_DEBUG std::cerr << "p3discovery2::addFriend() pgpId is no longer a friend, removing"; @@ -604,8 +604,8 @@ void p3discovery2::updatePgpFriendList() std::list::iterator lit; std::map::iterator it; - RsPgpId ownPgpId = AuthGPG::getAuthGPG()->getGPGOwnId(); - AuthGPG::getAuthGPG()->getGPGAcceptedList(pgpList); + RsPgpId ownPgpId = AuthGPG::getGPGOwnId(); + AuthGPG::getGPGAcceptedList(pgpList); pgpList.push_back(ownPgpId); // convert to set for ordering. @@ -723,7 +723,7 @@ void p3discovery2::processPGPList(const RsPeerId &fromId, const RsDiscPgpListIte std::set::const_iterator fit; for(fit = item->pgpIdSet.ids.begin(); fit != item->pgpIdSet.ids.end(); ++fit) { - if (!AuthGPG::getAuthGPG()->isGPGId(*fit)) + if (!AuthGPG::isPGPId(*fit)) { #ifdef P3DISC_DEBUG std::cerr << "p3discovery2::processPGPList() requesting certificate for PgpId: " << *fit; @@ -1058,11 +1058,11 @@ void p3discovery2::recvPGPCertificateRequest( const RsPeerId& fromId, const RsDi return; } - RsPgpId ownPgpId = AuthGPG::getAuthGPG()->getGPGOwnId(); + RsPgpId ownPgpId = AuthGPG::getGPGOwnId(); for(const RsPgpId& pgpId : item->pgpIdSet.ids) if (pgpId == ownPgpId) sendPGPCertificate(pgpId, fromId); - else if(ps.vs_disc != RS_VS_DISC_OFF && AuthGPG::getAuthGPG()->isGPGAccepted(pgpId)) + else if(ps.vs_disc != RS_VS_DISC_OFF && AuthGPG::isGPGAccepted(pgpId)) sendPGPCertificate(pgpId, fromId); else std::cerr << "(WW) not sending certificate " << pgpId << " asked by friend " << fromId << " because this either this cert is not a friend, or discovery is off" << std::endl; @@ -1078,7 +1078,7 @@ void p3discovery2::sendPGPCertificate(const RsPgpId &aboutId, const RsPeerId &to unsigned char *bin_data; size_t bin_len; - if(!AuthGPG::getAuthGPG()->exportPublicKey(aboutId,bin_data,bin_len,false,true)) + if(!AuthGPG::exportPublicKey(aboutId,bin_data,bin_len,false,true)) { std::cerr << "(EE) cannot export public key " << aboutId << " requested by peer " << toId << std::endl; return ; @@ -1098,7 +1098,7 @@ void p3discovery2::recvPGPCertificate(const RsPeerId& fromId, RsDiscPgpKeyItem* std::string cert_name; std::list cert_signers; - if(!AuthGPG::getAuthGPG()->getGPGDetailsFromBinaryBlock( (unsigned char*)item->bin_data,item->bin_len, cert_pgp_id, cert_name, cert_signers )) + if(!AuthGPG::getGPGDetailsFromBinaryBlock( (unsigned char*)item->bin_data,item->bin_len, cert_pgp_id, cert_name, cert_signers )) { std::cerr << "(EE) cannot parse own PGP key sent by " << fromId << std::endl; return; @@ -1147,7 +1147,7 @@ void p3discovery2::recvPGPCertificate(const RsPeerId& fromId, RsDiscPgpKeyItem* // otherwise the connection should already be accepted. This only happens when the short invite peer sends its own PGP key. if(det.skip_pgp_signature_validation) - AuthGPG::getAuthGPG()->AllowConnection(det.gpg_id,true); + AuthGPG::AllowConnection(det.gpg_id,true); } /************* from pqiServiceMonitor *******************/ diff --git a/libretroshare/src/pgp/pgpauxutils.cc b/libretroshare/src/pgp/pgpauxutils.cc index d7229e848..a9c3b36f6 100644 --- a/libretroshare/src/pgp/pgpauxutils.cc +++ b/libretroshare/src/pgp/pgpauxutils.cc @@ -34,7 +34,7 @@ PgpAuxUtilsImpl::PgpAuxUtilsImpl() const RsPgpId& PgpAuxUtilsImpl::getPGPOwnId() { - return AuthGPG::getAuthGPG()->getGPGOwnId(); + return AuthGPG::getGPGOwnId(); } RsPgpId PgpAuxUtilsImpl::getPGPId(const RsPeerId& sslid) @@ -44,7 +44,7 @@ RsPgpId PgpAuxUtilsImpl::getPGPId(const RsPeerId& sslid) bool PgpAuxUtilsImpl::getKeyFingerprint(const RsPgpId& id,PGPFingerprintType& fp) const { - return AuthGPG::getAuthGPG()->getKeyFingerprint(id, fp); + return AuthGPG::getKeyFingerprint(id, fp); } bool PgpAuxUtilsImpl::VerifySignBin(const void *data, @@ -54,17 +54,17 @@ bool PgpAuxUtilsImpl::VerifySignBin(const void *data, const PGPFingerprintType& withfingerprint) { - return AuthGPG::getAuthGPG()->VerifySignBin(data, len, sign, signlen, withfingerprint); + return AuthGPG::VerifySignBin(data, len, sign, signlen, withfingerprint); } bool PgpAuxUtilsImpl::getGPGAllList(std::list &ids) { - return AuthGPG::getAuthGPG()->getGPGAllList(ids); + return AuthGPG::getGPGAllList(ids); } bool PgpAuxUtilsImpl::parseSignature(unsigned char *sign, unsigned int signlen, RsPgpId& issuer) const { - return AuthGPG::getAuthGPG()->parseSignature(sign,signlen,issuer); + return AuthGPG::parseSignature(sign,signlen,issuer); } diff --git a/libretroshare/src/pqi/authgpg.cc b/libretroshare/src/pqi/authgpg.cc index 2d29fbb65..b870b5d1e 100644 --- a/libretroshare/src/pqi/authgpg.cc +++ b/libretroshare/src/pqi/authgpg.cc @@ -54,9 +54,21 @@ void cleanupZombies(int numkill); // function to cleanup zombies under OSX. /* Function to sign X509_REQ via GPGme. */ +int AuthGPG::availableGPGCertificatesWithPrivateKeys(std::list& pgpIds) +{ + return instance()->mPgpHandler->availableGPGCertificatesWithPrivateKeys(pgpIds); +} +bool AuthGPG::getGPGDetailsFromBinaryBlock(const unsigned char *mem,size_t mem_size,RsPgpId& key_id, std::string& name, std::list& signers) +{ + return instance()->mPgpHandler->getGPGDetailsFromBinaryBlock(mem,mem_size,key_id,name,signers); +} +void AuthGPG::registerToConfigMgr(const std::string& fname,p3ConfigMgr *CfgMgr) +{ + CfgMgr->addConfiguration(fname, instance()); +} bool AuthGPG::decryptTextFromFile(std::string& text,const std::string& inputfile) { - return PGPHandler::decryptTextFromFile(mOwnGpgId,text,inputfile) ; + return instance()->mPgpHandler->decryptTextFromFile(instance()->mOwnGpgId,text,inputfile) ; } bool AuthGPG::removeKeysFromPGPKeyring(const std::set& pgp_ids,std::string& backup_file,uint32_t& error_code) @@ -66,22 +78,22 @@ bool AuthGPG::removeKeysFromPGPKeyring(const std::set& pgp_ids,std::str // for(std::list::const_iterator it(pgp_ids.begin());it!=pgp_ids.end();++it) // pids.push_back(RsPgpId(*it)) ; - return PGPHandler::removeKeysFromPGPKeyring(pgp_ids,backup_file,error_code) ; + return instance()->mPgpHandler->removeKeysFromPGPKeyring(pgp_ids,backup_file,error_code) ; } // bool AuthGPG::decryptTextFromString(std::string& encrypted_text,std::string& output) // { -// return PGPHandler::decryptTextFromString(mOwnGpgId,encrypted_text,output) ; +// return instance()->mPgpHandler->decryptTextFromString(mOwnGpgId,encrypted_text,output) ; // } bool AuthGPG::encryptTextToFile(const std::string& text,const std::string& outfile) { - return PGPHandler::encryptTextToFile(mOwnGpgId,text,outfile) ; + return instance()->mPgpHandler->encryptTextToFile(instance()->mOwnGpgId,text,outfile) ; } // bool AuthGPG::encryptTextToString(const std::string& pgp_id,const std::string& text,std::string& outstr) // { -// return PGPHandler::encryptTextToString(RsPgpId(pgp_id),text,outstr) ; +// return instance()->mPgpHandler->encryptTextToString(RsPgpId(pgp_id),text,outstr) ; // } std::string pgp_pwd_callback(void * /*hook*/, const char *uid_title, const char *uid_hint, const char * /*passphrase_info*/, int prev_was_bad,bool *cancelled) @@ -107,8 +119,8 @@ void AuthGPG::init( std::cerr << "AuthGPG::init() called twice!" << std::endl ; } -// if(cb) PGPHandler::setPassphraseCallback(cb);else - PGPHandler::setPassphraseCallback(pgp_pwd_callback); +// if(cb) instance()->mPgpHandler->setPassphraseCallback(cb);else + instance()->mPgpHandler->setPassphraseCallback(pgp_pwd_callback); _instance = new AuthGPG( path_to_public_keyring, path_to_secret_keyring, path_to_trustdb, pgp_lock_file ); @@ -126,7 +138,6 @@ void AuthGPG::exit() AuthGPG::AuthGPG(const std::string& path_to_public_keyring,const std::string& path_to_secret_keyring,const std::string& path_to_trustdb,const std::string& pgp_lock_file) :p3Config(), - OpenPGPSDKHandler(path_to_public_keyring,path_to_secret_keyring,path_to_trustdb,pgp_lock_file), gpgMtxService("AuthGPG-service"), gpgMtxEngine("AuthGPG-engine"), gpgMtxData("AuthGPG-data"), @@ -135,7 +146,9 @@ AuthGPG::AuthGPG(const std::string& path_to_public_keyring,const std::string& pa _force_sync_database(false), mCount(0) { - start("AuthGPG"); + mPgpHandler = new OpenPGPSDKHandler(path_to_public_keyring,path_to_secret_keyring,path_to_trustdb,pgp_lock_file); + + start("AuthGPG"); } /* This function is called when retroshare is first started @@ -149,7 +162,7 @@ AuthGPG::AuthGPG(const std::string& path_to_public_keyring,const std::string& pa //{ // std::list pids ; // -// PGPHandler::availableGPGCertificatesWithPrivateKeys(pids) ; +// mPgpHandler->availableGPGCertificatesWithPrivateKeys(pids) ; // // for(std::list::const_iterator it(pids.begin());it!=pids.end();++it) // ids.push_back( (*it).toStdString() ) ; @@ -171,11 +184,11 @@ int AuthGPG::GPGInit(const RsPgpId &ownId) std::cerr << "AuthGPG::GPGInit() called with own gpg id : " << ownId.toStdString() << std::endl; #endif - mOwnGpgId = RsPgpId(ownId); + instance()->mOwnGpgId = ownId; //force the validity of the private key. When set to unknown, it caused signature and text encryptions bugs - privateTrustCertificate(ownId, 5); - updateOwnSignatureFlag(mOwnGpgId) ; + instance()->privateTrustCertificate(ownId, 5); + instance()->mPgpHandler->updateOwnSignatureFlag(ownId) ; #ifdef DEBUG_AUTHGPG std::cerr << "AuthGPG::GPGInit finished." << std::endl; @@ -204,7 +217,7 @@ void AuthGPG::threadTick() /// - checks whether the keyring has changed on disk. /// - merges/updates according to status. /// - PGPHandler::syncDatabase() ; + mPgpHandler->syncDatabase() ; mCount = 0; _force_sync_database = false ; }//if (++count >= 100 || _force_sync_database) @@ -251,7 +264,7 @@ void AuthGPG::processServices() /* don't bother loading - if we already have the certificate */ - if (isGPGId(loadOrSave->m_certGpgId)) + if (mPgpHandler->isGPGId(loadOrSave->m_certGpgId)) { #ifdef GPG_DEBUG std::cerr << "AuthGPGimpl::processServices() Skipping load - already have it" << std::endl; @@ -307,64 +320,64 @@ void AuthGPG::processServices() bool AuthGPG::DoOwnSignature(const void *data, unsigned int datalen, void *buf_sigout, unsigned int *outl, std::string reason /* = "" */) { - return PGPHandler::SignDataBin(mOwnGpgId,data,datalen,(unsigned char *)buf_sigout,outl,false,reason) ; + return instance()->mPgpHandler->SignDataBin(mOwnGpgId,data,datalen,(unsigned char *)buf_sigout,outl,false,reason) ; } /* import to GnuPG and other Certificates */ bool AuthGPG::VerifySignature(const void *data, int datalen, const void *sig, unsigned int siglen, const PGPFingerprintType& withfingerprint) { - return PGPHandler::VerifySignBin((unsigned char*)data,datalen,(unsigned char*)sig,siglen,withfingerprint) ; + return instance()->mPgpHandler->VerifySignBin((unsigned char*)data,datalen,(unsigned char*)sig,siglen,withfingerprint) ; } bool AuthGPG::parseSignature(const void *sig, unsigned int siglen, RsPgpId& issuer_id) { - return PGPHandler::parseSignature((unsigned char*)sig,siglen,issuer_id) ; + return instance()->mPgpHandler->parseSignature((unsigned char*)sig,siglen,issuer_id) ; } bool AuthGPG::exportProfile(const std::string& fname,const RsPgpId& exported_id) { - return PGPHandler::exportGPGKeyPair(fname,exported_id) ; + return instance()->mPgpHandler->exportGPGKeyPair(fname,exported_id) ; } bool AuthGPG::exportIdentityToString( std::string& data, const RsPgpId& pgpId, bool includeSignatures, std::string& errorMsg ) { - return PGPHandler::exportGPGKeyPairToString( + return instance()->mPgpHandler->exportGPGKeyPairToString( data, pgpId, includeSignatures, errorMsg); } bool AuthGPG::importProfile(const std::string& fname,RsPgpId& imported_id,std::string& import_error) { - return PGPHandler::importGPGKeyPair(fname,imported_id,import_error) ; + return instance()->mPgpHandler->importGPGKeyPair(fname,imported_id,import_error) ; } bool AuthGPG::importProfileFromString(const std::string &data, RsPgpId &gpg_id, std::string &import_error) { - return PGPHandler::importGPGKeyPairFromString(data, gpg_id, import_error); + return instance()->mPgpHandler->importGPGKeyPairFromString(data, gpg_id, import_error); } bool AuthGPG::active() { - RsStackMutex stack(gpgMtxData); /******* LOCKED ******/ + RsStackMutex stack(instance()->gpgMtxData); /******* LOCKED ******/ - return gpgKeySelected; + return instance()->gpgKeySelected; } bool AuthGPG::GeneratePGPCertificate(const std::string& name, const std::string& email, const std::string& passwd, RsPgpId& pgpId, const int keynumbits, std::string& errString) { - RsStackMutex stack(gpgMtxEngine); /******* LOCKED ******/ + RsStackMutex stack(instance()->gpgMtxEngine); /******* LOCKED ******/ - return PGPHandler::GeneratePGPCertificate(name, email, passwd, pgpId, keynumbits, errString) ; + return instance()->mPgpHandler->GeneratePGPCertificate(name, email, passwd, pgpId, keynumbits, errString) ; } /**** These Two are common */ std::string AuthGPG::getGPGName(const RsPgpId& id,bool *success) { - RsStackMutex stack(gpgMtxData); /******* LOCKED ******/ + RsStackMutex stack(instance()->gpgMtxData); /******* LOCKED ******/ - const PGPCertificateInfo *info = getCertificateInfo(id) ; + const PGPCertificateInfo *info = instance()->mPgpHandler->getCertificateInfo(id) ; if(info != NULL) { @@ -378,11 +391,29 @@ std::string AuthGPG::getGPGName(const RsPgpId& id,bool *success) } } +AuthGPG *AuthGPG::instance() +{ + if(!_instance) + { + RsFatal() << "AuthGPG::instance() called before AuthGPG::init()! This should not happen." << std::endl; + return nullptr; + } + + return _instance; +} +bool AuthGPG::isPGPId(const RsPgpId& id) +{ + return instance()->mPgpHandler->isGPGId(id); +} +bool AuthGPG::isPGPAccepted(const RsPgpId& id) +{ + return instance()->mPgpHandler->isGPGAccepted(id); +} /**** These Two are common */ std::string AuthGPG::getGPGEmail(const RsPgpId& id,bool *success) { - RsStackMutex stack(gpgMtxData); /******* LOCKED ******/ - const PGPCertificateInfo *info = getCertificateInfo(id) ; + RsStackMutex stack(instance()->gpgMtxData); /******* LOCKED ******/ + const PGPCertificateInfo *info = instance()->mPgpHandler->getCertificateInfo(id) ; if(info != NULL) { @@ -400,20 +431,20 @@ std::string AuthGPG::getGPGEmail(const RsPgpId& id,bool *success) const RsPgpId& AuthGPG::getGPGOwnId() { - RsStackMutex stack(gpgMtxData); /******* LOCKED ******/ - return mOwnGpgId ; + RsStackMutex stack(instance()->gpgMtxData); /******* LOCKED ******/ + return instance()->mOwnGpgId ; } std::string AuthGPG::getGPGOwnName() { - return getGPGName(mOwnGpgId) ; + return getGPGName(instance()->mOwnGpgId) ; } bool AuthGPG::getGPGAllList(std::list &ids) { - RsStackMutex stack(gpgMtxData); /******* LOCKED ******/ + RsStackMutex stack(instance()->gpgMtxData); /******* LOCKED ******/ - PGPHandler::getGPGFilteredList(ids) ; + instance()->mPgpHandler->getGPGFilteredList(ids) ; return true; } @@ -421,7 +452,7 @@ const PGPCertificateInfo *AuthGPG::getCertInfoFromStdString(const std::string& p { try { - return PGPHandler::getCertificateInfo(RsPgpId(pgp_id)) ; + return instance()->mPgpHandler->getCertificateInfo(RsPgpId(pgp_id)) ; } catch(std::exception& e) { @@ -429,13 +460,13 @@ const PGPCertificateInfo *AuthGPG::getCertInfoFromStdString(const std::string& p return NULL ; } } -bool AuthGPG::haveSecretKey(const RsPgpId& id) const +bool AuthGPG::haveSecretKey(const RsPgpId& id) { - return PGPHandler::haveSecretKey(id) ; + return instance()->mPgpHandler->haveSecretKey(id) ; } -bool AuthGPG::isKeySupported(const RsPgpId& id) const +bool AuthGPG::isKeySupported(const RsPgpId& id) { - const PGPCertificateInfo *pc = getCertificateInfo(id) ; + const PGPCertificateInfo *pc = instance()->mPgpHandler->getCertificateInfo(id) ; if(pc == NULL) return false ; @@ -445,9 +476,9 @@ bool AuthGPG::isKeySupported(const RsPgpId& id) const bool AuthGPG::getGPGDetails(const RsPgpId& pgp_id, RsPeerDetails &d) { - RsStackMutex stack(gpgMtxData); /******* LOCKED ******/ + RsStackMutex stack(instance()->gpgMtxData); /******* LOCKED ******/ - const PGPCertificateInfo *pc = PGPHandler::getCertificateInfo(pgp_id) ; + const PGPCertificateInfo *pc = instance()->mPgpHandler->getCertificateInfo(pgp_id) ; if(pc == NULL) return false ; @@ -476,9 +507,7 @@ bool AuthGPG::getGPGDetails(const RsPgpId& pgp_id, RsPeerDetails &d) bool AuthGPG::getGPGFilteredList(std::list& list,bool (*filter)(const PGPCertificateInfo&)) { - RsStackMutex stack(gpgMtxData); /******* LOCKED ******/ - - return PGPHandler::getGPGFilteredList(list,filter) ; + return instance()->mPgpHandler->getGPGFilteredList(list,filter) ; } static bool filter_Validity(const PGPCertificateInfo& /*info*/) { return true ; } //{ return info._validLvl >= PGPCertificateInfo::GPGME_VALIDITY_MARGINAL ; } @@ -504,9 +533,9 @@ bool AuthGPG::getGPGSignedList(std::list &ids) // { // RsStackMutex stack(gpgMtxData); /******* LOCKED ******/ // #ifdef LIMIT_CERTIFICATE_SIZE -// certificate = PGPHandler::SaveCertificateToString(RsPgpId(id),false) ; +// certificate = instance()->mPgpHandler->SaveCertificateToString(RsPgpId(id),false) ; // #else -// certificate = PGPHandler::SaveCertificateToString(RsPgpId(id),true) ; +// certificate = instance()->mPgpHandler->SaveCertificateToString(RsPgpId(id),true) ; // #endif // // // #ifdef LIMIT_CERTIFICATE_SIZE @@ -530,18 +559,18 @@ bool AuthGPG::getGPGSignedList(std::list &ids) /* SKTAN : do not know how to use std::string id */ std::string AuthGPG::SaveCertificateToString(const RsPgpId &id,bool include_signatures) { - RsStackMutex stack(gpgMtxEngine); /******* LOCKED ******/ + RsStackMutex stack(instance()->gpgMtxEngine); /******* LOCKED ******/ - return PGPHandler::SaveCertificateToString(id,include_signatures) ; + return instance()->mPgpHandler->SaveCertificateToString(id,include_signatures) ; } /* import to GnuPG and other Certificates */ bool AuthGPG::LoadPGPKeyFromBinaryData(const unsigned char *data,uint32_t data_len, RsPgpId& gpg_id,std::string& error_string) { - RsStackMutex stack(gpgMtxEngine); /******* LOCKED ******/ + RsStackMutex stack(instance()->gpgMtxEngine); /******* LOCKED ******/ - if(PGPHandler::LoadCertificateFromBinaryData(data,data_len,gpg_id,error_string)) + if(instance()->mPgpHandler->LoadCertificateFromBinaryData(data,data_len,gpg_id,error_string)) { - updateOwnSignatureFlag(gpg_id,mOwnGpgId) ; + instance()->mPgpHandler->updateOwnSignatureFlag(gpg_id,instance()->mOwnGpgId) ; return true ; } @@ -551,11 +580,11 @@ bool AuthGPG::LoadPGPKeyFromBinaryData(const unsigned char *data,uint32_t data_l /* import to GnuPG and other Certificates */ bool AuthGPG::LoadCertificateFromString(const std::string &str, RsPgpId& gpg_id,std::string& error_string) { - RsStackMutex stack(gpgMtxEngine); /******* LOCKED ******/ + RsStackMutex stack(instance()->gpgMtxEngine); /******* LOCKED ******/ - if(PGPHandler::LoadCertificateFromString(str,gpg_id,error_string)) + if(instance()->mPgpHandler->LoadCertificateFromString(str,gpg_id,error_string)) { - updateOwnSignatureFlag(gpg_id,mOwnGpgId) ; + instance()->mPgpHandler->updateOwnSignatureFlag(gpg_id,instance()->mOwnGpgId) ; return true ; } @@ -584,11 +613,11 @@ bool AuthGPG::AllowConnection(const RsPgpId& gpg_id, bool accept) /* Was a "Reload Certificates" here -> be shouldn't be needed -> and very expensive, try without. */ { - RsStackMutex stack(gpgMtxData); - PGPHandler::setAcceptConnexion(gpg_id,accept) ; + RsStackMutex stack(instance()->gpgMtxData); + instance()->mPgpHandler->setAcceptConnexion(gpg_id,accept) ; } - IndicateConfigChanged(); + instance()->IndicateConfigChanged(); RsServer::notify()->notifyListChange(NOTIFY_LIST_FRIENDS, accept ? NOTIFY_TYPE_ADD : NOTIFY_TYPE_DEL); @@ -602,7 +631,7 @@ bool AuthGPG::SignCertificateLevel0(const RsPgpId &id) std::cerr << "AuthGPG::SignCertificat(" << id << ")" << std::endl; #endif - return privateSignCertificate(id) ; + return instance()->privateSignCertificate(id) ; } bool AuthGPG::RevokeCertificate(const RsPgpId &id) @@ -622,26 +651,39 @@ bool AuthGPG::TrustCertificate(const RsPgpId& id, int trustlvl) #ifdef GPG_DEBUG std::cerr << "AuthGPG::TrustCertificate(" << id << ", " << trustlvl << ")" << std::endl; #endif - return privateTrustCertificate(id, trustlvl) ; + return instance()->privateTrustCertificate(id, trustlvl) ; } bool AuthGPG::encryptDataBin(const RsPgpId& pgp_id,const void *data, unsigned int datalen, unsigned char *sign, unsigned int *signlen) { - return PGPHandler::encryptDataBin(RsPgpId(pgp_id),data,datalen,sign,signlen) ; + return instance()->mPgpHandler->encryptDataBin(RsPgpId(pgp_id),data,datalen,sign,signlen) ; } bool AuthGPG::decryptDataBin(const void *data, unsigned int datalen, unsigned char *sign, unsigned int *signlen) { - return PGPHandler::decryptDataBin(mOwnGpgId,data,datalen,sign,signlen) ; + return instance()->mPgpHandler->decryptDataBin(instance()->mOwnGpgId,data,datalen,sign,signlen) ; } bool AuthGPG::SignDataBin(const void *data, unsigned int datalen, unsigned char *sign, unsigned int *signlen, std::string reason /*= ""*/) { - return DoOwnSignature(data, datalen, sign, signlen, reason); + return instance()->DoOwnSignature(data, datalen, sign, signlen, reason); } +bool AuthGPG::exportPublicKey( const RsPgpId& id, unsigned char*& mem_block, size_t& mem_size, bool armoured, bool include_signatures ) +{ + return instance()->mPgpHandler->exportPublicKey(id,mem_block,mem_size,armoured,include_signatures); +} + +bool AuthGPG::isPgpPubKeyAvailable(const RsPgpId& pgp_id) +{ + return instance()->mPgpHandler->isPgpPubKeyAvailable(pgp_id); +} +bool AuthGPG::getKeyFingerprint(const RsPgpId& id,PGPFingerprintType& fp) +{ + return instance()->mPgpHandler->getKeyFingerprint(id,fp); +} bool AuthGPG::VerifySignBin(const void *data, uint32_t datalen, unsigned char *sign, unsigned int signlen, const PGPFingerprintType& withfingerprint) { - return VerifySignature(data, datalen, sign, signlen, withfingerprint); + return instance()->VerifySignature(data, datalen, sign, signlen, withfingerprint); } /* Sign/Trust stuff */ @@ -650,7 +692,7 @@ int AuthGPG::privateSignCertificate(const RsPgpId &id) { RsStackMutex stack(gpgMtxData); /******* LOCKED ******/ - int ret = PGPHandler::privateSignCertificate(mOwnGpgId,id) ; + int ret = mPgpHandler->privateSignCertificate(mOwnGpgId,id) ; _force_sync_database = true ; return ret ; } @@ -675,7 +717,7 @@ int AuthGPG::privateTrustCertificate(const RsPgpId& id, int trustlvl) if(!isGPGAccepted(id)) return 0; - int res = PGPHandler::privateTrustCertificate(id,trustlvl) ; + int res = instance()->mPgpHandler->privateTrustCertificate(id,trustlvl) ; _force_sync_database = true ; return res ; } @@ -690,6 +732,10 @@ RsSerialiser *AuthGPG::setupSerialiser() rss->addSerialType(new RsGeneralConfigSerialiser()); return rss ; } +bool AuthGPG::isGPGAccepted(const RsPgpId& id) +{ + return instance()->mPgpHandler->isGPGAccepted(id); +} bool AuthGPG::saveList(bool& cleanup, std::list& lst) { @@ -745,7 +791,7 @@ bool AuthGPG::loadList(std::list& load) std::list::iterator kit; for(kit = vitem->tlvkvs.pairs.begin(); kit != vitem->tlvkvs.pairs.end(); ++kit) if (kit->key != mOwnGpgId.toStdString()) - PGPHandler::setAcceptConnexion(RsPgpId(kit->key), (kit->value == "TRUE")); + instance()->mPgpHandler->setAcceptConnexion(RsPgpId(kit->key), (kit->value == "TRUE")); } delete (*it); } @@ -755,14 +801,14 @@ bool AuthGPG::loadList(std::list& load) bool AuthGPG::addService(AuthGPGService *service) { - RsStackMutex stack(gpgMtxService); /********* LOCKED *********/ + RsStackMutex stack(instance()->gpgMtxService); /********* LOCKED *********/ - if (std::find(services.begin(), services.end(), service) != services.end()) { + if (std::find(instance()->services.begin(), instance()->services.end(), service) != instance()->services.end()) { /* it exists already! */ return false; } - services.push_back(service); + instance()->services.push_back(service); return true; } diff --git a/libretroshare/src/pqi/authgpg.h b/libretroshare/src/pqi/authgpg.h index a6023f436..177f71663 100644 --- a/libretroshare/src/pqi/authgpg.h +++ b/libretroshare/src/pqi/authgpg.h @@ -89,18 +89,19 @@ public: virtual void setGPGOperation(AuthGPGOperation *operation) = 0; }; -// Note: replace OpenPGPSDKHandler with your own PGP handler class when needed. - -class AuthGPG: public p3Config, public RsTickingThread, public OpenPGPSDKHandler +class AuthGPG: public p3Config, public RsTickingThread { public: - static void init(const std::string& path_to_pubring, - const std::string& path_to_secring, - const std::string& path_to_trustdb, - const std::string& pgp_lock_file); + static void init(const std::string& path_to_pubring, + const std::string& path_to_secring, + const std::string& path_to_trustdb, + const std::string& pgp_lock_file); - static void exit(); - static AuthGPG *getAuthGPG() { return _instance ; } + static void registerToConfigMgr(const std::string& fname,p3ConfigMgr *CfgMgr); + static void exit(); + + static bool isPGPId(const RsPgpId& id) ; + static bool isPGPAccepted(const RsPgpId& id) ; /** * @param ids list of gpg certificate ids (note, not the actual certificates) @@ -120,7 +121,7 @@ public: * (see storage at the end of the class) * ****/ - virtual bool active(); + static bool active(); // /* Initialize */ // virtual bool InitAuth (); @@ -128,10 +129,13 @@ public: /* Init by generating new Own PGP Cert, or selecting existing PGP Cert */ - virtual int GPGInit(const RsPgpId &ownId); - virtual bool GeneratePGPCertificate(const std::string& name, const std::string& email, const std::string& passwd, RsPgpId &pgpId, const int keynumbits, std::string &errString); + static int GPGInit(const RsPgpId &ownId); + static bool GeneratePGPCertificate(const std::string& name, const std::string& email, const std::string& passwd, RsPgpId &pgpId, const int keynumbits, std::string &errString); - /*********************************************************************************/ + static bool getGPGDetailsFromBinaryBlock(const unsigned char *mem,size_t mem_size,RsPgpId& key_id, std::string& name, std::list& signers) ; + static int availableGPGCertificatesWithPrivateKeys(std::list& pgpIds); + + /*********************************************************************************/ /************************* STAGE 3 ***********************************************/ /*********************************************************************************/ /***** @@ -142,29 +146,35 @@ public: * provide access to details in cache list. * ****/ - virtual std::string getGPGName(const RsPgpId &pgp_id,bool *success = NULL); - virtual std::string getGPGEmail(const RsPgpId &pgp_id,bool *success = NULL); + static std::string getGPGName(const RsPgpId &pgp_id,bool *success = NULL); + static std::string getGPGEmail(const RsPgpId &pgp_id,bool *success = NULL); - /* PGP web of trust management */ - virtual const RsPgpId& getGPGOwnId(); - virtual std::string getGPGOwnName(); + static bool exportPublicKey( const RsPgpId& id, unsigned char*& mem_block, size_t& mem_size, bool armoured, bool include_signatures ); - //virtual std::string getGPGOwnEmail(); - virtual bool isKeySupported(const RsPgpId &id) const ; - virtual bool haveSecretKey(const RsPgpId &id) const ; - virtual bool getGPGDetails(const RsPgpId& id, RsPeerDetails &d); - virtual bool getGPGAllList(std::list &ids); - virtual bool getGPGValidList(std::list &ids); - virtual bool getGPGAcceptedList(std::list &ids); - virtual bool getGPGSignedList(std::list &ids); - virtual bool importProfile(const std::string& filename,RsPgpId& gpg_id,std::string& import_error) ; - virtual bool importProfileFromString(const std::string& data,RsPgpId& gpg_id,std::string& import_error) ; - virtual bool exportProfile(const std::string& filename,const RsPgpId& gpg_id) ; - virtual bool exportIdentityToString( + /* PGP web of trust management */ + static const RsPgpId& getGPGOwnId(); + static std::string getGPGOwnName(); + + static bool isGPGAccepted(const RsPgpId& id); + + //virtual std::string getGPGOwnEmail(); + static bool getKeyFingerprint(const RsPgpId& id,PGPFingerprintType& fp) ; + static bool isKeySupported(const RsPgpId &id) ; + static bool isPgpPubKeyAvailable(const RsPgpId& pgp_id); + static bool haveSecretKey(const RsPgpId &id) ; + static bool getGPGDetails(const RsPgpId& id, RsPeerDetails &d); + static bool getGPGAllList(std::list &ids); + static bool getGPGValidList(std::list &ids); + static bool getGPGAcceptedList(std::list &ids); + static bool getGPGSignedList(std::list &ids); + static bool importProfile(const std::string& filename,RsPgpId& gpg_id,std::string& import_error) ; + static bool importProfileFromString(const std::string& data,RsPgpId& gpg_id,std::string& import_error) ; + static bool exportProfile(const std::string& filename,const RsPgpId& gpg_id) ; + static bool exportIdentityToString( std::string& data, const RsPgpId& pgpId, bool includeSignatures, std::string& errorMsg ); - virtual bool removeKeysFromPGPKeyring(const std::set &pgp_ids,std::string& backup_file,uint32_t& error_code) ; + static bool removeKeysFromPGPKeyring(const std::set &pgp_ids,std::string& backup_file,uint32_t& error_code) ; /*********************************************************************************/ /************************* STAGE 4 ***********************************************/ @@ -173,9 +183,9 @@ public: * STAGE 4: Loading and Saving Certificates. (Strings and Files) * ****/ - virtual bool LoadCertificateFromString(const std::string &pem, RsPgpId& gpg_id,std::string& error_string); - virtual bool LoadPGPKeyFromBinaryData(const unsigned char *data,uint32_t data_len, RsPgpId& gpg_id,std::string& error_string); - virtual std::string SaveCertificateToString(const RsPgpId &id,bool include_signatures) ; + static bool LoadCertificateFromString(const std::string &pem, RsPgpId& gpg_id,std::string& error_string); + static bool LoadPGPKeyFromBinaryData(const unsigned char *data,uint32_t data_len, RsPgpId& gpg_id,std::string& error_string); + static std::string SaveCertificateToString(const RsPgpId &id,bool include_signatures) ; // Cached certificates. //bool getCachedGPGCertificate(const RsPgpId &id, std::string &certificate); @@ -190,12 +200,12 @@ public: * done in gpgroot already. * ****/ - virtual bool AllowConnection(const RsPgpId &gpg_id, bool accept); + static bool AllowConnection(const RsPgpId &gpg_id, bool accept); - virtual bool SignCertificateLevel0(const RsPgpId &id); - virtual bool RevokeCertificate(const RsPgpId &id); /* Particularly hard - leave for later */ + static bool SignCertificateLevel0(const RsPgpId &id); + static bool RevokeCertificate(const RsPgpId &id); /* Particularly hard - leave for later */ - virtual bool TrustCertificate(const RsPgpId& id, int trustlvl); //trustlvl is 2 for none, 3 for marginal and 4 for full trust + static bool TrustCertificate(const RsPgpId& id, int trustlvl); //trustlvl is 2 for none, 3 for marginal and 4 for full trust /*********************************************************************************/ /************************* STAGE 7 ***********************************************/ @@ -206,25 +216,25 @@ public: * There should also be Encryption Functions... (do later). * ****/ - virtual bool SignDataBin(const void *data, const uint32_t len, unsigned char *sign, unsigned int *signlen, std::string reason = ""); - virtual bool VerifySignBin(const void*, uint32_t, unsigned char*, unsigned int, const PGPFingerprintType& withfingerprint); - virtual bool parseSignature(const void *sig, unsigned int siglen, RsPgpId& issuer_id); + static bool SignDataBin(const void *data, const uint32_t len, unsigned char *sign, unsigned int *signlen, std::string reason = ""); + static bool VerifySignBin(const void*, uint32_t, unsigned char*, unsigned int, const PGPFingerprintType& withfingerprint); + static bool parseSignature(const void *sig, unsigned int siglen, RsPgpId& issuer_id); - virtual bool encryptDataBin(const RsPgpId& pgp_id,const void *data, const uint32_t len, unsigned char *encr, unsigned int *encrlen); - virtual bool decryptDataBin(const void *data, const uint32_t len, unsigned char *decr, unsigned int *decrlen); + static bool encryptDataBin(const RsPgpId& pgp_id,const void *data, const uint32_t len, unsigned char *encr, unsigned int *encrlen); + static bool decryptDataBin(const void *data, const uint32_t len, unsigned char *decr, unsigned int *decrlen); - virtual bool decryptTextFromFile( std::string& text,const std::string& filename); - virtual bool encryptTextToFile (const std::string& text,const std::string& filename); + static bool decryptTextFromFile( std::string& text,const std::string& filename); + static bool encryptTextToFile (const std::string& text,const std::string& filename); // virtual bool decryptTextFromString( std::string& encrypted_text,std::string& clear_string); // virtual bool encryptTextToString (const std::string& pgp_id,const std::string& clear_text,std::string& encrypted_string); - bool getGPGFilteredList(std::list& list,bool (*filter)(const PGPCertificateInfo&) = NULL) ; + static bool getGPGFilteredList(std::list& list,bool (*filter)(const PGPCertificateInfo&) = NULL) ; //END of PGP public functions /* GPG service */ - virtual bool addService(AuthGPGService *service) ; + static bool addService(AuthGPGService *service) ; // This is for debug purpose only. Don't use it !! static void setAuthGPG_debug(AuthGPG *auth_gpg) { _instance = auth_gpg ; } @@ -236,9 +246,9 @@ public: /*****************************************************************/ /*********************** p3config ******************************/ /* Key Functions to be overloaded for Full Configuration */ - virtual RsSerialiser *setupSerialiser(); - virtual bool saveList(bool &cleanup, std::list&); - virtual bool loadList(std::list& load); + virtual RsSerialiser *setupSerialiser() override; + virtual bool saveList(bool &cleanup, std::list&) override; + virtual bool loadList(std::list& load) override; /*****************************************************************/ private: @@ -276,8 +286,7 @@ private: void threadTick() override; /// @see RsTickingThread private: - - static AuthGPG *instance_gpg; // pointeur vers le singleton + static AuthGPG *instance(); RsMutex gpgMtxService; RsMutex gpgMtxEngine; @@ -292,6 +301,8 @@ private: rstime_t mStoreKeyTime; + PGPHandler *mPgpHandler; + RsPgpId mOwnGpgId; bool gpgKeySelected; bool _force_sync_database ; diff --git a/libretroshare/src/pqi/authssl.cc b/libretroshare/src/pqi/authssl.cc index eb89a1ed5..6d14d0043 100644 --- a/libretroshare/src/pqi/authssl.cc +++ b/libretroshare/src/pqi/authssl.cc @@ -759,8 +759,7 @@ X509 *AuthSSLimpl::SignX509ReqWithGPG(X509_REQ *req, long /*days*/) //long version = 0x00; unsigned long chtype = MBSTRING_UTF8; X509_NAME *issuer_name = X509_NAME_new(); - X509_NAME_add_entry_by_txt(issuer_name, "CN", chtype, - (unsigned char *) AuthGPG::getAuthGPG()->getGPGOwnId().toStdString().c_str(), -1, -1, 0); + X509_NAME_add_entry_by_txt(issuer_name, "CN", chtype, (unsigned char *) AuthGPG::getGPGOwnId().toStdString().c_str(), -1, -1, 0); /**** X509_NAME_add_entry_by_NID(issuer_name, 48, 0, (unsigned char *) "email@email.com", -1, -1, 0); @@ -770,7 +769,7 @@ X509 *AuthSSLimpl::SignX509ReqWithGPG(X509_REQ *req, long /*days*/) (unsigned char *) "loc", -1, -1, 0); ****/ - std::cerr << "AuthSSLimpl::SignX509Req() Issuer name: " << AuthGPG::getAuthGPG()->getGPGOwnId().toStdString() << std::endl; + std::cerr << "AuthSSLimpl::SignX509Req() Issuer name: " << AuthGPG::getGPGOwnId().toStdString() << std::endl; #ifdef V07_NON_BACKWARD_COMPATIBLE_CHANGE_002 static const uint64_t CERTIFICATE_SERIAL_NUMBER = RS_CERTIFICATE_VERSION_NUMBER_07_0001 ; @@ -945,7 +944,7 @@ X509 *AuthSSLimpl::SignX509ReqWithGPG(X509_REQ *req, long /*days*/) std::cerr << "Buffers Allocated" << std::endl; /* NOW Sign via GPG Functions */ - if (!AuthGPG::getAuthGPG()->SignDataBin(buf_in, inl, buf_sigout, (unsigned int *) &sigoutl,"AuthSSLimpl::SignX509ReqWithGPG()")) + if (!AuthGPG::SignDataBin(buf_in, inl, buf_sigout, (unsigned int *) &sigoutl,"AuthSSLimpl::SignX509ReqWithGPG()")) { sigoutl = 0; goto err; @@ -1040,7 +1039,7 @@ bool AuthSSLimpl::AuthX509WithGPG(X509 *x509,bool verbose, uint32_t& diagnostic) { RsPgpId issuer = RsX509Cert::getCertIssuer(*x509); RsPeerDetails pd; - if (!AuthGPG::getAuthGPG()->getGPGDetails(issuer, pd)) + if (!AuthGPG::getGPGDetails(issuer, pd)) { RsInfo() << __PRETTY_FUNCTION__ << " X509 NOT authenticated : " << "AuthGPG::getAuthGPG()->getGPGDetails(" << issuer @@ -1185,9 +1184,7 @@ bool AuthSSLimpl::AuthX509WithGPG(X509 *x509,bool verbose, uint32_t& diagnostic) // passed, verify the signature itself - if (!AuthGPG::getAuthGPG()->VerifySignBin( - signed_data, signed_data_length, signature->data, - static_cast(signature->length), pd.fpr )) + if (!AuthGPG::VerifySignBin( signed_data, signed_data_length, signature->data, static_cast(signature->length), pd.fpr )) { diagnostic = RS_SSL_HANDSHAKE_DIAGNOSTIC_WRONG_SIGNATURE; goto err; @@ -1383,7 +1380,7 @@ int AuthSSLimpl::VerifyX509Callback(int /*preverify_ok*/, X509_STORE_CTX* ctx) std::cerr << "******* VerifyX509Callback cert: " << std::hex << ctx->cert <getGPGOwnId() && !AuthGPG::getAuthGPG()->isGPGAccepted(pgpId) ) + if ( !isSslOnlyFriend && pgpId != AuthGPG::getGPGOwnId() && !AuthGPG::isGPGAccepted(pgpId) ) { std::string errMsg = "Connection attempt signed by PGP key id: " + pgpId.toStdString() + " not accepted because it is not" diff --git a/libretroshare/src/pqi/p3peermgr.cc b/libretroshare/src/pqi/p3peermgr.cc index 83c4d9366..15eaa08f8 100644 --- a/libretroshare/src/pqi/p3peermgr.cc +++ b/libretroshare/src/pqi/p3peermgr.cc @@ -812,11 +812,11 @@ int p3PeerMgrIMPL::getFriendCount(bool ssl, bool online) // count all gpg id's std::list gpgIds; - AuthGPG::getAuthGPG()->getGPGAcceptedList(gpgIds); + AuthGPG::getGPGAcceptedList(gpgIds); // add own gpg id, if we have more than one location std::list ownSslIds; - getAssociatedPeers(AuthGPG::getAuthGPG()->getGPGOwnId(), ownSslIds); + getAssociatedPeers(AuthGPG::getGPGOwnId(), ownSslIds); return gpgIds.size() + ((ownSslIds.size() > 0) ? 1 : 0); } @@ -962,7 +962,7 @@ bool p3PeerMgrIMPL::addFriend(const RsPeerId& input_id, const RsPgpId& input_gpg // check that the PGP key is known - if(!AuthGPG::getAuthGPG()->isGPGId(gpg_id)) + if(!AuthGPG::isPGPId(gpg_id)) { RsErr() << "Trying to add SSL id (" << id << ") to be validated with unknown PGP key (" << gpg_id << ". This is a bug!" << std::endl; return false; @@ -970,7 +970,7 @@ bool p3PeerMgrIMPL::addFriend(const RsPeerId& input_id, const RsPgpId& input_gpg //Authentication is now tested at connection time, we don't store the ssl cert anymore // - if (!AuthGPG::getAuthGPG()->isGPGAccepted(gpg_id) && gpg_id != AuthGPG::getAuthGPG()->getGPGOwnId()) + if (!AuthGPG::isGPGAccepted(gpg_id) && gpg_id != AuthGPG::getGPGOwnId()) { #ifdef PEER_DEBUG std::cerr << "p3PeerMgrIMPL::addFriend() gpg is not accepted" << std::endl; @@ -1024,7 +1024,7 @@ bool p3PeerMgrIMPL::addFriend(const RsPeerId& input_id, const RsPgpId& input_gpg pstate.id = id; pstate.gpg_id = gpg_id; - pstate.name = AuthGPG::getAuthGPG()->getGPGName(gpg_id); + pstate.name = AuthGPG::getGPGName(gpg_id); pstate.vs_disc = vs_disc; pstate.vs_dht = vs_dht; @@ -1126,8 +1126,8 @@ bool p3PeerMgrIMPL::addSslOnlyFriend( const RsPeerId& sslId, const RsPgpId& pgp_ * superficially set to true the PGP signature verification would have been * skipped and the attacker connection would be accepted. * If the PGP key is available add it as full friend. */ - if(AuthGPG::getAuthGPG()->isPgpPubKeyAvailable(pgp_id)) - AuthGPG::getAuthGPG()->AllowConnection(pgp_id, true); + if(AuthGPG::isPgpPubKeyAvailable(pgp_id)) + AuthGPG::AllowConnection(pgp_id, true); else pstate.skip_pgp_signature_validation = true; @@ -2470,7 +2470,7 @@ bool p3PeerMgrIMPL::loadList(std::list& load) setOwnNetworkMode(pitem->netMode); setOwnVisState(pitem->vs_disc, pitem->vs_dht); - mOwnState.gpg_id = AuthGPG::getAuthGPG()->getGPGOwnId(); + mOwnState.gpg_id = AuthGPG::getGPGOwnId(); mOwnState.location = AuthSSL::getAuthSSL()->getOwnLocation(); } else @@ -2642,7 +2642,7 @@ bool p3PeerMgrIMPL::loadList(std::list& load) #endif for(uint32_t i=0;ipgp_ids.size();++i) - if(AuthGPG::getAuthGPG()->isGPGAccepted(sitem->pgp_ids[i]) || sitem->pgp_ids[i] == AuthGPG::getAuthGPG()->getGPGOwnId()) + if(AuthGPG::isGPGAccepted(sitem->pgp_ids[i]) || sitem->pgp_ids[i] == AuthGPG::getGPGOwnId()) { mFriendsPermissionFlags[sitem->pgp_ids[i]] = sitem->service_flags[i] ; #ifdef PEER_DEBUG @@ -2684,7 +2684,7 @@ bool p3PeerMgrIMPL::loadList(std::list& load) for(auto group_pair:groupList) { for(auto profileIdIt(group_pair.second.peerIds.begin());profileIdIt!=group_pair.second.peerIds.end();) - if(AuthGPG::getAuthGPG()->isGPGAccepted(*profileIdIt) || *profileIdIt == AuthGPG::getAuthGPG()->getGPGOwnId()) + if(AuthGPG::isGPGAccepted(*profileIdIt) || *profileIdIt == AuthGPG::getGPGOwnId()) ++profileIdIt; else { diff --git a/libretroshare/src/pqi/pqissl.cc b/libretroshare/src/pqi/pqissl.cc index 76d447cc8..b6f655692 100644 --- a/libretroshare/src/pqi/pqissl.cc +++ b/libretroshare/src/pqi/pqissl.cc @@ -1213,8 +1213,7 @@ int pqissl::Authorise_SSL_Connection() } RsPgpId pgpId = RsX509Cert::getCertIssuer(*peercert); - if( !isSslOnlyFriend && pgpId != AuthGPG::getAuthGPG()->getGPGOwnId() && - !AuthGPG::getAuthGPG()->isGPGAccepted(pgpId) ) + if( !isSslOnlyFriend && pgpId != AuthGPG::getGPGOwnId() && !AuthGPG::isGPGAccepted(pgpId) ) { RsFatal() << __PRETTY_FUNCTION__ << " pgpId: " << pgpId << " is not friend. It is very unlikely to happen at this " diff --git a/libretroshare/src/pqi/pqissllistener.cc b/libretroshare/src/pqi/pqissllistener.cc index fa25bfe0b..a9e392a56 100644 --- a/libretroshare/src/pqi/pqissllistener.cc +++ b/libretroshare/src/pqi/pqissllistener.cc @@ -797,8 +797,7 @@ int pqissllistener::completeConnection(int fd, IncomingSSLInfo& info) exit(failure); } - if( !isSslOnlyFriend && pgpId != AuthGPG::getAuthGPG()->getGPGOwnId() && - !AuthGPG::getAuthGPG()->isGPGAccepted(pgpId) ) + if( !isSslOnlyFriend && pgpId != AuthGPG::getGPGOwnId() && !AuthGPG::isGPGAccepted(pgpId) ) { RsFatal() << __PRETTY_FUNCTION__ << " pgpId: " << pgpId << " is not friend. It is very unlikely to happen at this " diff --git a/libretroshare/src/rsserver/p3peers.cc b/libretroshare/src/rsserver/p3peers.cc index c44877fc5..25caac374 100644 --- a/libretroshare/src/rsserver/p3peers.cc +++ b/libretroshare/src/rsserver/p3peers.cc @@ -254,7 +254,7 @@ bool p3Peers::setPeerMaximumRates(const RsPgpId& pid,uint32_t maxUploadRate,uint bool p3Peers::haveSecretKey(const RsPgpId& id) { - return AuthGPG::getAuthGPG()->haveSecretKey(id); + return AuthGPG::haveSecretKey(id); } /* There are too many dependancies of this function @@ -273,7 +273,7 @@ bool p3Peers::getPeerDetails(const RsPeerId& id, RsPeerDetails &d) if (id == sOwnId) { mPeerMgr->getOwnNetStatus(ps); - ps.gpg_id = AuthGPG::getAuthGPG()->getGPGOwnId(); + ps.gpg_id = AuthGPG::getGPGOwnId(); } else if (!mPeerMgr->getFriendNetStatus(id, ps)) { @@ -559,17 +559,17 @@ bool p3Peers::isProxyAddress(const uint32_t type, const sockaddr_storage& addr) bool p3Peers::isKeySupported(const RsPgpId& id) { - return AuthGPG::getAuthGPG()->isKeySupported(id); + return AuthGPG::isKeySupported(id); } std::string p3Peers::getGPGName(const RsPgpId &gpg_id) { /* get from mAuthMgr as it should have more peers? */ - return AuthGPG::getAuthGPG()->getGPGName(gpg_id); + return AuthGPG::getGPGName(gpg_id); } bool p3Peers::isPgpFriend(const RsPgpId& pgpId) -{ return AuthGPG::getAuthGPG()->isGPGAccepted(pgpId); } +{ return AuthGPG::isGPGAccepted(pgpId); } bool p3Peers::isSslOnlyFriend(const RsPeerId& sslId) { @@ -597,7 +597,7 @@ std::string p3Peers::getPeerName(const RsPeerId& ssl) #endif std::string name; if (ssl == AuthSSL::getAuthSSL()->OwnId()) - return AuthGPG::getAuthGPG()->getGPGOwnName(); + return AuthGPG::getGPGOwnName(); if (mPeerMgr->getPeerName(ssl, name)) { @@ -617,7 +617,7 @@ bool p3Peers::getGPGAllList(std::list &ids) #endif /* get from mAuthMgr */ - AuthGPG::getAuthGPG()->getGPGAllList(ids); + AuthGPG::getGPGAllList(ids); return true; } @@ -628,7 +628,7 @@ bool p3Peers::getGPGValidList(std::list &ids) #endif /* get from mAuthMgr */ - AuthGPG::getAuthGPG()->getGPGValidList(ids); + AuthGPG::getGPGValidList(ids); return true; } @@ -639,14 +639,14 @@ bool p3Peers::getGPGSignedList(std::list &ids) #endif /* get from mAuthMgr */ - AuthGPG::getAuthGPG()->getGPGSignedList(ids); + AuthGPG::getGPGSignedList(ids); return true; } bool p3Peers::getPgpFriendList(std::vector& pgpIds) { std::list ids; - if(AuthGPG::getAuthGPG()->getGPGAcceptedList(ids)) + if(AuthGPG::getGPGAcceptedList(ids)) { pgpIds.clear(); std::copy(ids.begin(), ids.end(), std::back_inserter(pgpIds)); @@ -660,7 +660,7 @@ bool p3Peers::getGPGAcceptedList(std::list &ids) #ifdef P3PEERS_DEBUG std::cerr << "p3Peers::getGPGAcceptedList()" << std::endl; #endif - AuthGPG::getAuthGPG()->getGPGAcceptedList(ids); + AuthGPG::getGPGAcceptedList(ids); return true; } @@ -676,7 +676,7 @@ bool p3Peers::getAssociatedSSLIds(const RsPgpId &gpg_id, std::list &id bool p3Peers::gpgSignData(const void *data, const uint32_t len, unsigned char *sign, unsigned int *signlen, std::string reason /* = "" */) { - return AuthGPG::getAuthGPG()->SignDataBin(data,len,sign,signlen, reason); + return AuthGPG::SignDataBin(data,len,sign,signlen, reason); } RsPgpId p3Peers::pgpIdFromFingerprint(const RsPgpFingerprint& fpr) @@ -691,7 +691,7 @@ bool p3Peers::getGPGDetails(const RsPgpId &pgp_id, RsPeerDetails &d) #endif /* get from mAuthMgr */ - bool res = AuthGPG::getAuthGPG()->getGPGDetails(pgp_id, d); + bool res = AuthGPG::getGPGDetails(pgp_id, d); d.isOnlyGPGdetail = true ; d.service_perm_flags = mPeerMgr->servicePermissionFlags(pgp_id) ; @@ -706,7 +706,7 @@ const RsPgpId& p3Peers::getGPGOwnId() #endif /* get from mAuthMgr */ - return AuthGPG::getAuthGPG()->getGPGOwnId(); + return AuthGPG::getGPGOwnId(); } RsPgpId p3Peers::getGPGId(const RsPeerId& sslid) @@ -718,7 +718,7 @@ RsPgpId p3Peers::getGPGId(const RsPeerId& sslid) /* get from mAuthMgr */ if (sslid == AuthSSL::getAuthSSL()->OwnId()) { - return AuthGPG::getAuthGPG()->getGPGOwnId(); + return AuthGPG::getGPGOwnId(); } peerState pcs; if (mPeerMgr->getFriendNetStatus(sslid, pcs)) @@ -739,12 +739,12 @@ bool p3Peers::addFriend(const RsPeerId &ssl_id, const RsPgpId &gpg_id,ServicePe #ifdef P3PEERS_DEBUG std::cerr << "p3Peers::addFriend() with : id : " << id << "; gpg_id : " << gpg_id << std::endl; #endif - if(AuthGPG::getAuthGPG()->isGPGId(gpg_id)) + if(AuthGPG::isPGPId(gpg_id)) { #ifdef P3PEERS_DEBUG std::cerr << "p3Peers::addFriend() Authorising GPG Id: " << gpg_id << std::endl; #endif - if (AuthGPG::getAuthGPG()->AllowConnection(gpg_id, true)) + if (AuthGPG::AllowConnection(gpg_id, true)) { #ifdef P3PEERS_DEBUG std::cerr << "p3Peers::addFriend() Authorization OK." << std::endl; @@ -797,7 +797,7 @@ bool p3Peers::addSslOnlyFriend( const RsPeerId& sslId, const RsPgpId& pgp_id,con bool p3Peers::removeKeysFromPGPKeyring(const std::set& pgp_ids,std::string& backup_file,uint32_t& error_code) { - return AuthGPG::getAuthGPG()->removeKeysFromPGPKeyring(pgp_ids,backup_file,error_code) ; + return AuthGPG::removeKeysFromPGPKeyring(pgp_ids,backup_file,error_code) ; } bool p3Peers::removeFriendLocation(const RsPeerId &sslId) @@ -817,7 +817,7 @@ bool p3Peers::removeFriend(const RsPgpId& gpgId) #ifdef P3PEERS_DEBUG std::cerr << "p3Peers::removeFriend() " << gpgId << std::endl; #endif - if (gpgId == AuthGPG::getAuthGPG()->getGPGOwnId()) { + if (gpgId == AuthGPG::getGPGOwnId()) { std::cerr << "p3Peers::removeFriend() ERROR we're not going to remove our own GPG id." << std::endl; return false; } @@ -825,7 +825,7 @@ bool p3Peers::removeFriend(const RsPgpId& gpgId) #ifdef P3PEERS_DEBUG std::cerr << "p3Peers::removeFriend() Removing GPG Id: " << gpgId << std::endl; #endif - if (AuthGPG::getAuthGPG()->AllowConnection(gpgId, false)) + if (AuthGPG::AllowConnection(gpgId, false)) { #ifdef P3PEERS_DEBUG std::cerr << "p3Peers::removeFriend() OK." << std::endl; @@ -1107,9 +1107,7 @@ std::string p3Peers::getPGPKey(const RsPgpId& pgp_id,bool include_signatures) rs_owner_ptr mem_block = nullptr; size_t mem_block_size = 0; - if( !AuthGPG::getAuthGPG()->exportPublicKey( - RsPgpId(pgp_id), mem_block, mem_block_size, - false, include_signatures ) ) + if( !AuthGPG::exportPublicKey( RsPgpId(pgp_id), mem_block, mem_block_size, false, include_signatures ) ) { RsErr() << __PRETTY_FUNCTION__ << " Failure retriving certificate for id " << pgp_id @@ -1140,8 +1138,7 @@ bool p3Peers::GetPGPBase64StringAndCheckSum( rs_owner_ptr mem_block = nullptr; size_t mem_block_size = 0; - if(!AuthGPG::getAuthGPG()->exportPublicKey( - gpg_id,mem_block,mem_block_size,false,false )) + if(!AuthGPG::exportPublicKey( gpg_id,mem_block,mem_block_size,false,false )) return false; RsBase64::encode(mem_block, mem_block_size, gpg_base64_string, true, false); @@ -1601,7 +1598,7 @@ std::string p3Peers::GetRetroshareInvite( const RsPeerId& sslId, RetroshareInvit unsigned char *mem_block = nullptr; size_t mem_block_size = 0; - if(!AuthGPG::getAuthGPG()->exportPublicKey( RsPgpId(detail.gpg_id), mem_block, mem_block_size, false, !!(invite_flags & RetroshareInviteFlags::PGP_SIGNATURES) )) + if(!AuthGPG::exportPublicKey( RsPgpId(detail.gpg_id), mem_block, mem_block_size, false, !!(invite_flags & RetroshareInviteFlags::PGP_SIGNATURES) )) { std::cerr << "Cannot output certificate for id \"" << detail.gpg_id << "\". Sorry." << std::endl; @@ -1637,7 +1634,7 @@ bool p3Peers::loadCertificateFromString( } RsPgpId gpgid; - bool res = AuthGPG::getAuthGPG()->LoadCertificateFromString( crt->armouredPGPKey(), gpgid, error_string ); + bool res = AuthGPG::LoadCertificateFromString( crt->armouredPGPKey(), gpgid, error_string ); gpg_id = gpgid; ssl_id = crt->sslid(); @@ -1654,7 +1651,7 @@ bool p3Peers::loadCertificateFromString( } bool p3Peers::loadPgpKeyFromBinaryData( const unsigned char *bin_key_data,uint32_t bin_key_len, RsPgpId& gpg_id, std::string& error_string ) { - bool res = AuthGPG::getAuthGPG()->LoadPGPKeyFromBinaryData( bin_key_data,bin_key_len, gpg_id, error_string ); + bool res = AuthGPG::LoadPGPKeyFromBinaryData( bin_key_data,bin_key_len, gpg_id, error_string ); if(res) mPeerMgr->notifyPgpKeyReceived(gpg_id); @@ -1673,9 +1670,7 @@ bool p3Peers::loadDetailsFromStringCert( const std::string &certstr, RsCertificate& cert = *certPtr; - if(!AuthGPG::getAuthGPG()->getGPGDetailsFromBinaryBlock( - cert.pgp_key(), cert.pgp_key_size(), - pd.gpg_id, pd.name, pd.gpgSigners )) + if(!AuthGPG::getGPGDetailsFromBinaryBlock( cert.pgp_key(), cert.pgp_key_size(), pd.gpg_id, pd.name, pd.gpgSigners )) return false; Dbg4() << __PRETTY_FUNCTION__ << " Parsing cert for sslid, location, ext " @@ -1753,7 +1748,7 @@ bool p3Peers::signGPGCertificate(const RsPgpId &id, const std::string &gpg_pass rsNotify->cachePgpPassphrase(gpg_passphrase); rsNotify->setDisableAskPassword(true); - bool res = AuthGPG::getAuthGPG()->SignCertificateLevel0(id); + bool res = AuthGPG::SignCertificateLevel0(id); rsNotify->clearPgpPassphrase(); rsNotify->setDisableAskPassword(false); @@ -1767,7 +1762,7 @@ bool p3Peers::trustGPGCertificate(const RsPgpId &id, uint32_t trustlvl) std::cerr << "p3Peers::TrustCertificate() " << id; std::cerr << std::endl; #endif - return AuthGPG::getAuthGPG()->TrustCertificate(id, trustlvl); + return AuthGPG::TrustCertificate(id, trustlvl); } /* Group Stuff */ diff --git a/libretroshare/src/rsserver/p3serverconfig.cc b/libretroshare/src/rsserver/p3serverconfig.cc index 6d3343dc7..7abb1e6da 100644 --- a/libretroshare/src/rsserver/p3serverconfig.cc +++ b/libretroshare/src/rsserver/p3serverconfig.cc @@ -140,7 +140,7 @@ bool p3ServerConfig::setConfigurationOption(uint32_t key, const std::string &opt int p3ServerConfig::getConfigNetStatus(RsConfigNetStatus &status) { status.ownId = AuthSSL::getAuthSSL()->OwnId(); - status.ownName = AuthGPG::getAuthGPG()->getGPGOwnName(); + status.ownName = AuthGPG::getGPGOwnName(); // Details from PeerMgr. peerState pstate; diff --git a/libretroshare/src/rsserver/rsaccounts.cc b/libretroshare/src/rsserver/rsaccounts.cc index 8be56073c..2bf306449 100644 --- a/libretroshare/src/rsserver/rsaccounts.cc +++ b/libretroshare/src/rsserver/rsaccounts.cc @@ -701,10 +701,10 @@ static bool checkAccount(const std::string &accountdir, AccountDetails &account, if(! RsAccounts::GetPGPLoginDetails(account.mPgpId, account.mPgpName, account.mPgpEmail)) return false ; - if(!AuthGPG::getAuthGPG()->haveSecretKey(account.mPgpId)) + if(!AuthGPG::haveSecretKey(account.mPgpId)) return false ; - if(!AuthGPG::getAuthGPG()->isKeySupported(account.mPgpId)) + if(!AuthGPG::isKeySupported(account.mPgpId)) { std::string keystring = account.mPgpId.toStdString() + " " + account.mPgpName + "<" + account.mPgpEmail ; unsupported_keys[keystring].push_back("Location: " + account.mLocation + "  (" + account.mSslId.toStdString() + ")") ; @@ -851,9 +851,10 @@ static bool checkAccount(const std::string &accountdir, AccountDetails &account, /* Generating GPGme Account */ -int RsAccountsDetail::GetPGPLogins(std::list &pgpIds) { - AuthGPG::getAuthGPG()->availableGPGCertificatesWithPrivateKeys(pgpIds); - return 1; +int RsAccountsDetail::GetPGPLogins(std::list& pgpIds) +{ + AuthGPG::availableGPGCertificatesWithPrivateKeys(pgpIds); + return 1; } int RsAccountsDetail::GetPGPLoginDetails(const RsPgpId& id, std::string &name, std::string &email) @@ -863,10 +864,10 @@ int RsAccountsDetail::GetPGPLoginDetails(const RsPgpId& id, std::string &na #endif bool ok = true ; - name = AuthGPG::getAuthGPG()->getGPGName(id,&ok); + name = AuthGPG::getGPGName(id,&ok); if(!ok) return 0 ; - email = AuthGPG::getAuthGPG()->getGPGEmail(id,&ok); + email = AuthGPG::getGPGEmail(id,&ok); if(!ok) return 0 ; @@ -886,7 +887,7 @@ bool RsAccountsDetail::SelectPGPAccount(const RsPgpId& pgpId) { bool retVal = false; - if (0 < AuthGPG::getAuthGPG() -> GPGInit(pgpId)) + if (0 < AuthGPG::GPGInit(pgpId)) { retVal = true; #ifdef DEBUG_ACCOUNTS @@ -906,7 +907,7 @@ bool RsAccountsDetail::SelectPGPAccount(const RsPgpId& pgpId) bool RsAccountsDetail::GeneratePGPCertificate(const std::string& name, const std::string& email, const std::string& passwd, RsPgpId &pgpId, const int keynumbits, std::string &errString) { - return AuthGPG::getAuthGPG()->GeneratePGPCertificate(name, email, passwd, pgpId, keynumbits, errString); + return AuthGPG::GeneratePGPCertificate(name, email, passwd, pgpId, keynumbits, errString); } // PGP Support Functions. @@ -918,24 +919,24 @@ void RsAccountsDetail::getUnsupportedKeys(std::mapexportProfile(fname,id); + return AuthGPG::exportProfile(fname,id); } bool RsAccountsDetail::importIdentity(const std::string& fname,RsPgpId& id,std::string& import_error) { - return AuthGPG::getAuthGPG()->importProfile(fname,id,import_error); + return AuthGPG::importProfile(fname,id,import_error); } bool RsAccountsDetail::importIdentityFromString(const std::string &data, RsPgpId &imported_pgp_id, std::string &import_error) { - return AuthGPG::getAuthGPG()->importProfileFromString(data, imported_pgp_id, import_error); + return AuthGPG::importProfileFromString(data, imported_pgp_id, import_error); } bool RsAccountsDetail::exportIdentityToString( std::string& data, const RsPgpId& pgpId, bool includeSignatures, std::string& errorMsg ) { - return AuthGPG::getAuthGPG()->exportIdentityToString( + return AuthGPG::exportIdentityToString( data, pgpId, includeSignatures, errorMsg ); } @@ -1020,7 +1021,7 @@ bool RsAccountsDetail::GenerateSSLCertificate(const RsPgpId& pgp_id, const s int nbits = 4096; - //std::string pgp_name = AuthGPG::getAuthGPG()->getGPGName(pgp_id); + //std::string pgp_name = AuthGPG::getGPGName(pgp_id); // Create the filename ..... // Temporary Directory for creating files.... diff --git a/libretroshare/src/rsserver/rsinit.cc b/libretroshare/src/rsserver/rsinit.cc index 8449a9e3e..6b12152fc 100644 --- a/libretroshare/src/rsserver/rsinit.cc +++ b/libretroshare/src/rsserver/rsinit.cc @@ -510,7 +510,7 @@ RsInit::LoadCertificateStatus RsInit::LockAndLoadCertificates( if(!RsAccounts::GetAccountDetails(accountId, pgpId, pgpName, pgpEmail, location)) throw RsInit::ERR_UNKNOWN; // invalid PreferredAccount; - if(0 == AuthGPG::getAuthGPG() -> GPGInit(pgpId)) + if(0 == AuthGPG::GPGInit(pgpId)) throw RsInit::ERR_UNKNOWN; // PGP Error. LoadCertificateStatus retVal = @@ -910,8 +910,8 @@ int RsServer::StartupRetroShare() /* History Manager */ mHistoryMgr = new p3HistoryMgr(); mPeerMgr = new p3PeerMgrIMPL( AuthSSL::getAuthSSL()->OwnId(), - AuthGPG::getAuthGPG()->getGPGOwnId(), - AuthGPG::getAuthGPG()->getGPGOwnName(), + AuthGPG::getGPGOwnId(), + AuthGPG::getGPGOwnName(), AuthSSL::getAuthSSL()->getOwnLocation()); mNetMgr = new p3NetMgrIMPL(); mLinkMgr = new p3LinkMgrIMPL(mPeerMgr, mNetMgr); @@ -1604,7 +1604,8 @@ int RsServer::StartupRetroShare() //mConfigMgr->addConfiguration("ftserver.cfg", ftserver); // - mConfigMgr->addConfiguration("gpg_prefs.cfg" , AuthGPG::getAuthGPG()); + AuthGPG::registerToConfigMgr(std::string("gpg_prefs.cfg"),mConfigMgr); + mConfigMgr->addConfiguration("gxsnettunnel.cfg", mGxsNetTunnel); mConfigMgr->addConfiguration("peers.cfg" , mPeerMgr); mConfigMgr->addConfiguration("general.cfg" , mGeneralConfig); @@ -1792,7 +1793,7 @@ int RsServer::StartupRetroShare() /* Add AuthGPG services */ /**************************************************************************/ - //AuthGPG::getAuthGPG()->addService(mDisc); + //AuthGPG::addService(mDisc); /**************************************************************************/ /* Force Any Last Configuration Options */ diff --git a/libretroshare/src/rsserver/rsloginhandler.cc b/libretroshare/src/rsserver/rsloginhandler.cc index dbe023235..67b863931 100644 --- a/libretroshare/src/rsserver/rsloginhandler.cc +++ b/libretroshare/src/rsserver/rsloginhandler.cc @@ -60,8 +60,7 @@ bool RsLoginHandler::checkAndStoreSSLPasswdIntoGPGFile( return true ; } - bool ok = AuthGPG::getAuthGPG()->encryptTextToFile( - ssl_passwd, getSSLPasswdFileName(ssl_id)); + bool ok = AuthGPG::encryptTextToFile( ssl_passwd, getSSLPasswdFileName(ssl_id)); if (!ok) std::cerr << "Encrypting went wrong !" << std::endl; @@ -90,7 +89,7 @@ bool RsLoginHandler::getSSLPasswdFromGPGFile(const RsPeerId& ssl_id,std::string& #endif std::string plain; - if ( AuthGPG::getAuthGPG()->decryptTextFromFile( plain, getSSLPasswdFileName(ssl_id)) ) + if ( AuthGPG::decryptTextFromFile( plain, getSSLPasswdFileName(ssl_id)) ) { sslPassword = plain; #ifdef DEBUG_RSLOGINHANDLER diff --git a/libretroshare/src/services/p3idservice.cc b/libretroshare/src/services/p3idservice.cc index d35d3afe0..bc6a83333 100644 --- a/libretroshare/src/services/p3idservice.cc +++ b/libretroshare/src/services/p3idservice.cc @@ -1066,7 +1066,7 @@ bool p3IdService::createIdentity(uint32_t& token, RsIdentityParameters ¶ms) if(params.isPgpLinked) { - ssdata.pgp.pgpId = AuthGPG::getAuthGPG()->getGPGOwnId(); + ssdata.pgp.pgpId = AuthGPG::getGPGOwnId(); ssdata.pgp.lastCheckTs = time(nullptr); } @@ -3618,7 +3618,7 @@ RsGenExchange::ServiceCreate_Return p3IdService::service_CreateGroup( unsigned int sign_size = MAX_SIGN_SIZE; memset(signarray,0,MAX_SIGN_SIZE) ; // just in case. - int result = AuthGPG::getAuthGPG()->SignDataBin( + int result = AuthGPG::SignDataBin( static_cast(hash.toByteArray()), hash.SIZE_IN_BYTES, signarray, &sign_size, __PRETTY_FUNCTION__ ) From 020ef61297f50c2f93a419713e3972e8ae5d2a9e Mon Sep 17 00:00:00 2001 From: csoler Date: Sun, 15 Aug 2021 09:41:30 +0200 Subject: [PATCH 016/113] fixed compilation --- libretroshare/src/pgp/openpgpsdkhandler.cc | 2 -- libretroshare/src/pgp/openpgpsdkhandler.h | 2 +- libretroshare/src/pgp/pgphandler.h | 2 +- 3 files changed, 2 insertions(+), 4 deletions(-) diff --git a/libretroshare/src/pgp/openpgpsdkhandler.cc b/libretroshare/src/pgp/openpgpsdkhandler.cc index 87f3c3343..316b428af 100644 --- a/libretroshare/src/pgp/openpgpsdkhandler.cc +++ b/libretroshare/src/pgp/openpgpsdkhandler.cc @@ -61,8 +61,6 @@ static const uint32_t PGP_CERTIFICATE_LIMIT_MAX_PASSWD_SIZE = 1024 ; //#define DEBUG_PGPHANDLER 1 //#define PGPHANDLER_DSA_SUPPORT -PassphraseCallback PGPHandler::_passphrase_callback = NULL ; - ops_keyring_t *OpenPGPSDKHandler::allocateOPSKeyring() { ops_keyring_t *kr = (ops_keyring_t*)rs_malloc(sizeof(ops_keyring_t)) ; diff --git a/libretroshare/src/pgp/openpgpsdkhandler.h b/libretroshare/src/pgp/openpgpsdkhandler.h index e6c06ba84..8aff1459b 100644 --- a/libretroshare/src/pgp/openpgpsdkhandler.h +++ b/libretroshare/src/pgp/openpgpsdkhandler.h @@ -51,7 +51,7 @@ public: // Implemented API from PGPHandler // //================================================================================================// - virtual std::string makeRadixEncodedPGPKey(uint32_t key_index,bool include_signatures) override; + //virtual std::string makeRadixEncodedPGPKey(uint32_t key_index,bool include_signatures) override; virtual bool removeKeysFromPGPKeyring(const std::set& key_ids,std::string& backup_file,uint32_t& error_code) override; virtual bool availableGPGCertificatesWithPrivateKeys(std::list& ids) override; virtual bool GeneratePGPCertificate(const std::string& name, const std::string& email, const std::string& passphrase, RsPgpId& pgpId, const int keynumbits, std::string& errString) override; diff --git a/libretroshare/src/pgp/pgphandler.h b/libretroshare/src/pgp/pgphandler.h index 07b02325c..19323b142 100644 --- a/libretroshare/src/pgp/pgphandler.h +++ b/libretroshare/src/pgp/pgphandler.h @@ -91,7 +91,7 @@ public: // and given pack for proper display. // virtual bool removeKeysFromPGPKeyring(const std::set& key_ids,std::string& backup_file,uint32_t& error_code) =0; - virtual std::string makeRadixEncodedPGPKey(uint32_t key_index,bool include_signatures) =0; + //virtual std::string makeRadixEncodedPGPKey(uint32_t key_index,bool include_signatures) =0; virtual bool availableGPGCertificatesWithPrivateKeys(std::list& ids)=0; virtual bool GeneratePGPCertificate(const std::string& name, const std::string& email, const std::string& passwd, RsPgpId& pgpId, const int keynumbits, std::string& errString) =0; From f5f608dbec8086ea553d4bd4135212c595e84a1b Mon Sep 17 00:00:00 2001 From: csoler Date: Sat, 28 Aug 2021 21:39:12 +0200 Subject: [PATCH 017/113] 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 018/113] 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 b328c3a49317ee3ff383224464e87f21115e1529 Mon Sep 17 00:00:00 2001 From: csoler Date: Fri, 29 Oct 2021 18:51:40 +0200 Subject: [PATCH 019/113] renamed AuthGPG into AuthPGP --- .../src/gossipdiscovery/p3gossipdiscovery.cc | 20 +-- libretroshare/src/pgp/pgpauxutils.cc | 10 +- libretroshare/src/pqi/authgpg.cc | 124 +++++++++--------- libretroshare/src/pqi/authgpg.h | 12 +- libretroshare/src/pqi/authssl.cc | 12 +- libretroshare/src/pqi/p3peermgr.cc | 20 +-- libretroshare/src/pqi/pqissl.cc | 2 +- libretroshare/src/pqi/pqissllistener.cc | 2 +- libretroshare/src/rsserver/p3face-config.cc | 2 +- libretroshare/src/rsserver/p3peers.cc | 56 ++++---- libretroshare/src/rsserver/p3serverconfig.cc | 2 +- libretroshare/src/rsserver/rsaccounts.cc | 24 ++-- libretroshare/src/rsserver/rsinit.cc | 8 +- libretroshare/src/rsserver/rsloginhandler.cc | 4 +- libretroshare/src/services/p3idservice.cc | 4 +- 15 files changed, 151 insertions(+), 151 deletions(-) diff --git a/libretroshare/src/gossipdiscovery/p3gossipdiscovery.cc b/libretroshare/src/gossipdiscovery/p3gossipdiscovery.cc index 179a845d7..ad95f7ee3 100644 --- a/libretroshare/src/gossipdiscovery/p3gossipdiscovery.cc +++ b/libretroshare/src/gossipdiscovery/p3gossipdiscovery.cc @@ -107,7 +107,7 @@ p3discovery2::p3discovery2( addSerialType(new RsDiscSerialiser()); // Add self into PGP FriendList. - mFriendList[AuthGPG::getGPGOwnId()] = DiscPgpInfo(); + mFriendList[AuthPGP::getGPGOwnId()] = DiscPgpInfo(); } @@ -219,7 +219,7 @@ void p3discovery2::removeFriend(const RsPeerId &sslId) std::cerr << std::endl; #endif /* pgp peer without any ssl entries -> check if they are still a real friend */ - if (!(AuthGPG::isGPGAccepted(pgpId))) + if (!(AuthPGP::isGPGAccepted(pgpId))) { #ifdef P3DISC_DEBUG std::cerr << "p3discovery2::addFriend() pgpId is no longer a friend, removing"; @@ -604,8 +604,8 @@ void p3discovery2::updatePgpFriendList() std::list::iterator lit; std::map::iterator it; - RsPgpId ownPgpId = AuthGPG::getGPGOwnId(); - AuthGPG::getGPGAcceptedList(pgpList); + RsPgpId ownPgpId = AuthPGP::getGPGOwnId(); + AuthPGP::getGPGAcceptedList(pgpList); pgpList.push_back(ownPgpId); // convert to set for ordering. @@ -723,7 +723,7 @@ void p3discovery2::processPGPList(const RsPeerId &fromId, const RsDiscPgpListIte std::set::const_iterator fit; for(fit = item->pgpIdSet.ids.begin(); fit != item->pgpIdSet.ids.end(); ++fit) { - if (!AuthGPG::isPGPId(*fit)) + if (!AuthPGP::isPGPId(*fit)) { #ifdef P3DISC_DEBUG std::cerr << "p3discovery2::processPGPList() requesting certificate for PgpId: " << *fit; @@ -1058,11 +1058,11 @@ void p3discovery2::recvPGPCertificateRequest( const RsPeerId& fromId, const RsDi return; } - RsPgpId ownPgpId = AuthGPG::getGPGOwnId(); + RsPgpId ownPgpId = AuthPGP::getGPGOwnId(); for(const RsPgpId& pgpId : item->pgpIdSet.ids) if (pgpId == ownPgpId) sendPGPCertificate(pgpId, fromId); - else if(ps.vs_disc != RS_VS_DISC_OFF && AuthGPG::isGPGAccepted(pgpId)) + else if(ps.vs_disc != RS_VS_DISC_OFF && AuthPGP::isGPGAccepted(pgpId)) sendPGPCertificate(pgpId, fromId); else std::cerr << "(WW) not sending certificate " << pgpId << " asked by friend " << fromId << " because this either this cert is not a friend, or discovery is off" << std::endl; @@ -1078,7 +1078,7 @@ void p3discovery2::sendPGPCertificate(const RsPgpId &aboutId, const RsPeerId &to unsigned char *bin_data; size_t bin_len; - if(!AuthGPG::exportPublicKey(aboutId,bin_data,bin_len,false,true)) + if(!AuthPGP::exportPublicKey(aboutId,bin_data,bin_len,false,true)) { std::cerr << "(EE) cannot export public key " << aboutId << " requested by peer " << toId << std::endl; return ; @@ -1098,7 +1098,7 @@ void p3discovery2::recvPGPCertificate(const RsPeerId& fromId, RsDiscPgpKeyItem* std::string cert_name; std::list cert_signers; - if(!AuthGPG::getGPGDetailsFromBinaryBlock( (unsigned char*)item->bin_data,item->bin_len, cert_pgp_id, cert_name, cert_signers )) + if(!AuthPGP::getGPGDetailsFromBinaryBlock( (unsigned char*)item->bin_data,item->bin_len, cert_pgp_id, cert_name, cert_signers )) { std::cerr << "(EE) cannot parse own PGP key sent by " << fromId << std::endl; return; @@ -1147,7 +1147,7 @@ void p3discovery2::recvPGPCertificate(const RsPeerId& fromId, RsDiscPgpKeyItem* // otherwise the connection should already be accepted. This only happens when the short invite peer sends its own PGP key. if(det.skip_pgp_signature_validation) - AuthGPG::AllowConnection(det.gpg_id,true); + AuthPGP::AllowConnection(det.gpg_id,true); } /************* from pqiServiceMonitor *******************/ diff --git a/libretroshare/src/pgp/pgpauxutils.cc b/libretroshare/src/pgp/pgpauxutils.cc index a9c3b36f6..99d3e8880 100644 --- a/libretroshare/src/pgp/pgpauxutils.cc +++ b/libretroshare/src/pgp/pgpauxutils.cc @@ -34,7 +34,7 @@ PgpAuxUtilsImpl::PgpAuxUtilsImpl() const RsPgpId& PgpAuxUtilsImpl::getPGPOwnId() { - return AuthGPG::getGPGOwnId(); + return AuthPGP::getGPGOwnId(); } RsPgpId PgpAuxUtilsImpl::getPGPId(const RsPeerId& sslid) @@ -44,7 +44,7 @@ RsPgpId PgpAuxUtilsImpl::getPGPId(const RsPeerId& sslid) bool PgpAuxUtilsImpl::getKeyFingerprint(const RsPgpId& id,PGPFingerprintType& fp) const { - return AuthGPG::getKeyFingerprint(id, fp); + return AuthPGP::getKeyFingerprint(id, fp); } bool PgpAuxUtilsImpl::VerifySignBin(const void *data, @@ -54,17 +54,17 @@ bool PgpAuxUtilsImpl::VerifySignBin(const void *data, const PGPFingerprintType& withfingerprint) { - return AuthGPG::VerifySignBin(data, len, sign, signlen, withfingerprint); + return AuthPGP::VerifySignBin(data, len, sign, signlen, withfingerprint); } bool PgpAuxUtilsImpl::getGPGAllList(std::list &ids) { - return AuthGPG::getGPGAllList(ids); + return AuthPGP::getGPGAllList(ids); } bool PgpAuxUtilsImpl::parseSignature(unsigned char *sign, unsigned int signlen, RsPgpId& issuer) const { - return AuthGPG::parseSignature(sign,signlen,issuer); + return AuthPGP::parseSignature(sign,signlen,issuer); } diff --git a/libretroshare/src/pqi/authgpg.cc b/libretroshare/src/pqi/authgpg.cc index b870b5d1e..5e93823a4 100644 --- a/libretroshare/src/pqi/authgpg.cc +++ b/libretroshare/src/pqi/authgpg.cc @@ -46,7 +46,7 @@ //const rstime_t STORE_KEY_TIMEOUT = 1 * 60 * 60; //store key is call around every hour -AuthGPG *AuthGPG::_instance = NULL ; +AuthPGP *AuthPGP::_instance = NULL ; void cleanupZombies(int numkill); // function to cleanup zombies under OSX. @@ -54,24 +54,24 @@ void cleanupZombies(int numkill); // function to cleanup zombies under OSX. /* Function to sign X509_REQ via GPGme. */ -int AuthGPG::availableGPGCertificatesWithPrivateKeys(std::list& pgpIds) +int AuthPGP::availableGPGCertificatesWithPrivateKeys(std::list& pgpIds) { return instance()->mPgpHandler->availableGPGCertificatesWithPrivateKeys(pgpIds); } -bool AuthGPG::getGPGDetailsFromBinaryBlock(const unsigned char *mem,size_t mem_size,RsPgpId& key_id, std::string& name, std::list& signers) +bool AuthPGP::getGPGDetailsFromBinaryBlock(const unsigned char *mem,size_t mem_size,RsPgpId& key_id, std::string& name, std::list& signers) { return instance()->mPgpHandler->getGPGDetailsFromBinaryBlock(mem,mem_size,key_id,name,signers); } -void AuthGPG::registerToConfigMgr(const std::string& fname,p3ConfigMgr *CfgMgr) +void AuthPGP::registerToConfigMgr(const std::string& fname,p3ConfigMgr *CfgMgr) { CfgMgr->addConfiguration(fname, instance()); } -bool AuthGPG::decryptTextFromFile(std::string& text,const std::string& inputfile) +bool AuthPGP::decryptTextFromFile(std::string& text,const std::string& inputfile) { return instance()->mPgpHandler->decryptTextFromFile(instance()->mOwnGpgId,text,inputfile) ; } -bool AuthGPG::removeKeysFromPGPKeyring(const std::set& pgp_ids,std::string& backup_file,uint32_t& error_code) +bool AuthPGP::removeKeysFromPGPKeyring(const std::set& pgp_ids,std::string& backup_file,uint32_t& error_code) { // std::list pids ; // @@ -86,7 +86,7 @@ bool AuthGPG::removeKeysFromPGPKeyring(const std::set& pgp_ids,std::str // return instance()->mPgpHandler->decryptTextFromString(mOwnGpgId,encrypted_text,output) ; // } -bool AuthGPG::encryptTextToFile(const std::string& text,const std::string& outfile) +bool AuthPGP::encryptTextToFile(const std::string& text,const std::string& outfile) { return instance()->mPgpHandler->encryptTextToFile(instance()->mOwnGpgId,text,outfile) ; } @@ -107,7 +107,7 @@ std::string pgp_pwd_callback(void * /*hook*/, const char *uid_title, const char return password ; } -void AuthGPG::init( +void AuthPGP::init( const std::string& path_to_public_keyring, const std::string& path_to_secret_keyring, const std::string& path_to_trustdb, @@ -121,12 +121,12 @@ void AuthGPG::init( // if(cb) instance()->mPgpHandler->setPassphraseCallback(cb);else instance()->mPgpHandler->setPassphraseCallback(pgp_pwd_callback); - _instance = new AuthGPG( path_to_public_keyring, + _instance = new AuthPGP( path_to_public_keyring, path_to_secret_keyring, path_to_trustdb, pgp_lock_file ); } -void AuthGPG::exit() +void AuthPGP::exit() { if(_instance) { @@ -136,7 +136,7 @@ void AuthGPG::exit() } } -AuthGPG::AuthGPG(const std::string& path_to_public_keyring,const std::string& path_to_secret_keyring,const std::string& path_to_trustdb,const std::string& pgp_lock_file) +AuthPGP::AuthPGP(const std::string& path_to_public_keyring,const std::string& path_to_secret_keyring,const std::string& path_to_trustdb,const std::string& pgp_lock_file) :p3Config(), gpgMtxService("AuthGPG-service"), gpgMtxEngine("AuthGPG-engine"), @@ -178,7 +178,7 @@ AuthGPG::AuthGPG(const std::string& path_to_public_keyring,const std::string& pa * This function must be called successfully (return == 1) * before anything else can be done. (except above fn). */ -int AuthGPG::GPGInit(const RsPgpId &ownId) +int AuthPGP::GPGInit(const RsPgpId &ownId) { #ifdef DEBUG_AUTHGPG std::cerr << "AuthGPG::GPGInit() called with own gpg id : " << ownId.toStdString() << std::endl; @@ -197,11 +197,11 @@ int AuthGPG::GPGInit(const RsPgpId &ownId) return 1; } - AuthGPG::~AuthGPG() + AuthPGP::~AuthPGP() { } -void AuthGPG::threadTick() +void AuthPGP::threadTick() { rstime::rs_usleep(100 * 1000); //100 msec @@ -223,7 +223,7 @@ void AuthGPG::threadTick() }//if (++count >= 100 || _force_sync_database) } -void AuthGPG::processServices() +void AuthPGP::processServices() { AuthGPGOperation *operation = NULL; AuthGPGService *service = NULL; @@ -318,29 +318,29 @@ void AuthGPG::processServices() delete operation; } -bool AuthGPG::DoOwnSignature(const void *data, unsigned int datalen, void *buf_sigout, unsigned int *outl, std::string reason /* = "" */) +bool AuthPGP::DoOwnSignature(const void *data, unsigned int datalen, void *buf_sigout, unsigned int *outl, std::string reason /* = "" */) { return instance()->mPgpHandler->SignDataBin(mOwnGpgId,data,datalen,(unsigned char *)buf_sigout,outl,false,reason) ; } /* import to GnuPG and other Certificates */ -bool AuthGPG::VerifySignature(const void *data, int datalen, const void *sig, unsigned int siglen, const PGPFingerprintType& withfingerprint) +bool AuthPGP::VerifySignature(const void *data, int datalen, const void *sig, unsigned int siglen, const PGPFingerprintType& withfingerprint) { return instance()->mPgpHandler->VerifySignBin((unsigned char*)data,datalen,(unsigned char*)sig,siglen,withfingerprint) ; } -bool AuthGPG::parseSignature(const void *sig, unsigned int siglen, RsPgpId& issuer_id) +bool AuthPGP::parseSignature(const void *sig, unsigned int siglen, RsPgpId& issuer_id) { return instance()->mPgpHandler->parseSignature((unsigned char*)sig,siglen,issuer_id) ; } -bool AuthGPG::exportProfile(const std::string& fname,const RsPgpId& exported_id) +bool AuthPGP::exportProfile(const std::string& fname,const RsPgpId& exported_id) { return instance()->mPgpHandler->exportGPGKeyPair(fname,exported_id) ; } -bool AuthGPG::exportIdentityToString( +bool AuthPGP::exportIdentityToString( std::string& data, const RsPgpId& pgpId, bool includeSignatures, std::string& errorMsg ) { @@ -348,24 +348,24 @@ bool AuthGPG::exportIdentityToString( data, pgpId, includeSignatures, errorMsg); } -bool AuthGPG::importProfile(const std::string& fname,RsPgpId& imported_id,std::string& import_error) +bool AuthPGP::importProfile(const std::string& fname,RsPgpId& imported_id,std::string& import_error) { return instance()->mPgpHandler->importGPGKeyPair(fname,imported_id,import_error) ; } -bool AuthGPG::importProfileFromString(const std::string &data, RsPgpId &gpg_id, std::string &import_error) +bool AuthPGP::importProfileFromString(const std::string &data, RsPgpId &gpg_id, std::string &import_error) { return instance()->mPgpHandler->importGPGKeyPairFromString(data, gpg_id, import_error); } -bool AuthGPG::active() +bool AuthPGP::active() { RsStackMutex stack(instance()->gpgMtxData); /******* LOCKED ******/ return instance()->gpgKeySelected; } -bool AuthGPG::GeneratePGPCertificate(const std::string& name, const std::string& email, const std::string& passwd, RsPgpId& pgpId, const int keynumbits, std::string& errString) +bool AuthPGP::GeneratePGPCertificate(const std::string& name, const std::string& email, const std::string& passwd, RsPgpId& pgpId, const int keynumbits, std::string& errString) { RsStackMutex stack(instance()->gpgMtxEngine); /******* LOCKED ******/ @@ -373,7 +373,7 @@ bool AuthGPG::GeneratePGPCertificate(const std::string& name, const std::stri } /**** These Two are common */ -std::string AuthGPG::getGPGName(const RsPgpId& id,bool *success) +std::string AuthPGP::getGPGName(const RsPgpId& id,bool *success) { RsStackMutex stack(instance()->gpgMtxData); /******* LOCKED ******/ @@ -391,7 +391,7 @@ std::string AuthGPG::getGPGName(const RsPgpId& id,bool *success) } } -AuthGPG *AuthGPG::instance() +AuthPGP *AuthPGP::instance() { if(!_instance) { @@ -401,16 +401,16 @@ AuthGPG *AuthGPG::instance() return _instance; } -bool AuthGPG::isPGPId(const RsPgpId& id) +bool AuthPGP::isPGPId(const RsPgpId& id) { return instance()->mPgpHandler->isGPGId(id); } -bool AuthGPG::isPGPAccepted(const RsPgpId& id) +bool AuthPGP::isPGPAccepted(const RsPgpId& id) { return instance()->mPgpHandler->isGPGAccepted(id); } /**** These Two are common */ -std::string AuthGPG::getGPGEmail(const RsPgpId& id,bool *success) +std::string AuthPGP::getGPGEmail(const RsPgpId& id,bool *success) { RsStackMutex stack(instance()->gpgMtxData); /******* LOCKED ******/ const PGPCertificateInfo *info = instance()->mPgpHandler->getCertificateInfo(id) ; @@ -429,18 +429,18 @@ std::string AuthGPG::getGPGEmail(const RsPgpId& id,bool *success) /**** GPG versions ***/ -const RsPgpId& AuthGPG::getGPGOwnId() +const RsPgpId& AuthPGP::getGPGOwnId() { RsStackMutex stack(instance()->gpgMtxData); /******* LOCKED ******/ return instance()->mOwnGpgId ; } -std::string AuthGPG::getGPGOwnName() +std::string AuthPGP::getGPGOwnName() { return getGPGName(instance()->mOwnGpgId) ; } -bool AuthGPG::getGPGAllList(std::list &ids) +bool AuthPGP::getGPGAllList(std::list &ids) { RsStackMutex stack(instance()->gpgMtxData); /******* LOCKED ******/ @@ -448,7 +448,7 @@ bool AuthGPG::getGPGAllList(std::list &ids) return true; } -const PGPCertificateInfo *AuthGPG::getCertInfoFromStdString(const std::string& pgp_id) const +const PGPCertificateInfo *AuthPGP::getCertInfoFromStdString(const std::string& pgp_id) const { try { @@ -460,11 +460,11 @@ const PGPCertificateInfo *AuthGPG::getCertInfoFromStdString(const std::string& p return NULL ; } } -bool AuthGPG::haveSecretKey(const RsPgpId& id) +bool AuthPGP::haveSecretKey(const RsPgpId& id) { return instance()->mPgpHandler->haveSecretKey(id) ; } -bool AuthGPG::isKeySupported(const RsPgpId& id) +bool AuthPGP::isKeySupported(const RsPgpId& id) { const PGPCertificateInfo *pc = instance()->mPgpHandler->getCertificateInfo(id) ; @@ -474,7 +474,7 @@ bool AuthGPG::isKeySupported(const RsPgpId& id) return !(pc->_flags & PGPCertificateInfo::PGP_CERTIFICATE_FLAG_UNSUPPORTED_ALGORITHM) ; } -bool AuthGPG::getGPGDetails(const RsPgpId& pgp_id, RsPeerDetails &d) +bool AuthPGP::getGPGDetails(const RsPgpId& pgp_id, RsPeerDetails &d) { RsStackMutex stack(instance()->gpgMtxData); /******* LOCKED ******/ @@ -505,7 +505,7 @@ bool AuthGPG::getGPGDetails(const RsPgpId& pgp_id, RsPeerDetails &d) return true; } -bool AuthGPG::getGPGFilteredList(std::list& list,bool (*filter)(const PGPCertificateInfo&)) +bool AuthPGP::getGPGFilteredList(std::list& list,bool (*filter)(const PGPCertificateInfo&)) { return instance()->mPgpHandler->getGPGFilteredList(list,filter) ; } @@ -514,17 +514,17 @@ static bool filter_Validity(const PGPCertificateInfo& /*info*/) { return true ; static bool filter_Accepted(const PGPCertificateInfo& info) { return info._flags & PGPCertificateInfo::PGP_CERTIFICATE_FLAG_ACCEPT_CONNEXION ; } static bool filter_OwnSigned(const PGPCertificateInfo& info) { return info._flags & PGPCertificateInfo::PGP_CERTIFICATE_FLAG_HAS_OWN_SIGNATURE ; } -bool AuthGPG::getGPGValidList(std::list &ids) +bool AuthPGP::getGPGValidList(std::list &ids) { return getGPGFilteredList(ids,&filter_Validity); } -bool AuthGPG::getGPGAcceptedList(std::list &ids) +bool AuthPGP::getGPGAcceptedList(std::list &ids) { return getGPGFilteredList(ids,&filter_Accepted); } -bool AuthGPG::getGPGSignedList(std::list &ids) +bool AuthPGP::getGPGSignedList(std::list &ids) { return getGPGFilteredList(ids,&filter_OwnSigned); } @@ -557,14 +557,14 @@ bool AuthGPG::getGPGSignedList(std::list &ids) /* SKTAN : do not know how to use std::string id */ - std::string AuthGPG::SaveCertificateToString(const RsPgpId &id,bool include_signatures) + std::string AuthPGP::SaveCertificateToString(const RsPgpId &id,bool include_signatures) { RsStackMutex stack(instance()->gpgMtxEngine); /******* LOCKED ******/ return instance()->mPgpHandler->SaveCertificateToString(id,include_signatures) ; } /* import to GnuPG and other Certificates */ -bool AuthGPG::LoadPGPKeyFromBinaryData(const unsigned char *data,uint32_t data_len, RsPgpId& gpg_id,std::string& error_string) +bool AuthPGP::LoadPGPKeyFromBinaryData(const unsigned char *data,uint32_t data_len, RsPgpId& gpg_id,std::string& error_string) { RsStackMutex stack(instance()->gpgMtxEngine); /******* LOCKED ******/ @@ -578,7 +578,7 @@ bool AuthGPG::LoadPGPKeyFromBinaryData(const unsigned char *data,uint32_t data_l } /* import to GnuPG and other Certificates */ -bool AuthGPG::LoadCertificateFromString(const std::string &str, RsPgpId& gpg_id,std::string& error_string) +bool AuthPGP::LoadCertificateFromString(const std::string &str, RsPgpId& gpg_id,std::string& error_string) { RsStackMutex stack(instance()->gpgMtxEngine); /******* LOCKED ******/ @@ -605,7 +605,7 @@ bool AuthGPG::LoadCertificateFromString(const std::string &str, RsPgpId& gpg_id, /*************************************/ /* These take PGP Ids */ -bool AuthGPG::AllowConnection(const RsPgpId& gpg_id, bool accept) +bool AuthPGP::AllowConnection(const RsPgpId& gpg_id, bool accept) { #ifdef GPG_DEBUG std::cerr << "AuthGPG::AllowConnection(" << gpg_id << ")" << std::endl; @@ -625,7 +625,7 @@ bool AuthGPG::AllowConnection(const RsPgpId& gpg_id, bool accept) } /* These take PGP Ids */ -bool AuthGPG::SignCertificateLevel0(const RsPgpId &id) +bool AuthPGP::SignCertificateLevel0(const RsPgpId &id) { #ifdef GPG_DEBUG std::cerr << "AuthGPG::SignCertificat(" << id << ")" << std::endl; @@ -634,7 +634,7 @@ bool AuthGPG::SignCertificateLevel0(const RsPgpId &id) return instance()->privateSignCertificate(id) ; } -bool AuthGPG::RevokeCertificate(const RsPgpId &id) +bool AuthPGP::RevokeCertificate(const RsPgpId &id) { /* remove unused parameter warnings */ (void) id; @@ -646,7 +646,7 @@ bool AuthGPG::RevokeCertificate(const RsPgpId &id) return false; } -bool AuthGPG::TrustCertificate(const RsPgpId& id, int trustlvl) +bool AuthPGP::TrustCertificate(const RsPgpId& id, int trustlvl) { #ifdef GPG_DEBUG std::cerr << "AuthGPG::TrustCertificate(" << id << ", " << trustlvl << ")" << std::endl; @@ -654,41 +654,41 @@ bool AuthGPG::TrustCertificate(const RsPgpId& id, int trustlvl) return instance()->privateTrustCertificate(id, trustlvl) ; } -bool AuthGPG::encryptDataBin(const RsPgpId& pgp_id,const void *data, unsigned int datalen, unsigned char *sign, unsigned int *signlen) +bool AuthPGP::encryptDataBin(const RsPgpId& pgp_id,const void *data, unsigned int datalen, unsigned char *sign, unsigned int *signlen) { return instance()->mPgpHandler->encryptDataBin(RsPgpId(pgp_id),data,datalen,sign,signlen) ; } -bool AuthGPG::decryptDataBin(const void *data, unsigned int datalen, unsigned char *sign, unsigned int *signlen) +bool AuthPGP::decryptDataBin(const void *data, unsigned int datalen, unsigned char *sign, unsigned int *signlen) { return instance()->mPgpHandler->decryptDataBin(instance()->mOwnGpgId,data,datalen,sign,signlen) ; } -bool AuthGPG::SignDataBin(const void *data, unsigned int datalen, unsigned char *sign, unsigned int *signlen, std::string reason /*= ""*/) +bool AuthPGP::SignDataBin(const void *data, unsigned int datalen, unsigned char *sign, unsigned int *signlen, std::string reason /*= ""*/) { return instance()->DoOwnSignature(data, datalen, sign, signlen, reason); } -bool AuthGPG::exportPublicKey( const RsPgpId& id, unsigned char*& mem_block, size_t& mem_size, bool armoured, bool include_signatures ) +bool AuthPGP::exportPublicKey( const RsPgpId& id, unsigned char*& mem_block, size_t& mem_size, bool armoured, bool include_signatures ) { return instance()->mPgpHandler->exportPublicKey(id,mem_block,mem_size,armoured,include_signatures); } -bool AuthGPG::isPgpPubKeyAvailable(const RsPgpId& pgp_id) +bool AuthPGP::isPgpPubKeyAvailable(const RsPgpId& pgp_id) { return instance()->mPgpHandler->isPgpPubKeyAvailable(pgp_id); } -bool AuthGPG::getKeyFingerprint(const RsPgpId& id,PGPFingerprintType& fp) +bool AuthPGP::getKeyFingerprint(const RsPgpId& id,PGPFingerprintType& fp) { return instance()->mPgpHandler->getKeyFingerprint(id,fp); } -bool AuthGPG::VerifySignBin(const void *data, uint32_t datalen, unsigned char *sign, unsigned int signlen, const PGPFingerprintType& withfingerprint) +bool AuthPGP::VerifySignBin(const void *data, uint32_t datalen, unsigned char *sign, unsigned int signlen, const PGPFingerprintType& withfingerprint) { return instance()->VerifySignature(data, datalen, sign, signlen, withfingerprint); } /* Sign/Trust stuff */ -int AuthGPG::privateSignCertificate(const RsPgpId &id) +int AuthPGP::privateSignCertificate(const RsPgpId &id) { RsStackMutex stack(gpgMtxData); /******* LOCKED ******/ @@ -698,7 +698,7 @@ int AuthGPG::privateSignCertificate(const RsPgpId &id) } /* revoke the signature on Certificate */ -int AuthGPG::privateRevokeCertificate(const RsPgpId &/*id*/) +int AuthPGP::privateRevokeCertificate(const RsPgpId &/*id*/) { //RsStackMutex stack(gpgMtx); /******* LOCKED ******/ std::cerr << __PRETTY_FUNCTION__ << ": not implemented!" << std::endl; @@ -706,7 +706,7 @@ int AuthGPG::privateRevokeCertificate(const RsPgpId &/*id*/) return 0; } -int AuthGPG::privateTrustCertificate(const RsPgpId& id, int trustlvl) +int AuthPGP::privateTrustCertificate(const RsPgpId& id, int trustlvl) { RsStackMutex stack(gpgMtxData); /******* LOCKED ******/ @@ -726,18 +726,18 @@ int AuthGPG::privateTrustCertificate(const RsPgpId& id, int trustlvl) // -------------------------------- Config functions ------------------------------ // // -----------------------------------------------------------------------------------// // -RsSerialiser *AuthGPG::setupSerialiser() +RsSerialiser *AuthPGP::setupSerialiser() { RsSerialiser *rss = new RsSerialiser ; rss->addSerialType(new RsGeneralConfigSerialiser()); return rss ; } -bool AuthGPG::isGPGAccepted(const RsPgpId& id) +bool AuthPGP::isGPGAccepted(const RsPgpId& id) { return instance()->mPgpHandler->isGPGAccepted(id); } -bool AuthGPG::saveList(bool& cleanup, std::list& lst) +bool AuthPGP::saveList(bool& cleanup, std::list& lst) { #ifdef GPG_DEBUG std::cerr << "AuthGPG::saveList() called" << std::endl ; @@ -768,7 +768,7 @@ bool AuthGPG::saveList(bool& cleanup, std::list& lst) return true; } -bool AuthGPG::loadList(std::list& load) +bool AuthPGP::loadList(std::list& load) { #ifdef GPG_DEBUG std::cerr << "AuthGPG::loadList() Item Count: " << load.size() << std::endl; @@ -799,7 +799,7 @@ bool AuthGPG::loadList(std::list& load) return true; } -bool AuthGPG::addService(AuthGPGService *service) +bool AuthPGP::addService(AuthGPGService *service) { RsStackMutex stack(instance()->gpgMtxService); /********* LOCKED *********/ diff --git a/libretroshare/src/pqi/authgpg.h b/libretroshare/src/pqi/authgpg.h index 177f71663..d124efdd4 100644 --- a/libretroshare/src/pqi/authgpg.h +++ b/libretroshare/src/pqi/authgpg.h @@ -89,7 +89,7 @@ public: virtual void setGPGOperation(AuthGPGOperation *operation) = 0; }; -class AuthGPG: public p3Config, public RsTickingThread +class AuthPGP: public p3Config, public RsTickingThread { public: static void init(const std::string& path_to_pubring, @@ -237,11 +237,11 @@ public: static bool addService(AuthGPGService *service) ; // This is for debug purpose only. Don't use it !! - static void setAuthGPG_debug(AuthGPG *auth_gpg) { _instance = auth_gpg ; } + static void setAuthGPG_debug(AuthPGP *auth_gpg) { _instance = auth_gpg ; } protected: - AuthGPG(const std::string& path_to_pubring, const std::string& path_to_secring,const std::string& path_to_trustdb,const std::string& pgp_lock_file); - virtual ~AuthGPG(); + AuthPGP(const std::string& path_to_pubring, const std::string& path_to_secring,const std::string& path_to_trustdb,const std::string& pgp_lock_file); + virtual ~AuthPGP(); /*****************************************************************/ /*********************** p3config ******************************/ @@ -286,7 +286,7 @@ private: void threadTick() override; /// @see RsTickingThread private: - static AuthGPG *instance(); + static AuthPGP *instance(); RsMutex gpgMtxService; RsMutex gpgMtxEngine; @@ -310,7 +310,7 @@ private: std::list services ; - static AuthGPG *_instance ; + static AuthPGP *_instance ; }; #endif diff --git a/libretroshare/src/pqi/authssl.cc b/libretroshare/src/pqi/authssl.cc index 6d14d0043..47eea9e58 100644 --- a/libretroshare/src/pqi/authssl.cc +++ b/libretroshare/src/pqi/authssl.cc @@ -759,7 +759,7 @@ X509 *AuthSSLimpl::SignX509ReqWithGPG(X509_REQ *req, long /*days*/) //long version = 0x00; unsigned long chtype = MBSTRING_UTF8; X509_NAME *issuer_name = X509_NAME_new(); - X509_NAME_add_entry_by_txt(issuer_name, "CN", chtype, (unsigned char *) AuthGPG::getGPGOwnId().toStdString().c_str(), -1, -1, 0); + X509_NAME_add_entry_by_txt(issuer_name, "CN", chtype, (unsigned char *) AuthPGP::getGPGOwnId().toStdString().c_str(), -1, -1, 0); /**** X509_NAME_add_entry_by_NID(issuer_name, 48, 0, (unsigned char *) "email@email.com", -1, -1, 0); @@ -769,7 +769,7 @@ X509 *AuthSSLimpl::SignX509ReqWithGPG(X509_REQ *req, long /*days*/) (unsigned char *) "loc", -1, -1, 0); ****/ - std::cerr << "AuthSSLimpl::SignX509Req() Issuer name: " << AuthGPG::getGPGOwnId().toStdString() << std::endl; + std::cerr << "AuthSSLimpl::SignX509Req() Issuer name: " << AuthPGP::getGPGOwnId().toStdString() << std::endl; #ifdef V07_NON_BACKWARD_COMPATIBLE_CHANGE_002 static const uint64_t CERTIFICATE_SERIAL_NUMBER = RS_CERTIFICATE_VERSION_NUMBER_07_0001 ; @@ -944,7 +944,7 @@ X509 *AuthSSLimpl::SignX509ReqWithGPG(X509_REQ *req, long /*days*/) std::cerr << "Buffers Allocated" << std::endl; /* NOW Sign via GPG Functions */ - if (!AuthGPG::SignDataBin(buf_in, inl, buf_sigout, (unsigned int *) &sigoutl,"AuthSSLimpl::SignX509ReqWithGPG()")) + if (!AuthPGP::SignDataBin(buf_in, inl, buf_sigout, (unsigned int *) &sigoutl,"AuthSSLimpl::SignX509ReqWithGPG()")) { sigoutl = 0; goto err; @@ -1039,7 +1039,7 @@ bool AuthSSLimpl::AuthX509WithGPG(X509 *x509,bool verbose, uint32_t& diagnostic) { RsPgpId issuer = RsX509Cert::getCertIssuer(*x509); RsPeerDetails pd; - if (!AuthGPG::getGPGDetails(issuer, pd)) + if (!AuthPGP::getGPGDetails(issuer, pd)) { RsInfo() << __PRETTY_FUNCTION__ << " X509 NOT authenticated : " << "AuthGPG::getAuthGPG()->getGPGDetails(" << issuer @@ -1184,7 +1184,7 @@ bool AuthSSLimpl::AuthX509WithGPG(X509 *x509,bool verbose, uint32_t& diagnostic) // passed, verify the signature itself - if (!AuthGPG::VerifySignBin( signed_data, signed_data_length, signature->data, static_cast(signature->length), pd.fpr )) + if (!AuthPGP::VerifySignBin( signed_data, signed_data_length, signature->data, static_cast(signature->length), pd.fpr )) { diagnostic = RS_SSL_HANDSHAKE_DIAGNOSTIC_WRONG_SIGNATURE; goto err; @@ -1380,7 +1380,7 @@ int AuthSSLimpl::VerifyX509Callback(int /*preverify_ok*/, X509_STORE_CTX* ctx) std::cerr << "******* VerifyX509Callback cert: " << std::hex << ctx->cert < gpgIds; - AuthGPG::getGPGAcceptedList(gpgIds); + AuthPGP::getGPGAcceptedList(gpgIds); // add own gpg id, if we have more than one location std::list ownSslIds; - getAssociatedPeers(AuthGPG::getGPGOwnId(), ownSslIds); + getAssociatedPeers(AuthPGP::getGPGOwnId(), ownSslIds); return gpgIds.size() + ((ownSslIds.size() > 0) ? 1 : 0); } @@ -962,7 +962,7 @@ bool p3PeerMgrIMPL::addFriend(const RsPeerId& input_id, const RsPgpId& input_gpg // check that the PGP key is known - if(!AuthGPG::isPGPId(gpg_id)) + if(!AuthPGP::isPGPId(gpg_id)) { RsErr() << "Trying to add SSL id (" << id << ") to be validated with unknown PGP key (" << gpg_id << ". This is a bug!" << std::endl; return false; @@ -970,7 +970,7 @@ bool p3PeerMgrIMPL::addFriend(const RsPeerId& input_id, const RsPgpId& input_gpg //Authentication is now tested at connection time, we don't store the ssl cert anymore // - if (!AuthGPG::isGPGAccepted(gpg_id) && gpg_id != AuthGPG::getGPGOwnId()) + if (!AuthPGP::isGPGAccepted(gpg_id) && gpg_id != AuthPGP::getGPGOwnId()) { #ifdef PEER_DEBUG std::cerr << "p3PeerMgrIMPL::addFriend() gpg is not accepted" << std::endl; @@ -1024,7 +1024,7 @@ bool p3PeerMgrIMPL::addFriend(const RsPeerId& input_id, const RsPgpId& input_gpg pstate.id = id; pstate.gpg_id = gpg_id; - pstate.name = AuthGPG::getGPGName(gpg_id); + pstate.name = AuthPGP::getGPGName(gpg_id); pstate.vs_disc = vs_disc; pstate.vs_dht = vs_dht; @@ -1126,8 +1126,8 @@ bool p3PeerMgrIMPL::addSslOnlyFriend( const RsPeerId& sslId, const RsPgpId& pgp_ * superficially set to true the PGP signature verification would have been * skipped and the attacker connection would be accepted. * If the PGP key is available add it as full friend. */ - if(AuthGPG::isPgpPubKeyAvailable(pgp_id)) - AuthGPG::AllowConnection(pgp_id, true); + if(AuthPGP::isPgpPubKeyAvailable(pgp_id)) + AuthPGP::AllowConnection(pgp_id, true); else pstate.skip_pgp_signature_validation = true; @@ -2470,7 +2470,7 @@ bool p3PeerMgrIMPL::loadList(std::list& load) setOwnNetworkMode(pitem->netMode); setOwnVisState(pitem->vs_disc, pitem->vs_dht); - mOwnState.gpg_id = AuthGPG::getGPGOwnId(); + mOwnState.gpg_id = AuthPGP::getGPGOwnId(); mOwnState.location = AuthSSL::getAuthSSL()->getOwnLocation(); } else @@ -2642,7 +2642,7 @@ bool p3PeerMgrIMPL::loadList(std::list& load) #endif for(uint32_t i=0;ipgp_ids.size();++i) - if(AuthGPG::isGPGAccepted(sitem->pgp_ids[i]) || sitem->pgp_ids[i] == AuthGPG::getGPGOwnId()) + if(AuthPGP::isGPGAccepted(sitem->pgp_ids[i]) || sitem->pgp_ids[i] == AuthPGP::getGPGOwnId()) { mFriendsPermissionFlags[sitem->pgp_ids[i]] = sitem->service_flags[i] ; #ifdef PEER_DEBUG @@ -2684,7 +2684,7 @@ bool p3PeerMgrIMPL::loadList(std::list& load) for(auto group_pair:groupList) { for(auto profileIdIt(group_pair.second.peerIds.begin());profileIdIt!=group_pair.second.peerIds.end();) - if(AuthGPG::isGPGAccepted(*profileIdIt) || *profileIdIt == AuthGPG::getGPGOwnId()) + if(AuthPGP::isGPGAccepted(*profileIdIt) || *profileIdIt == AuthPGP::getGPGOwnId()) ++profileIdIt; else { diff --git a/libretroshare/src/pqi/pqissl.cc b/libretroshare/src/pqi/pqissl.cc index b6f655692..bf91b72d9 100644 --- a/libretroshare/src/pqi/pqissl.cc +++ b/libretroshare/src/pqi/pqissl.cc @@ -1213,7 +1213,7 @@ int pqissl::Authorise_SSL_Connection() } RsPgpId pgpId = RsX509Cert::getCertIssuer(*peercert); - if( !isSslOnlyFriend && pgpId != AuthGPG::getGPGOwnId() && !AuthGPG::isGPGAccepted(pgpId) ) + if( !isSslOnlyFriend && pgpId != AuthPGP::getGPGOwnId() && !AuthPGP::isGPGAccepted(pgpId) ) { RsFatal() << __PRETTY_FUNCTION__ << " pgpId: " << pgpId << " is not friend. It is very unlikely to happen at this " diff --git a/libretroshare/src/pqi/pqissllistener.cc b/libretroshare/src/pqi/pqissllistener.cc index a9e392a56..c579280bc 100644 --- a/libretroshare/src/pqi/pqissllistener.cc +++ b/libretroshare/src/pqi/pqissllistener.cc @@ -797,7 +797,7 @@ int pqissllistener::completeConnection(int fd, IncomingSSLInfo& info) exit(failure); } - if( !isSslOnlyFriend && pgpId != AuthGPG::getGPGOwnId() && !AuthGPG::isGPGAccepted(pgpId) ) + if( !isSslOnlyFriend && pgpId != AuthPGP::getGPGOwnId() && !AuthPGP::isGPGAccepted(pgpId) ) { RsFatal() << __PRETTY_FUNCTION__ << " pgpId: " << pgpId << " is not friend. It is very unlikely to happen at this " diff --git a/libretroshare/src/rsserver/p3face-config.cc b/libretroshare/src/rsserver/p3face-config.cc index 3251f33eb..62c60815b 100644 --- a/libretroshare/src/rsserver/p3face-config.cc +++ b/libretroshare/src/rsserver/p3face-config.cc @@ -118,7 +118,7 @@ void RsServer::rsGlobalShutDown() // if(mWire) mWire->join(); // #endif - AuthGPG::exit(); + AuthPGP::exit(); mShutdownCallback(0); } diff --git a/libretroshare/src/rsserver/p3peers.cc b/libretroshare/src/rsserver/p3peers.cc index 25caac374..58dae7e44 100644 --- a/libretroshare/src/rsserver/p3peers.cc +++ b/libretroshare/src/rsserver/p3peers.cc @@ -254,7 +254,7 @@ bool p3Peers::setPeerMaximumRates(const RsPgpId& pid,uint32_t maxUploadRate,uint bool p3Peers::haveSecretKey(const RsPgpId& id) { - return AuthGPG::haveSecretKey(id); + return AuthPGP::haveSecretKey(id); } /* There are too many dependancies of this function @@ -273,7 +273,7 @@ bool p3Peers::getPeerDetails(const RsPeerId& id, RsPeerDetails &d) if (id == sOwnId) { mPeerMgr->getOwnNetStatus(ps); - ps.gpg_id = AuthGPG::getGPGOwnId(); + ps.gpg_id = AuthPGP::getGPGOwnId(); } else if (!mPeerMgr->getFriendNetStatus(id, ps)) { @@ -559,17 +559,17 @@ bool p3Peers::isProxyAddress(const uint32_t type, const sockaddr_storage& addr) bool p3Peers::isKeySupported(const RsPgpId& id) { - return AuthGPG::isKeySupported(id); + return AuthPGP::isKeySupported(id); } std::string p3Peers::getGPGName(const RsPgpId &gpg_id) { /* get from mAuthMgr as it should have more peers? */ - return AuthGPG::getGPGName(gpg_id); + return AuthPGP::getGPGName(gpg_id); } bool p3Peers::isPgpFriend(const RsPgpId& pgpId) -{ return AuthGPG::isGPGAccepted(pgpId); } +{ return AuthPGP::isGPGAccepted(pgpId); } bool p3Peers::isSslOnlyFriend(const RsPeerId& sslId) { @@ -597,7 +597,7 @@ std::string p3Peers::getPeerName(const RsPeerId& ssl) #endif std::string name; if (ssl == AuthSSL::getAuthSSL()->OwnId()) - return AuthGPG::getGPGOwnName(); + return AuthPGP::getGPGOwnName(); if (mPeerMgr->getPeerName(ssl, name)) { @@ -617,7 +617,7 @@ bool p3Peers::getGPGAllList(std::list &ids) #endif /* get from mAuthMgr */ - AuthGPG::getGPGAllList(ids); + AuthPGP::getGPGAllList(ids); return true; } @@ -628,7 +628,7 @@ bool p3Peers::getGPGValidList(std::list &ids) #endif /* get from mAuthMgr */ - AuthGPG::getGPGValidList(ids); + AuthPGP::getGPGValidList(ids); return true; } @@ -639,14 +639,14 @@ bool p3Peers::getGPGSignedList(std::list &ids) #endif /* get from mAuthMgr */ - AuthGPG::getGPGSignedList(ids); + AuthPGP::getGPGSignedList(ids); return true; } bool p3Peers::getPgpFriendList(std::vector& pgpIds) { std::list ids; - if(AuthGPG::getGPGAcceptedList(ids)) + if(AuthPGP::getGPGAcceptedList(ids)) { pgpIds.clear(); std::copy(ids.begin(), ids.end(), std::back_inserter(pgpIds)); @@ -660,7 +660,7 @@ bool p3Peers::getGPGAcceptedList(std::list &ids) #ifdef P3PEERS_DEBUG std::cerr << "p3Peers::getGPGAcceptedList()" << std::endl; #endif - AuthGPG::getGPGAcceptedList(ids); + AuthPGP::getGPGAcceptedList(ids); return true; } @@ -676,7 +676,7 @@ bool p3Peers::getAssociatedSSLIds(const RsPgpId &gpg_id, std::list &id bool p3Peers::gpgSignData(const void *data, const uint32_t len, unsigned char *sign, unsigned int *signlen, std::string reason /* = "" */) { - return AuthGPG::SignDataBin(data,len,sign,signlen, reason); + return AuthPGP::SignDataBin(data,len,sign,signlen, reason); } RsPgpId p3Peers::pgpIdFromFingerprint(const RsPgpFingerprint& fpr) @@ -691,7 +691,7 @@ bool p3Peers::getGPGDetails(const RsPgpId &pgp_id, RsPeerDetails &d) #endif /* get from mAuthMgr */ - bool res = AuthGPG::getGPGDetails(pgp_id, d); + bool res = AuthPGP::getGPGDetails(pgp_id, d); d.isOnlyGPGdetail = true ; d.service_perm_flags = mPeerMgr->servicePermissionFlags(pgp_id) ; @@ -706,7 +706,7 @@ const RsPgpId& p3Peers::getGPGOwnId() #endif /* get from mAuthMgr */ - return AuthGPG::getGPGOwnId(); + return AuthPGP::getGPGOwnId(); } RsPgpId p3Peers::getGPGId(const RsPeerId& sslid) @@ -718,7 +718,7 @@ RsPgpId p3Peers::getGPGId(const RsPeerId& sslid) /* get from mAuthMgr */ if (sslid == AuthSSL::getAuthSSL()->OwnId()) { - return AuthGPG::getGPGOwnId(); + return AuthPGP::getGPGOwnId(); } peerState pcs; if (mPeerMgr->getFriendNetStatus(sslid, pcs)) @@ -739,12 +739,12 @@ bool p3Peers::addFriend(const RsPeerId &ssl_id, const RsPgpId &gpg_id,ServicePe #ifdef P3PEERS_DEBUG std::cerr << "p3Peers::addFriend() with : id : " << id << "; gpg_id : " << gpg_id << std::endl; #endif - if(AuthGPG::isPGPId(gpg_id)) + if(AuthPGP::isPGPId(gpg_id)) { #ifdef P3PEERS_DEBUG std::cerr << "p3Peers::addFriend() Authorising GPG Id: " << gpg_id << std::endl; #endif - if (AuthGPG::AllowConnection(gpg_id, true)) + if (AuthPGP::AllowConnection(gpg_id, true)) { #ifdef P3PEERS_DEBUG std::cerr << "p3Peers::addFriend() Authorization OK." << std::endl; @@ -797,7 +797,7 @@ bool p3Peers::addSslOnlyFriend( const RsPeerId& sslId, const RsPgpId& pgp_id,con bool p3Peers::removeKeysFromPGPKeyring(const std::set& pgp_ids,std::string& backup_file,uint32_t& error_code) { - return AuthGPG::removeKeysFromPGPKeyring(pgp_ids,backup_file,error_code) ; + return AuthPGP::removeKeysFromPGPKeyring(pgp_ids,backup_file,error_code) ; } bool p3Peers::removeFriendLocation(const RsPeerId &sslId) @@ -817,7 +817,7 @@ bool p3Peers::removeFriend(const RsPgpId& gpgId) #ifdef P3PEERS_DEBUG std::cerr << "p3Peers::removeFriend() " << gpgId << std::endl; #endif - if (gpgId == AuthGPG::getGPGOwnId()) { + if (gpgId == AuthPGP::getGPGOwnId()) { std::cerr << "p3Peers::removeFriend() ERROR we're not going to remove our own GPG id." << std::endl; return false; } @@ -825,7 +825,7 @@ bool p3Peers::removeFriend(const RsPgpId& gpgId) #ifdef P3PEERS_DEBUG std::cerr << "p3Peers::removeFriend() Removing GPG Id: " << gpgId << std::endl; #endif - if (AuthGPG::AllowConnection(gpgId, false)) + if (AuthPGP::AllowConnection(gpgId, false)) { #ifdef P3PEERS_DEBUG std::cerr << "p3Peers::removeFriend() OK." << std::endl; @@ -1107,7 +1107,7 @@ std::string p3Peers::getPGPKey(const RsPgpId& pgp_id,bool include_signatures) rs_owner_ptr mem_block = nullptr; size_t mem_block_size = 0; - if( !AuthGPG::exportPublicKey( RsPgpId(pgp_id), mem_block, mem_block_size, false, include_signatures ) ) + if( !AuthPGP::exportPublicKey( RsPgpId(pgp_id), mem_block, mem_block_size, false, include_signatures ) ) { RsErr() << __PRETTY_FUNCTION__ << " Failure retriving certificate for id " << pgp_id @@ -1138,7 +1138,7 @@ bool p3Peers::GetPGPBase64StringAndCheckSum( rs_owner_ptr mem_block = nullptr; size_t mem_block_size = 0; - if(!AuthGPG::exportPublicKey( gpg_id,mem_block,mem_block_size,false,false )) + if(!AuthPGP::exportPublicKey( gpg_id,mem_block,mem_block_size,false,false )) return false; RsBase64::encode(mem_block, mem_block_size, gpg_base64_string, true, false); @@ -1598,7 +1598,7 @@ std::string p3Peers::GetRetroshareInvite( const RsPeerId& sslId, RetroshareInvit unsigned char *mem_block = nullptr; size_t mem_block_size = 0; - if(!AuthGPG::exportPublicKey( RsPgpId(detail.gpg_id), mem_block, mem_block_size, false, !!(invite_flags & RetroshareInviteFlags::PGP_SIGNATURES) )) + if(!AuthPGP::exportPublicKey( RsPgpId(detail.gpg_id), mem_block, mem_block_size, false, !!(invite_flags & RetroshareInviteFlags::PGP_SIGNATURES) )) { std::cerr << "Cannot output certificate for id \"" << detail.gpg_id << "\". Sorry." << std::endl; @@ -1634,7 +1634,7 @@ bool p3Peers::loadCertificateFromString( } RsPgpId gpgid; - bool res = AuthGPG::LoadCertificateFromString( crt->armouredPGPKey(), gpgid, error_string ); + bool res = AuthPGP::LoadCertificateFromString( crt->armouredPGPKey(), gpgid, error_string ); gpg_id = gpgid; ssl_id = crt->sslid(); @@ -1651,7 +1651,7 @@ bool p3Peers::loadCertificateFromString( } bool p3Peers::loadPgpKeyFromBinaryData( const unsigned char *bin_key_data,uint32_t bin_key_len, RsPgpId& gpg_id, std::string& error_string ) { - bool res = AuthGPG::LoadPGPKeyFromBinaryData( bin_key_data,bin_key_len, gpg_id, error_string ); + bool res = AuthPGP::LoadPGPKeyFromBinaryData( bin_key_data,bin_key_len, gpg_id, error_string ); if(res) mPeerMgr->notifyPgpKeyReceived(gpg_id); @@ -1670,7 +1670,7 @@ bool p3Peers::loadDetailsFromStringCert( const std::string &certstr, RsCertificate& cert = *certPtr; - if(!AuthGPG::getGPGDetailsFromBinaryBlock( cert.pgp_key(), cert.pgp_key_size(), pd.gpg_id, pd.name, pd.gpgSigners )) + if(!AuthPGP::getGPGDetailsFromBinaryBlock( cert.pgp_key(), cert.pgp_key_size(), pd.gpg_id, pd.name, pd.gpgSigners )) return false; Dbg4() << __PRETTY_FUNCTION__ << " Parsing cert for sslid, location, ext " @@ -1748,7 +1748,7 @@ bool p3Peers::signGPGCertificate(const RsPgpId &id, const std::string &gpg_pass rsNotify->cachePgpPassphrase(gpg_passphrase); rsNotify->setDisableAskPassword(true); - bool res = AuthGPG::SignCertificateLevel0(id); + bool res = AuthPGP::SignCertificateLevel0(id); rsNotify->clearPgpPassphrase(); rsNotify->setDisableAskPassword(false); @@ -1762,7 +1762,7 @@ bool p3Peers::trustGPGCertificate(const RsPgpId &id, uint32_t trustlvl) std::cerr << "p3Peers::TrustCertificate() " << id; std::cerr << std::endl; #endif - return AuthGPG::TrustCertificate(id, trustlvl); + return AuthPGP::TrustCertificate(id, trustlvl); } /* Group Stuff */ diff --git a/libretroshare/src/rsserver/p3serverconfig.cc b/libretroshare/src/rsserver/p3serverconfig.cc index 7abb1e6da..2aa859fe1 100644 --- a/libretroshare/src/rsserver/p3serverconfig.cc +++ b/libretroshare/src/rsserver/p3serverconfig.cc @@ -140,7 +140,7 @@ bool p3ServerConfig::setConfigurationOption(uint32_t key, const std::string &opt int p3ServerConfig::getConfigNetStatus(RsConfigNetStatus &status) { status.ownId = AuthSSL::getAuthSSL()->OwnId(); - status.ownName = AuthGPG::getGPGOwnName(); + status.ownName = AuthPGP::getGPGOwnName(); // Details from PeerMgr. peerState pstate; diff --git a/libretroshare/src/rsserver/rsaccounts.cc b/libretroshare/src/rsserver/rsaccounts.cc index 2bf306449..83867b943 100644 --- a/libretroshare/src/rsserver/rsaccounts.cc +++ b/libretroshare/src/rsserver/rsaccounts.cc @@ -701,10 +701,10 @@ static bool checkAccount(const std::string &accountdir, AccountDetails &account, if(! RsAccounts::GetPGPLoginDetails(account.mPgpId, account.mPgpName, account.mPgpEmail)) return false ; - if(!AuthGPG::haveSecretKey(account.mPgpId)) + if(!AuthPGP::haveSecretKey(account.mPgpId)) return false ; - if(!AuthGPG::isKeySupported(account.mPgpId)) + if(!AuthPGP::isKeySupported(account.mPgpId)) { std::string keystring = account.mPgpId.toStdString() + " " + account.mPgpName + "<" + account.mPgpEmail ; unsupported_keys[keystring].push_back("Location: " + account.mLocation + "  (" + account.mSslId.toStdString() + ")") ; @@ -853,7 +853,7 @@ static bool checkAccount(const std::string &accountdir, AccountDetails &account, /* Generating GPGme Account */ int RsAccountsDetail::GetPGPLogins(std::list& pgpIds) { - AuthGPG::availableGPGCertificatesWithPrivateKeys(pgpIds); + AuthPGP::availableGPGCertificatesWithPrivateKeys(pgpIds); return 1; } @@ -864,10 +864,10 @@ int RsAccountsDetail::GetPGPLoginDetails(const RsPgpId& id, std::string &na #endif bool ok = true ; - name = AuthGPG::getGPGName(id,&ok); + name = AuthPGP::getGPGName(id,&ok); if(!ok) return 0 ; - email = AuthGPG::getGPGEmail(id,&ok); + email = AuthPGP::getGPGEmail(id,&ok); if(!ok) return 0 ; @@ -887,7 +887,7 @@ bool RsAccountsDetail::SelectPGPAccount(const RsPgpId& pgpId) { bool retVal = false; - if (0 < AuthGPG::GPGInit(pgpId)) + if (0 < AuthPGP::GPGInit(pgpId)) { retVal = true; #ifdef DEBUG_ACCOUNTS @@ -907,7 +907,7 @@ bool RsAccountsDetail::SelectPGPAccount(const RsPgpId& pgpId) bool RsAccountsDetail::GeneratePGPCertificate(const std::string& name, const std::string& email, const std::string& passwd, RsPgpId &pgpId, const int keynumbits, std::string &errString) { - return AuthGPG::GeneratePGPCertificate(name, email, passwd, pgpId, keynumbits, errString); + return AuthPGP::GeneratePGPCertificate(name, email, passwd, pgpId, keynumbits, errString); } // PGP Support Functions. @@ -919,24 +919,24 @@ void RsAccountsDetail::getUnsupportedKeys(std::mapOwnId(), - AuthGPG::getGPGOwnId(), - AuthGPG::getGPGOwnName(), + AuthPGP::getGPGOwnId(), + AuthPGP::getGPGOwnName(), AuthSSL::getAuthSSL()->getOwnLocation()); mNetMgr = new p3NetMgrIMPL(); mLinkMgr = new p3LinkMgrIMPL(mPeerMgr, mNetMgr); @@ -1604,7 +1604,7 @@ int RsServer::StartupRetroShare() //mConfigMgr->addConfiguration("ftserver.cfg", ftserver); // - AuthGPG::registerToConfigMgr(std::string("gpg_prefs.cfg"),mConfigMgr); + AuthPGP::registerToConfigMgr(std::string("gpg_prefs.cfg"),mConfigMgr); mConfigMgr->addConfiguration("gxsnettunnel.cfg", mGxsNetTunnel); mConfigMgr->addConfiguration("peers.cfg" , mPeerMgr); diff --git a/libretroshare/src/rsserver/rsloginhandler.cc b/libretroshare/src/rsserver/rsloginhandler.cc index 67b863931..a0834b0af 100644 --- a/libretroshare/src/rsserver/rsloginhandler.cc +++ b/libretroshare/src/rsserver/rsloginhandler.cc @@ -60,7 +60,7 @@ bool RsLoginHandler::checkAndStoreSSLPasswdIntoGPGFile( return true ; } - bool ok = AuthGPG::encryptTextToFile( ssl_passwd, getSSLPasswdFileName(ssl_id)); + bool ok = AuthPGP::encryptTextToFile( ssl_passwd, getSSLPasswdFileName(ssl_id)); if (!ok) std::cerr << "Encrypting went wrong !" << std::endl; @@ -89,7 +89,7 @@ bool RsLoginHandler::getSSLPasswdFromGPGFile(const RsPeerId& ssl_id,std::string& #endif std::string plain; - if ( AuthGPG::decryptTextFromFile( plain, getSSLPasswdFileName(ssl_id)) ) + if ( AuthPGP::decryptTextFromFile( plain, getSSLPasswdFileName(ssl_id)) ) { sslPassword = plain; #ifdef DEBUG_RSLOGINHANDLER diff --git a/libretroshare/src/services/p3idservice.cc b/libretroshare/src/services/p3idservice.cc index 981c246c4..49bfc36dc 100644 --- a/libretroshare/src/services/p3idservice.cc +++ b/libretroshare/src/services/p3idservice.cc @@ -1067,7 +1067,7 @@ bool p3IdService::createIdentity(uint32_t& token, RsIdentityParameters ¶ms) if(params.isPgpLinked) { - ssdata.pgp.pgpId = AuthGPG::getGPGOwnId(); + ssdata.pgp.pgpId = AuthPGP::getGPGOwnId(); ssdata.pgp.lastCheckTs = time(nullptr); } @@ -3619,7 +3619,7 @@ RsGenExchange::ServiceCreate_Return p3IdService::service_CreateGroup( unsigned int sign_size = MAX_SIGN_SIZE; memset(signarray,0,MAX_SIGN_SIZE) ; // just in case. - int result = AuthGPG::SignDataBin( + int result = AuthPGP::SignDataBin( static_cast(hash.toByteArray()), hash.SIZE_IN_BYTES, signarray, &sign_size, __PRETTY_FUNCTION__ ) From 5e37bd42e4e9a7717f6a0b92bc86c76aaa1fd647 Mon Sep 17 00:00:00 2001 From: csoler Date: Fri, 29 Oct 2021 18:57:58 +0200 Subject: [PATCH 020/113] renamed isGPGAccepted into isPGPAccepted --- libretroshare/src/gossipdiscovery/p3gossipdiscovery.cc | 4 ++-- libretroshare/src/pqi/authgpg.cc | 8 ++------ libretroshare/src/pqi/authgpg.h | 2 -- libretroshare/src/pqi/authssl.cc | 2 +- libretroshare/src/pqi/p3peermgr.cc | 6 +++--- libretroshare/src/pqi/pqissl.cc | 2 +- libretroshare/src/pqi/pqissllistener.cc | 2 +- libretroshare/src/rsserver/p3peers.cc | 2 +- 8 files changed, 11 insertions(+), 17 deletions(-) diff --git a/libretroshare/src/gossipdiscovery/p3gossipdiscovery.cc b/libretroshare/src/gossipdiscovery/p3gossipdiscovery.cc index ad95f7ee3..3f4290dd4 100644 --- a/libretroshare/src/gossipdiscovery/p3gossipdiscovery.cc +++ b/libretroshare/src/gossipdiscovery/p3gossipdiscovery.cc @@ -219,7 +219,7 @@ void p3discovery2::removeFriend(const RsPeerId &sslId) std::cerr << std::endl; #endif /* pgp peer without any ssl entries -> check if they are still a real friend */ - if (!(AuthPGP::isGPGAccepted(pgpId))) + if (!(AuthPGP::isPGPAccepted(pgpId))) { #ifdef P3DISC_DEBUG std::cerr << "p3discovery2::addFriend() pgpId is no longer a friend, removing"; @@ -1062,7 +1062,7 @@ void p3discovery2::recvPGPCertificateRequest( const RsPeerId& fromId, const RsDi for(const RsPgpId& pgpId : item->pgpIdSet.ids) if (pgpId == ownPgpId) sendPGPCertificate(pgpId, fromId); - else if(ps.vs_disc != RS_VS_DISC_OFF && AuthPGP::isGPGAccepted(pgpId)) + else if(ps.vs_disc != RS_VS_DISC_OFF && AuthPGP::isPGPAccepted(pgpId)) sendPGPCertificate(pgpId, fromId); else std::cerr << "(WW) not sending certificate " << pgpId << " asked by friend " << fromId << " because this either this cert is not a friend, or discovery is off" << std::endl; diff --git a/libretroshare/src/pqi/authgpg.cc b/libretroshare/src/pqi/authgpg.cc index 5e93823a4..1d0481112 100644 --- a/libretroshare/src/pqi/authgpg.cc +++ b/libretroshare/src/pqi/authgpg.cc @@ -405,10 +405,6 @@ bool AuthPGP::isPGPId(const RsPgpId& id) { return instance()->mPgpHandler->isGPGId(id); } -bool AuthPGP::isPGPAccepted(const RsPgpId& id) -{ - return instance()->mPgpHandler->isGPGAccepted(id); -} /**** These Two are common */ std::string AuthPGP::getGPGEmail(const RsPgpId& id,bool *success) { @@ -714,7 +710,7 @@ int AuthPGP::privateTrustCertificate(const RsPgpId& id, int trustlvl) // The trust level is only a user-defined property that has nothing to // do with the fact that we allow connections or not. - if(!isGPGAccepted(id)) + if(!isPGPAccepted(id)) return 0; int res = instance()->mPgpHandler->privateTrustCertificate(id,trustlvl) ; @@ -732,7 +728,7 @@ RsSerialiser *AuthPGP::setupSerialiser() rss->addSerialType(new RsGeneralConfigSerialiser()); return rss ; } -bool AuthPGP::isGPGAccepted(const RsPgpId& id) +bool AuthPGP::isPGPAccepted(const RsPgpId& id) { return instance()->mPgpHandler->isGPGAccepted(id); } diff --git a/libretroshare/src/pqi/authgpg.h b/libretroshare/src/pqi/authgpg.h index d124efdd4..6081600b5 100644 --- a/libretroshare/src/pqi/authgpg.h +++ b/libretroshare/src/pqi/authgpg.h @@ -155,8 +155,6 @@ public: static const RsPgpId& getGPGOwnId(); static std::string getGPGOwnName(); - static bool isGPGAccepted(const RsPgpId& id); - //virtual std::string getGPGOwnEmail(); static bool getKeyFingerprint(const RsPgpId& id,PGPFingerprintType& fp) ; static bool isKeySupported(const RsPgpId &id) ; diff --git a/libretroshare/src/pqi/authssl.cc b/libretroshare/src/pqi/authssl.cc index 47eea9e58..75dcf2fe3 100644 --- a/libretroshare/src/pqi/authssl.cc +++ b/libretroshare/src/pqi/authssl.cc @@ -1380,7 +1380,7 @@ int AuthSSLimpl::VerifyX509Callback(int /*preverify_ok*/, X509_STORE_CTX* ctx) std::cerr << "******* VerifyX509Callback cert: " << std::hex << ctx->cert <& load) #endif for(uint32_t i=0;ipgp_ids.size();++i) - if(AuthPGP::isGPGAccepted(sitem->pgp_ids[i]) || sitem->pgp_ids[i] == AuthPGP::getGPGOwnId()) + if(AuthPGP::isPGPAccepted(sitem->pgp_ids[i]) || sitem->pgp_ids[i] == AuthPGP::getGPGOwnId()) { mFriendsPermissionFlags[sitem->pgp_ids[i]] = sitem->service_flags[i] ; #ifdef PEER_DEBUG @@ -2684,7 +2684,7 @@ bool p3PeerMgrIMPL::loadList(std::list& load) for(auto group_pair:groupList) { for(auto profileIdIt(group_pair.second.peerIds.begin());profileIdIt!=group_pair.second.peerIds.end();) - if(AuthPGP::isGPGAccepted(*profileIdIt) || *profileIdIt == AuthPGP::getGPGOwnId()) + if(AuthPGP::isPGPAccepted(*profileIdIt) || *profileIdIt == AuthPGP::getGPGOwnId()) ++profileIdIt; else { diff --git a/libretroshare/src/pqi/pqissl.cc b/libretroshare/src/pqi/pqissl.cc index bf91b72d9..f56f73180 100644 --- a/libretroshare/src/pqi/pqissl.cc +++ b/libretroshare/src/pqi/pqissl.cc @@ -1213,7 +1213,7 @@ int pqissl::Authorise_SSL_Connection() } RsPgpId pgpId = RsX509Cert::getCertIssuer(*peercert); - if( !isSslOnlyFriend && pgpId != AuthPGP::getGPGOwnId() && !AuthPGP::isGPGAccepted(pgpId) ) + if( !isSslOnlyFriend && pgpId != AuthPGP::getGPGOwnId() && !AuthPGP::isPGPAccepted(pgpId) ) { RsFatal() << __PRETTY_FUNCTION__ << " pgpId: " << pgpId << " is not friend. It is very unlikely to happen at this " diff --git a/libretroshare/src/pqi/pqissllistener.cc b/libretroshare/src/pqi/pqissllistener.cc index c579280bc..8986a9a19 100644 --- a/libretroshare/src/pqi/pqissllistener.cc +++ b/libretroshare/src/pqi/pqissllistener.cc @@ -797,7 +797,7 @@ int pqissllistener::completeConnection(int fd, IncomingSSLInfo& info) exit(failure); } - if( !isSslOnlyFriend && pgpId != AuthPGP::getGPGOwnId() && !AuthPGP::isGPGAccepted(pgpId) ) + if( !isSslOnlyFriend && pgpId != AuthPGP::getGPGOwnId() && !AuthPGP::isPGPAccepted(pgpId) ) { RsFatal() << __PRETTY_FUNCTION__ << " pgpId: " << pgpId << " is not friend. It is very unlikely to happen at this " diff --git a/libretroshare/src/rsserver/p3peers.cc b/libretroshare/src/rsserver/p3peers.cc index 58dae7e44..48c0b79c2 100644 --- a/libretroshare/src/rsserver/p3peers.cc +++ b/libretroshare/src/rsserver/p3peers.cc @@ -569,7 +569,7 @@ std::string p3Peers::getGPGName(const RsPgpId &gpg_id) } bool p3Peers::isPgpFriend(const RsPgpId& pgpId) -{ return AuthPGP::isGPGAccepted(pgpId); } +{ return AuthPGP::isPGPAccepted(pgpId); } bool p3Peers::isSslOnlyFriend(const RsPeerId& sslId) { From fdac22f49cc72d443b96214e8c19f8cb17a24eaf Mon Sep 17 00:00:00 2001 From: csoler Date: Fri, 29 Oct 2021 19:02:09 +0200 Subject: [PATCH 021/113] renamed remaining *GPG* names into *PGP* --- .../src/gossipdiscovery/p3gossipdiscovery.cc | 8 +++---- libretroshare/src/pgp/pgpauxutils.cc | 4 ++-- libretroshare/src/pqi/authgpg.cc | 16 +++++++------- libretroshare/src/pqi/authgpg.h | 14 ++++++------ libretroshare/src/pqi/authssl.cc | 8 +++---- libretroshare/src/pqi/p3peermgr.cc | 12 +++++----- libretroshare/src/pqi/pqissl.cc | 2 +- libretroshare/src/pqi/pqissllistener.cc | 2 +- libretroshare/src/rsserver/p3peers.cc | 22 +++++++++---------- libretroshare/src/rsserver/p3serverconfig.cc | 2 +- libretroshare/src/rsserver/rsinit.cc | 4 ++-- libretroshare/src/services/p3idservice.cc | 2 +- 12 files changed, 48 insertions(+), 48 deletions(-) diff --git a/libretroshare/src/gossipdiscovery/p3gossipdiscovery.cc b/libretroshare/src/gossipdiscovery/p3gossipdiscovery.cc index 3f4290dd4..b14efb550 100644 --- a/libretroshare/src/gossipdiscovery/p3gossipdiscovery.cc +++ b/libretroshare/src/gossipdiscovery/p3gossipdiscovery.cc @@ -107,7 +107,7 @@ p3discovery2::p3discovery2( addSerialType(new RsDiscSerialiser()); // Add self into PGP FriendList. - mFriendList[AuthPGP::getGPGOwnId()] = DiscPgpInfo(); + mFriendList[AuthPGP::getPGPOwnId()] = DiscPgpInfo(); } @@ -604,8 +604,8 @@ void p3discovery2::updatePgpFriendList() std::list::iterator lit; std::map::iterator it; - RsPgpId ownPgpId = AuthPGP::getGPGOwnId(); - AuthPGP::getGPGAcceptedList(pgpList); + RsPgpId ownPgpId = AuthPGP::getPGPOwnId(); + AuthPGP::getPGPAcceptedList(pgpList); pgpList.push_back(ownPgpId); // convert to set for ordering. @@ -1058,7 +1058,7 @@ void p3discovery2::recvPGPCertificateRequest( const RsPeerId& fromId, const RsDi return; } - RsPgpId ownPgpId = AuthPGP::getGPGOwnId(); + RsPgpId ownPgpId = AuthPGP::getPGPOwnId(); for(const RsPgpId& pgpId : item->pgpIdSet.ids) if (pgpId == ownPgpId) sendPGPCertificate(pgpId, fromId); diff --git a/libretroshare/src/pgp/pgpauxutils.cc b/libretroshare/src/pgp/pgpauxutils.cc index 99d3e8880..a95424973 100644 --- a/libretroshare/src/pgp/pgpauxutils.cc +++ b/libretroshare/src/pgp/pgpauxutils.cc @@ -34,7 +34,7 @@ PgpAuxUtilsImpl::PgpAuxUtilsImpl() const RsPgpId& PgpAuxUtilsImpl::getPGPOwnId() { - return AuthPGP::getGPGOwnId(); + return AuthPGP::getPGPOwnId(); } RsPgpId PgpAuxUtilsImpl::getPGPId(const RsPeerId& sslid) @@ -59,7 +59,7 @@ bool PgpAuxUtilsImpl::VerifySignBin(const void *data, bool PgpAuxUtilsImpl::getGPGAllList(std::list &ids) { - return AuthPGP::getGPGAllList(ids); + return AuthPGP::getPGPAllList(ids); } bool PgpAuxUtilsImpl::parseSignature(unsigned char *sign, unsigned int signlen, RsPgpId& issuer) const diff --git a/libretroshare/src/pqi/authgpg.cc b/libretroshare/src/pqi/authgpg.cc index 1d0481112..371cebe0d 100644 --- a/libretroshare/src/pqi/authgpg.cc +++ b/libretroshare/src/pqi/authgpg.cc @@ -425,18 +425,18 @@ std::string AuthPGP::getGPGEmail(const RsPgpId& id,bool *success) /**** GPG versions ***/ -const RsPgpId& AuthPGP::getGPGOwnId() +const RsPgpId& AuthPGP::getPGPOwnId() { RsStackMutex stack(instance()->gpgMtxData); /******* LOCKED ******/ return instance()->mOwnGpgId ; } -std::string AuthPGP::getGPGOwnName() +std::string AuthPGP::getPGPOwnName() { return getGPGName(instance()->mOwnGpgId) ; } -bool AuthPGP::getGPGAllList(std::list &ids) +bool AuthPGP::getPGPAllList(std::list &ids) { RsStackMutex stack(instance()->gpgMtxData); /******* LOCKED ******/ @@ -470,7 +470,7 @@ bool AuthPGP::isKeySupported(const RsPgpId& id) return !(pc->_flags & PGPCertificateInfo::PGP_CERTIFICATE_FLAG_UNSUPPORTED_ALGORITHM) ; } -bool AuthPGP::getGPGDetails(const RsPgpId& pgp_id, RsPeerDetails &d) +bool AuthPGP::getPGPDetails(const RsPgpId& pgp_id, RsPeerDetails &d) { RsStackMutex stack(instance()->gpgMtxData); /******* LOCKED ******/ @@ -510,17 +510,17 @@ static bool filter_Validity(const PGPCertificateInfo& /*info*/) { return true ; static bool filter_Accepted(const PGPCertificateInfo& info) { return info._flags & PGPCertificateInfo::PGP_CERTIFICATE_FLAG_ACCEPT_CONNEXION ; } static bool filter_OwnSigned(const PGPCertificateInfo& info) { return info._flags & PGPCertificateInfo::PGP_CERTIFICATE_FLAG_HAS_OWN_SIGNATURE ; } -bool AuthPGP::getGPGValidList(std::list &ids) +bool AuthPGP::getPGPValidList(std::list &ids) { return getGPGFilteredList(ids,&filter_Validity); } -bool AuthPGP::getGPGAcceptedList(std::list &ids) +bool AuthPGP::getPGPAcceptedList(std::list &ids) { return getGPGFilteredList(ids,&filter_Accepted); } -bool AuthPGP::getGPGSignedList(std::list &ids) +bool AuthPGP::getPGPSignedList(std::list &ids) { return getGPGFilteredList(ids,&filter_OwnSigned); } @@ -739,7 +739,7 @@ bool AuthPGP::saveList(bool& cleanup, std::list& lst) std::cerr << "AuthGPG::saveList() called" << std::endl ; #endif std::list ids ; - getGPGAcceptedList(ids) ; // needs to be done before the lock + getPGPAcceptedList(ids) ; // needs to be done before the lock RsStackMutex stack(gpgMtxData); /******* LOCKED ******/ diff --git a/libretroshare/src/pqi/authgpg.h b/libretroshare/src/pqi/authgpg.h index 6081600b5..a94d0161f 100644 --- a/libretroshare/src/pqi/authgpg.h +++ b/libretroshare/src/pqi/authgpg.h @@ -152,19 +152,19 @@ public: static bool exportPublicKey( const RsPgpId& id, unsigned char*& mem_block, size_t& mem_size, bool armoured, bool include_signatures ); /* PGP web of trust management */ - static const RsPgpId& getGPGOwnId(); - static std::string getGPGOwnName(); + static const RsPgpId& getPGPOwnId(); + static std::string getPGPOwnName(); //virtual std::string getGPGOwnEmail(); static bool getKeyFingerprint(const RsPgpId& id,PGPFingerprintType& fp) ; static bool isKeySupported(const RsPgpId &id) ; static bool isPgpPubKeyAvailable(const RsPgpId& pgp_id); static bool haveSecretKey(const RsPgpId &id) ; - static bool getGPGDetails(const RsPgpId& id, RsPeerDetails &d); - static bool getGPGAllList(std::list &ids); - static bool getGPGValidList(std::list &ids); - static bool getGPGAcceptedList(std::list &ids); - static bool getGPGSignedList(std::list &ids); + static bool getPGPDetails(const RsPgpId& id, RsPeerDetails &d); + static bool getPGPAllList(std::list &ids); + static bool getPGPValidList(std::list &ids); + static bool getPGPAcceptedList(std::list &ids); + static bool getPGPSignedList(std::list &ids); static bool importProfile(const std::string& filename,RsPgpId& gpg_id,std::string& import_error) ; static bool importProfileFromString(const std::string& data,RsPgpId& gpg_id,std::string& import_error) ; static bool exportProfile(const std::string& filename,const RsPgpId& gpg_id) ; diff --git a/libretroshare/src/pqi/authssl.cc b/libretroshare/src/pqi/authssl.cc index 75dcf2fe3..cfded5951 100644 --- a/libretroshare/src/pqi/authssl.cc +++ b/libretroshare/src/pqi/authssl.cc @@ -759,7 +759,7 @@ X509 *AuthSSLimpl::SignX509ReqWithGPG(X509_REQ *req, long /*days*/) //long version = 0x00; unsigned long chtype = MBSTRING_UTF8; X509_NAME *issuer_name = X509_NAME_new(); - X509_NAME_add_entry_by_txt(issuer_name, "CN", chtype, (unsigned char *) AuthPGP::getGPGOwnId().toStdString().c_str(), -1, -1, 0); + X509_NAME_add_entry_by_txt(issuer_name, "CN", chtype, (unsigned char *) AuthPGP::getPGPOwnId().toStdString().c_str(), -1, -1, 0); /**** X509_NAME_add_entry_by_NID(issuer_name, 48, 0, (unsigned char *) "email@email.com", -1, -1, 0); @@ -769,7 +769,7 @@ X509 *AuthSSLimpl::SignX509ReqWithGPG(X509_REQ *req, long /*days*/) (unsigned char *) "loc", -1, -1, 0); ****/ - std::cerr << "AuthSSLimpl::SignX509Req() Issuer name: " << AuthPGP::getGPGOwnId().toStdString() << std::endl; + std::cerr << "AuthSSLimpl::SignX509Req() Issuer name: " << AuthPGP::getPGPOwnId().toStdString() << std::endl; #ifdef V07_NON_BACKWARD_COMPATIBLE_CHANGE_002 static const uint64_t CERTIFICATE_SERIAL_NUMBER = RS_CERTIFICATE_VERSION_NUMBER_07_0001 ; @@ -1039,7 +1039,7 @@ bool AuthSSLimpl::AuthX509WithGPG(X509 *x509,bool verbose, uint32_t& diagnostic) { RsPgpId issuer = RsX509Cert::getCertIssuer(*x509); RsPeerDetails pd; - if (!AuthPGP::getGPGDetails(issuer, pd)) + if (!AuthPGP::getPGPDetails(issuer, pd)) { RsInfo() << __PRETTY_FUNCTION__ << " X509 NOT authenticated : " << "AuthGPG::getAuthGPG()->getGPGDetails(" << issuer @@ -1380,7 +1380,7 @@ int AuthSSLimpl::VerifyX509Callback(int /*preverify_ok*/, X509_STORE_CTX* ctx) std::cerr << "******* VerifyX509Callback cert: " << std::hex << ctx->cert < gpgIds; - AuthPGP::getGPGAcceptedList(gpgIds); + AuthPGP::getPGPAcceptedList(gpgIds); // add own gpg id, if we have more than one location std::list ownSslIds; - getAssociatedPeers(AuthPGP::getGPGOwnId(), ownSslIds); + getAssociatedPeers(AuthPGP::getPGPOwnId(), ownSslIds); return gpgIds.size() + ((ownSslIds.size() > 0) ? 1 : 0); } @@ -970,7 +970,7 @@ bool p3PeerMgrIMPL::addFriend(const RsPeerId& input_id, const RsPgpId& input_gpg //Authentication is now tested at connection time, we don't store the ssl cert anymore // - if (!AuthPGP::isPGPAccepted(gpg_id) && gpg_id != AuthPGP::getGPGOwnId()) + if (!AuthPGP::isPGPAccepted(gpg_id) && gpg_id != AuthPGP::getPGPOwnId()) { #ifdef PEER_DEBUG std::cerr << "p3PeerMgrIMPL::addFriend() gpg is not accepted" << std::endl; @@ -2470,7 +2470,7 @@ bool p3PeerMgrIMPL::loadList(std::list& load) setOwnNetworkMode(pitem->netMode); setOwnVisState(pitem->vs_disc, pitem->vs_dht); - mOwnState.gpg_id = AuthPGP::getGPGOwnId(); + mOwnState.gpg_id = AuthPGP::getPGPOwnId(); mOwnState.location = AuthSSL::getAuthSSL()->getOwnLocation(); } else @@ -2642,7 +2642,7 @@ bool p3PeerMgrIMPL::loadList(std::list& load) #endif for(uint32_t i=0;ipgp_ids.size();++i) - if(AuthPGP::isPGPAccepted(sitem->pgp_ids[i]) || sitem->pgp_ids[i] == AuthPGP::getGPGOwnId()) + if(AuthPGP::isPGPAccepted(sitem->pgp_ids[i]) || sitem->pgp_ids[i] == AuthPGP::getPGPOwnId()) { mFriendsPermissionFlags[sitem->pgp_ids[i]] = sitem->service_flags[i] ; #ifdef PEER_DEBUG @@ -2684,7 +2684,7 @@ bool p3PeerMgrIMPL::loadList(std::list& load) for(auto group_pair:groupList) { for(auto profileIdIt(group_pair.second.peerIds.begin());profileIdIt!=group_pair.second.peerIds.end();) - if(AuthPGP::isPGPAccepted(*profileIdIt) || *profileIdIt == AuthPGP::getGPGOwnId()) + if(AuthPGP::isPGPAccepted(*profileIdIt) || *profileIdIt == AuthPGP::getPGPOwnId()) ++profileIdIt; else { diff --git a/libretroshare/src/pqi/pqissl.cc b/libretroshare/src/pqi/pqissl.cc index f56f73180..75ed02faa 100644 --- a/libretroshare/src/pqi/pqissl.cc +++ b/libretroshare/src/pqi/pqissl.cc @@ -1213,7 +1213,7 @@ int pqissl::Authorise_SSL_Connection() } RsPgpId pgpId = RsX509Cert::getCertIssuer(*peercert); - if( !isSslOnlyFriend && pgpId != AuthPGP::getGPGOwnId() && !AuthPGP::isPGPAccepted(pgpId) ) + if( !isSslOnlyFriend && pgpId != AuthPGP::getPGPOwnId() && !AuthPGP::isPGPAccepted(pgpId) ) { RsFatal() << __PRETTY_FUNCTION__ << " pgpId: " << pgpId << " is not friend. It is very unlikely to happen at this " diff --git a/libretroshare/src/pqi/pqissllistener.cc b/libretroshare/src/pqi/pqissllistener.cc index 8986a9a19..9cf2d4aef 100644 --- a/libretroshare/src/pqi/pqissllistener.cc +++ b/libretroshare/src/pqi/pqissllistener.cc @@ -797,7 +797,7 @@ int pqissllistener::completeConnection(int fd, IncomingSSLInfo& info) exit(failure); } - if( !isSslOnlyFriend && pgpId != AuthPGP::getGPGOwnId() && !AuthPGP::isPGPAccepted(pgpId) ) + if( !isSslOnlyFriend && pgpId != AuthPGP::getPGPOwnId() && !AuthPGP::isPGPAccepted(pgpId) ) { RsFatal() << __PRETTY_FUNCTION__ << " pgpId: " << pgpId << " is not friend. It is very unlikely to happen at this " diff --git a/libretroshare/src/rsserver/p3peers.cc b/libretroshare/src/rsserver/p3peers.cc index 48c0b79c2..931b75aa6 100644 --- a/libretroshare/src/rsserver/p3peers.cc +++ b/libretroshare/src/rsserver/p3peers.cc @@ -273,7 +273,7 @@ bool p3Peers::getPeerDetails(const RsPeerId& id, RsPeerDetails &d) if (id == sOwnId) { mPeerMgr->getOwnNetStatus(ps); - ps.gpg_id = AuthPGP::getGPGOwnId(); + ps.gpg_id = AuthPGP::getPGPOwnId(); } else if (!mPeerMgr->getFriendNetStatus(id, ps)) { @@ -597,7 +597,7 @@ std::string p3Peers::getPeerName(const RsPeerId& ssl) #endif std::string name; if (ssl == AuthSSL::getAuthSSL()->OwnId()) - return AuthPGP::getGPGOwnName(); + return AuthPGP::getPGPOwnName(); if (mPeerMgr->getPeerName(ssl, name)) { @@ -617,7 +617,7 @@ bool p3Peers::getGPGAllList(std::list &ids) #endif /* get from mAuthMgr */ - AuthPGP::getGPGAllList(ids); + AuthPGP::getPGPAllList(ids); return true; } @@ -628,7 +628,7 @@ bool p3Peers::getGPGValidList(std::list &ids) #endif /* get from mAuthMgr */ - AuthPGP::getGPGValidList(ids); + AuthPGP::getPGPValidList(ids); return true; } @@ -639,14 +639,14 @@ bool p3Peers::getGPGSignedList(std::list &ids) #endif /* get from mAuthMgr */ - AuthPGP::getGPGSignedList(ids); + AuthPGP::getPGPSignedList(ids); return true; } bool p3Peers::getPgpFriendList(std::vector& pgpIds) { std::list ids; - if(AuthPGP::getGPGAcceptedList(ids)) + if(AuthPGP::getPGPAcceptedList(ids)) { pgpIds.clear(); std::copy(ids.begin(), ids.end(), std::back_inserter(pgpIds)); @@ -660,7 +660,7 @@ bool p3Peers::getGPGAcceptedList(std::list &ids) #ifdef P3PEERS_DEBUG std::cerr << "p3Peers::getGPGAcceptedList()" << std::endl; #endif - AuthPGP::getGPGAcceptedList(ids); + AuthPGP::getPGPAcceptedList(ids); return true; } @@ -691,7 +691,7 @@ bool p3Peers::getGPGDetails(const RsPgpId &pgp_id, RsPeerDetails &d) #endif /* get from mAuthMgr */ - bool res = AuthPGP::getGPGDetails(pgp_id, d); + bool res = AuthPGP::getPGPDetails(pgp_id, d); d.isOnlyGPGdetail = true ; d.service_perm_flags = mPeerMgr->servicePermissionFlags(pgp_id) ; @@ -706,7 +706,7 @@ const RsPgpId& p3Peers::getGPGOwnId() #endif /* get from mAuthMgr */ - return AuthPGP::getGPGOwnId(); + return AuthPGP::getPGPOwnId(); } RsPgpId p3Peers::getGPGId(const RsPeerId& sslid) @@ -718,7 +718,7 @@ RsPgpId p3Peers::getGPGId(const RsPeerId& sslid) /* get from mAuthMgr */ if (sslid == AuthSSL::getAuthSSL()->OwnId()) { - return AuthPGP::getGPGOwnId(); + return AuthPGP::getPGPOwnId(); } peerState pcs; if (mPeerMgr->getFriendNetStatus(sslid, pcs)) @@ -817,7 +817,7 @@ bool p3Peers::removeFriend(const RsPgpId& gpgId) #ifdef P3PEERS_DEBUG std::cerr << "p3Peers::removeFriend() " << gpgId << std::endl; #endif - if (gpgId == AuthPGP::getGPGOwnId()) { + if (gpgId == AuthPGP::getPGPOwnId()) { std::cerr << "p3Peers::removeFriend() ERROR we're not going to remove our own GPG id." << std::endl; return false; } diff --git a/libretroshare/src/rsserver/p3serverconfig.cc b/libretroshare/src/rsserver/p3serverconfig.cc index 2aa859fe1..ae48ebb16 100644 --- a/libretroshare/src/rsserver/p3serverconfig.cc +++ b/libretroshare/src/rsserver/p3serverconfig.cc @@ -140,7 +140,7 @@ bool p3ServerConfig::setConfigurationOption(uint32_t key, const std::string &opt int p3ServerConfig::getConfigNetStatus(RsConfigNetStatus &status) { status.ownId = AuthSSL::getAuthSSL()->OwnId(); - status.ownName = AuthPGP::getGPGOwnName(); + status.ownName = AuthPGP::getPGPOwnName(); // Details from PeerMgr. peerState pstate; diff --git a/libretroshare/src/rsserver/rsinit.cc b/libretroshare/src/rsserver/rsinit.cc index eb2b07790..d4d87ba60 100644 --- a/libretroshare/src/rsserver/rsinit.cc +++ b/libretroshare/src/rsserver/rsinit.cc @@ -910,8 +910,8 @@ int RsServer::StartupRetroShare() /* History Manager */ mHistoryMgr = new p3HistoryMgr(); mPeerMgr = new p3PeerMgrIMPL( AuthSSL::getAuthSSL()->OwnId(), - AuthPGP::getGPGOwnId(), - AuthPGP::getGPGOwnName(), + AuthPGP::getPGPOwnId(), + AuthPGP::getPGPOwnName(), AuthSSL::getAuthSSL()->getOwnLocation()); mNetMgr = new p3NetMgrIMPL(); mLinkMgr = new p3LinkMgrIMPL(mPeerMgr, mNetMgr); diff --git a/libretroshare/src/services/p3idservice.cc b/libretroshare/src/services/p3idservice.cc index 49bfc36dc..bffdaccde 100644 --- a/libretroshare/src/services/p3idservice.cc +++ b/libretroshare/src/services/p3idservice.cc @@ -1067,7 +1067,7 @@ bool p3IdService::createIdentity(uint32_t& token, RsIdentityParameters ¶ms) if(params.isPgpLinked) { - ssdata.pgp.pgpId = AuthPGP::getGPGOwnId(); + ssdata.pgp.pgpId = AuthPGP::getPGPOwnId(); ssdata.pgp.lastCheckTs = time(nullptr); } From 7672ffa0ecd9d2ab9ad573ae3ab19ec66976eca0 Mon Sep 17 00:00:00 2001 From: csoler Date: Fri, 29 Oct 2021 19:05:54 +0200 Subject: [PATCH 022/113] fixed casing of PGP into Pgp --- .../src/gossipdiscovery/p3gossipdiscovery.cc | 8 +++---- libretroshare/src/pgp/pgpauxutils.cc | 4 ++-- libretroshare/src/pqi/authgpg.cc | 22 ++++++++--------- libretroshare/src/pqi/authgpg.h | 18 +++++++------- libretroshare/src/pqi/authssl.cc | 8 +++---- libretroshare/src/pqi/p3peermgr.cc | 14 +++++------ libretroshare/src/pqi/pqissl.cc | 2 +- libretroshare/src/pqi/pqissllistener.cc | 2 +- libretroshare/src/rsserver/p3peers.cc | 24 +++++++++---------- libretroshare/src/rsserver/p3serverconfig.cc | 2 +- libretroshare/src/rsserver/rsaccounts.cc | 4 ++-- libretroshare/src/rsserver/rsinit.cc | 4 ++-- libretroshare/src/services/p3idservice.cc | 2 +- 13 files changed, 57 insertions(+), 57 deletions(-) diff --git a/libretroshare/src/gossipdiscovery/p3gossipdiscovery.cc b/libretroshare/src/gossipdiscovery/p3gossipdiscovery.cc index b14efb550..30e71763a 100644 --- a/libretroshare/src/gossipdiscovery/p3gossipdiscovery.cc +++ b/libretroshare/src/gossipdiscovery/p3gossipdiscovery.cc @@ -107,7 +107,7 @@ p3discovery2::p3discovery2( addSerialType(new RsDiscSerialiser()); // Add self into PGP FriendList. - mFriendList[AuthPGP::getPGPOwnId()] = DiscPgpInfo(); + mFriendList[AuthPGP::getPgpOwnId()] = DiscPgpInfo(); } @@ -604,8 +604,8 @@ void p3discovery2::updatePgpFriendList() std::list::iterator lit; std::map::iterator it; - RsPgpId ownPgpId = AuthPGP::getPGPOwnId(); - AuthPGP::getPGPAcceptedList(pgpList); + RsPgpId ownPgpId = AuthPGP::getPgpOwnId(); + AuthPGP::getPgpAcceptedList(pgpList); pgpList.push_back(ownPgpId); // convert to set for ordering. @@ -1058,7 +1058,7 @@ void p3discovery2::recvPGPCertificateRequest( const RsPeerId& fromId, const RsDi return; } - RsPgpId ownPgpId = AuthPGP::getPGPOwnId(); + RsPgpId ownPgpId = AuthPGP::getPgpOwnId(); for(const RsPgpId& pgpId : item->pgpIdSet.ids) if (pgpId == ownPgpId) sendPGPCertificate(pgpId, fromId); diff --git a/libretroshare/src/pgp/pgpauxutils.cc b/libretroshare/src/pgp/pgpauxutils.cc index a95424973..377e5261d 100644 --- a/libretroshare/src/pgp/pgpauxutils.cc +++ b/libretroshare/src/pgp/pgpauxutils.cc @@ -34,7 +34,7 @@ PgpAuxUtilsImpl::PgpAuxUtilsImpl() const RsPgpId& PgpAuxUtilsImpl::getPGPOwnId() { - return AuthPGP::getPGPOwnId(); + return AuthPGP::getPgpOwnId(); } RsPgpId PgpAuxUtilsImpl::getPGPId(const RsPeerId& sslid) @@ -59,7 +59,7 @@ bool PgpAuxUtilsImpl::VerifySignBin(const void *data, bool PgpAuxUtilsImpl::getGPGAllList(std::list &ids) { - return AuthPGP::getPGPAllList(ids); + return AuthPGP::getPgpAllList(ids); } bool PgpAuxUtilsImpl::parseSignature(unsigned char *sign, unsigned int signlen, RsPgpId& issuer) const diff --git a/libretroshare/src/pqi/authgpg.cc b/libretroshare/src/pqi/authgpg.cc index 371cebe0d..9cbcade21 100644 --- a/libretroshare/src/pqi/authgpg.cc +++ b/libretroshare/src/pqi/authgpg.cc @@ -373,7 +373,7 @@ bool AuthPGP::GeneratePGPCertificate(const std::string& name, const std::stri } /**** These Two are common */ -std::string AuthPGP::getGPGName(const RsPgpId& id,bool *success) +std::string AuthPGP::getPgpName(const RsPgpId& id,bool *success) { RsStackMutex stack(instance()->gpgMtxData); /******* LOCKED ******/ @@ -406,7 +406,7 @@ bool AuthPGP::isPGPId(const RsPgpId& id) return instance()->mPgpHandler->isGPGId(id); } /**** These Two are common */ -std::string AuthPGP::getGPGEmail(const RsPgpId& id,bool *success) +std::string AuthPGP::getPgpEmail(const RsPgpId& id,bool *success) { RsStackMutex stack(instance()->gpgMtxData); /******* LOCKED ******/ const PGPCertificateInfo *info = instance()->mPgpHandler->getCertificateInfo(id) ; @@ -425,18 +425,18 @@ std::string AuthPGP::getGPGEmail(const RsPgpId& id,bool *success) /**** GPG versions ***/ -const RsPgpId& AuthPGP::getPGPOwnId() +const RsPgpId& AuthPGP::getPgpOwnId() { RsStackMutex stack(instance()->gpgMtxData); /******* LOCKED ******/ return instance()->mOwnGpgId ; } -std::string AuthPGP::getPGPOwnName() +std::string AuthPGP::getPgpOwnName() { - return getGPGName(instance()->mOwnGpgId) ; + return getPgpName(instance()->mOwnGpgId) ; } -bool AuthPGP::getPGPAllList(std::list &ids) +bool AuthPGP::getPgpAllList(std::list &ids) { RsStackMutex stack(instance()->gpgMtxData); /******* LOCKED ******/ @@ -470,7 +470,7 @@ bool AuthPGP::isKeySupported(const RsPgpId& id) return !(pc->_flags & PGPCertificateInfo::PGP_CERTIFICATE_FLAG_UNSUPPORTED_ALGORITHM) ; } -bool AuthPGP::getPGPDetails(const RsPgpId& pgp_id, RsPeerDetails &d) +bool AuthPGP::getPgpDetails(const RsPgpId& pgp_id, RsPeerDetails &d) { RsStackMutex stack(instance()->gpgMtxData); /******* LOCKED ******/ @@ -510,17 +510,17 @@ static bool filter_Validity(const PGPCertificateInfo& /*info*/) { return true ; static bool filter_Accepted(const PGPCertificateInfo& info) { return info._flags & PGPCertificateInfo::PGP_CERTIFICATE_FLAG_ACCEPT_CONNEXION ; } static bool filter_OwnSigned(const PGPCertificateInfo& info) { return info._flags & PGPCertificateInfo::PGP_CERTIFICATE_FLAG_HAS_OWN_SIGNATURE ; } -bool AuthPGP::getPGPValidList(std::list &ids) +bool AuthPGP::getPgpValidList(std::list &ids) { return getGPGFilteredList(ids,&filter_Validity); } -bool AuthPGP::getPGPAcceptedList(std::list &ids) +bool AuthPGP::getPgpAcceptedList(std::list &ids) { return getGPGFilteredList(ids,&filter_Accepted); } -bool AuthPGP::getPGPSignedList(std::list &ids) +bool AuthPGP::getPgpSignedList(std::list &ids) { return getGPGFilteredList(ids,&filter_OwnSigned); } @@ -739,7 +739,7 @@ bool AuthPGP::saveList(bool& cleanup, std::list& lst) std::cerr << "AuthGPG::saveList() called" << std::endl ; #endif std::list ids ; - getPGPAcceptedList(ids) ; // needs to be done before the lock + getPgpAcceptedList(ids) ; // needs to be done before the lock RsStackMutex stack(gpgMtxData); /******* LOCKED ******/ diff --git a/libretroshare/src/pqi/authgpg.h b/libretroshare/src/pqi/authgpg.h index a94d0161f..5a8839b67 100644 --- a/libretroshare/src/pqi/authgpg.h +++ b/libretroshare/src/pqi/authgpg.h @@ -146,25 +146,25 @@ public: * provide access to details in cache list. * ****/ - static std::string getGPGName(const RsPgpId &pgp_id,bool *success = NULL); - static std::string getGPGEmail(const RsPgpId &pgp_id,bool *success = NULL); + static std::string getPgpName(const RsPgpId &pgp_id,bool *success = NULL); + static std::string getPgpEmail(const RsPgpId &pgp_id,bool *success = NULL); static bool exportPublicKey( const RsPgpId& id, unsigned char*& mem_block, size_t& mem_size, bool armoured, bool include_signatures ); /* PGP web of trust management */ - static const RsPgpId& getPGPOwnId(); - static std::string getPGPOwnName(); + static const RsPgpId& getPgpOwnId(); + static std::string getPgpOwnName(); //virtual std::string getGPGOwnEmail(); static bool getKeyFingerprint(const RsPgpId& id,PGPFingerprintType& fp) ; static bool isKeySupported(const RsPgpId &id) ; static bool isPgpPubKeyAvailable(const RsPgpId& pgp_id); static bool haveSecretKey(const RsPgpId &id) ; - static bool getPGPDetails(const RsPgpId& id, RsPeerDetails &d); - static bool getPGPAllList(std::list &ids); - static bool getPGPValidList(std::list &ids); - static bool getPGPAcceptedList(std::list &ids); - static bool getPGPSignedList(std::list &ids); + static bool getPgpDetails(const RsPgpId& id, RsPeerDetails &d); + static bool getPgpAllList(std::list &ids); + static bool getPgpValidList(std::list &ids); + static bool getPgpAcceptedList(std::list &ids); + static bool getPgpSignedList(std::list &ids); static bool importProfile(const std::string& filename,RsPgpId& gpg_id,std::string& import_error) ; static bool importProfileFromString(const std::string& data,RsPgpId& gpg_id,std::string& import_error) ; static bool exportProfile(const std::string& filename,const RsPgpId& gpg_id) ; diff --git a/libretroshare/src/pqi/authssl.cc b/libretroshare/src/pqi/authssl.cc index cfded5951..9d70121a3 100644 --- a/libretroshare/src/pqi/authssl.cc +++ b/libretroshare/src/pqi/authssl.cc @@ -759,7 +759,7 @@ X509 *AuthSSLimpl::SignX509ReqWithGPG(X509_REQ *req, long /*days*/) //long version = 0x00; unsigned long chtype = MBSTRING_UTF8; X509_NAME *issuer_name = X509_NAME_new(); - X509_NAME_add_entry_by_txt(issuer_name, "CN", chtype, (unsigned char *) AuthPGP::getPGPOwnId().toStdString().c_str(), -1, -1, 0); + X509_NAME_add_entry_by_txt(issuer_name, "CN", chtype, (unsigned char *) AuthPGP::getPgpOwnId().toStdString().c_str(), -1, -1, 0); /**** X509_NAME_add_entry_by_NID(issuer_name, 48, 0, (unsigned char *) "email@email.com", -1, -1, 0); @@ -769,7 +769,7 @@ X509 *AuthSSLimpl::SignX509ReqWithGPG(X509_REQ *req, long /*days*/) (unsigned char *) "loc", -1, -1, 0); ****/ - std::cerr << "AuthSSLimpl::SignX509Req() Issuer name: " << AuthPGP::getPGPOwnId().toStdString() << std::endl; + std::cerr << "AuthSSLimpl::SignX509Req() Issuer name: " << AuthPGP::getPgpOwnId().toStdString() << std::endl; #ifdef V07_NON_BACKWARD_COMPATIBLE_CHANGE_002 static const uint64_t CERTIFICATE_SERIAL_NUMBER = RS_CERTIFICATE_VERSION_NUMBER_07_0001 ; @@ -1039,7 +1039,7 @@ bool AuthSSLimpl::AuthX509WithGPG(X509 *x509,bool verbose, uint32_t& diagnostic) { RsPgpId issuer = RsX509Cert::getCertIssuer(*x509); RsPeerDetails pd; - if (!AuthPGP::getPGPDetails(issuer, pd)) + if (!AuthPGP::getPgpDetails(issuer, pd)) { RsInfo() << __PRETTY_FUNCTION__ << " X509 NOT authenticated : " << "AuthGPG::getAuthGPG()->getGPGDetails(" << issuer @@ -1380,7 +1380,7 @@ int AuthSSLimpl::VerifyX509Callback(int /*preverify_ok*/, X509_STORE_CTX* ctx) std::cerr << "******* VerifyX509Callback cert: " << std::hex << ctx->cert < gpgIds; - AuthPGP::getPGPAcceptedList(gpgIds); + AuthPGP::getPgpAcceptedList(gpgIds); // add own gpg id, if we have more than one location std::list ownSslIds; - getAssociatedPeers(AuthPGP::getPGPOwnId(), ownSslIds); + getAssociatedPeers(AuthPGP::getPgpOwnId(), ownSslIds); return gpgIds.size() + ((ownSslIds.size() > 0) ? 1 : 0); } @@ -970,7 +970,7 @@ bool p3PeerMgrIMPL::addFriend(const RsPeerId& input_id, const RsPgpId& input_gpg //Authentication is now tested at connection time, we don't store the ssl cert anymore // - if (!AuthPGP::isPGPAccepted(gpg_id) && gpg_id != AuthPGP::getPGPOwnId()) + if (!AuthPGP::isPGPAccepted(gpg_id) && gpg_id != AuthPGP::getPgpOwnId()) { #ifdef PEER_DEBUG std::cerr << "p3PeerMgrIMPL::addFriend() gpg is not accepted" << std::endl; @@ -1024,7 +1024,7 @@ bool p3PeerMgrIMPL::addFriend(const RsPeerId& input_id, const RsPgpId& input_gpg pstate.id = id; pstate.gpg_id = gpg_id; - pstate.name = AuthPGP::getGPGName(gpg_id); + pstate.name = AuthPGP::getPgpName(gpg_id); pstate.vs_disc = vs_disc; pstate.vs_dht = vs_dht; @@ -2470,7 +2470,7 @@ bool p3PeerMgrIMPL::loadList(std::list& load) setOwnNetworkMode(pitem->netMode); setOwnVisState(pitem->vs_disc, pitem->vs_dht); - mOwnState.gpg_id = AuthPGP::getPGPOwnId(); + mOwnState.gpg_id = AuthPGP::getPgpOwnId(); mOwnState.location = AuthSSL::getAuthSSL()->getOwnLocation(); } else @@ -2642,7 +2642,7 @@ bool p3PeerMgrIMPL::loadList(std::list& load) #endif for(uint32_t i=0;ipgp_ids.size();++i) - if(AuthPGP::isPGPAccepted(sitem->pgp_ids[i]) || sitem->pgp_ids[i] == AuthPGP::getPGPOwnId()) + if(AuthPGP::isPGPAccepted(sitem->pgp_ids[i]) || sitem->pgp_ids[i] == AuthPGP::getPgpOwnId()) { mFriendsPermissionFlags[sitem->pgp_ids[i]] = sitem->service_flags[i] ; #ifdef PEER_DEBUG @@ -2684,7 +2684,7 @@ bool p3PeerMgrIMPL::loadList(std::list& load) for(auto group_pair:groupList) { for(auto profileIdIt(group_pair.second.peerIds.begin());profileIdIt!=group_pair.second.peerIds.end();) - if(AuthPGP::isPGPAccepted(*profileIdIt) || *profileIdIt == AuthPGP::getPGPOwnId()) + if(AuthPGP::isPGPAccepted(*profileIdIt) || *profileIdIt == AuthPGP::getPgpOwnId()) ++profileIdIt; else { diff --git a/libretroshare/src/pqi/pqissl.cc b/libretroshare/src/pqi/pqissl.cc index 75ed02faa..60be4ae7b 100644 --- a/libretroshare/src/pqi/pqissl.cc +++ b/libretroshare/src/pqi/pqissl.cc @@ -1213,7 +1213,7 @@ int pqissl::Authorise_SSL_Connection() } RsPgpId pgpId = RsX509Cert::getCertIssuer(*peercert); - if( !isSslOnlyFriend && pgpId != AuthPGP::getPGPOwnId() && !AuthPGP::isPGPAccepted(pgpId) ) + if( !isSslOnlyFriend && pgpId != AuthPGP::getPgpOwnId() && !AuthPGP::isPGPAccepted(pgpId) ) { RsFatal() << __PRETTY_FUNCTION__ << " pgpId: " << pgpId << " is not friend. It is very unlikely to happen at this " diff --git a/libretroshare/src/pqi/pqissllistener.cc b/libretroshare/src/pqi/pqissllistener.cc index 9cf2d4aef..ad2129928 100644 --- a/libretroshare/src/pqi/pqissllistener.cc +++ b/libretroshare/src/pqi/pqissllistener.cc @@ -797,7 +797,7 @@ int pqissllistener::completeConnection(int fd, IncomingSSLInfo& info) exit(failure); } - if( !isSslOnlyFriend && pgpId != AuthPGP::getPGPOwnId() && !AuthPGP::isPGPAccepted(pgpId) ) + if( !isSslOnlyFriend && pgpId != AuthPGP::getPgpOwnId() && !AuthPGP::isPGPAccepted(pgpId) ) { RsFatal() << __PRETTY_FUNCTION__ << " pgpId: " << pgpId << " is not friend. It is very unlikely to happen at this " diff --git a/libretroshare/src/rsserver/p3peers.cc b/libretroshare/src/rsserver/p3peers.cc index 931b75aa6..50d4dc3dc 100644 --- a/libretroshare/src/rsserver/p3peers.cc +++ b/libretroshare/src/rsserver/p3peers.cc @@ -273,7 +273,7 @@ bool p3Peers::getPeerDetails(const RsPeerId& id, RsPeerDetails &d) if (id == sOwnId) { mPeerMgr->getOwnNetStatus(ps); - ps.gpg_id = AuthPGP::getPGPOwnId(); + ps.gpg_id = AuthPGP::getPgpOwnId(); } else if (!mPeerMgr->getFriendNetStatus(id, ps)) { @@ -565,7 +565,7 @@ bool p3Peers::isKeySupported(const RsPgpId& id) std::string p3Peers::getGPGName(const RsPgpId &gpg_id) { /* get from mAuthMgr as it should have more peers? */ - return AuthPGP::getGPGName(gpg_id); + return AuthPGP::getPgpName(gpg_id); } bool p3Peers::isPgpFriend(const RsPgpId& pgpId) @@ -597,7 +597,7 @@ std::string p3Peers::getPeerName(const RsPeerId& ssl) #endif std::string name; if (ssl == AuthSSL::getAuthSSL()->OwnId()) - return AuthPGP::getPGPOwnName(); + return AuthPGP::getPgpOwnName(); if (mPeerMgr->getPeerName(ssl, name)) { @@ -617,7 +617,7 @@ bool p3Peers::getGPGAllList(std::list &ids) #endif /* get from mAuthMgr */ - AuthPGP::getPGPAllList(ids); + AuthPGP::getPgpAllList(ids); return true; } @@ -628,7 +628,7 @@ bool p3Peers::getGPGValidList(std::list &ids) #endif /* get from mAuthMgr */ - AuthPGP::getPGPValidList(ids); + AuthPGP::getPgpValidList(ids); return true; } @@ -639,14 +639,14 @@ bool p3Peers::getGPGSignedList(std::list &ids) #endif /* get from mAuthMgr */ - AuthPGP::getPGPSignedList(ids); + AuthPGP::getPgpSignedList(ids); return true; } bool p3Peers::getPgpFriendList(std::vector& pgpIds) { std::list ids; - if(AuthPGP::getPGPAcceptedList(ids)) + if(AuthPGP::getPgpAcceptedList(ids)) { pgpIds.clear(); std::copy(ids.begin(), ids.end(), std::back_inserter(pgpIds)); @@ -660,7 +660,7 @@ bool p3Peers::getGPGAcceptedList(std::list &ids) #ifdef P3PEERS_DEBUG std::cerr << "p3Peers::getGPGAcceptedList()" << std::endl; #endif - AuthPGP::getPGPAcceptedList(ids); + AuthPGP::getPgpAcceptedList(ids); return true; } @@ -691,7 +691,7 @@ bool p3Peers::getGPGDetails(const RsPgpId &pgp_id, RsPeerDetails &d) #endif /* get from mAuthMgr */ - bool res = AuthPGP::getPGPDetails(pgp_id, d); + bool res = AuthPGP::getPgpDetails(pgp_id, d); d.isOnlyGPGdetail = true ; d.service_perm_flags = mPeerMgr->servicePermissionFlags(pgp_id) ; @@ -706,7 +706,7 @@ const RsPgpId& p3Peers::getGPGOwnId() #endif /* get from mAuthMgr */ - return AuthPGP::getPGPOwnId(); + return AuthPGP::getPgpOwnId(); } RsPgpId p3Peers::getGPGId(const RsPeerId& sslid) @@ -718,7 +718,7 @@ RsPgpId p3Peers::getGPGId(const RsPeerId& sslid) /* get from mAuthMgr */ if (sslid == AuthSSL::getAuthSSL()->OwnId()) { - return AuthPGP::getPGPOwnId(); + return AuthPGP::getPgpOwnId(); } peerState pcs; if (mPeerMgr->getFriendNetStatus(sslid, pcs)) @@ -817,7 +817,7 @@ bool p3Peers::removeFriend(const RsPgpId& gpgId) #ifdef P3PEERS_DEBUG std::cerr << "p3Peers::removeFriend() " << gpgId << std::endl; #endif - if (gpgId == AuthPGP::getPGPOwnId()) { + if (gpgId == AuthPGP::getPgpOwnId()) { std::cerr << "p3Peers::removeFriend() ERROR we're not going to remove our own GPG id." << std::endl; return false; } diff --git a/libretroshare/src/rsserver/p3serverconfig.cc b/libretroshare/src/rsserver/p3serverconfig.cc index ae48ebb16..c50eb2c89 100644 --- a/libretroshare/src/rsserver/p3serverconfig.cc +++ b/libretroshare/src/rsserver/p3serverconfig.cc @@ -140,7 +140,7 @@ bool p3ServerConfig::setConfigurationOption(uint32_t key, const std::string &opt int p3ServerConfig::getConfigNetStatus(RsConfigNetStatus &status) { status.ownId = AuthSSL::getAuthSSL()->OwnId(); - status.ownName = AuthPGP::getPGPOwnName(); + status.ownName = AuthPGP::getPgpOwnName(); // Details from PeerMgr. peerState pstate; diff --git a/libretroshare/src/rsserver/rsaccounts.cc b/libretroshare/src/rsserver/rsaccounts.cc index 83867b943..737254f73 100644 --- a/libretroshare/src/rsserver/rsaccounts.cc +++ b/libretroshare/src/rsserver/rsaccounts.cc @@ -864,10 +864,10 @@ int RsAccountsDetail::GetPGPLoginDetails(const RsPgpId& id, std::string &na #endif bool ok = true ; - name = AuthPGP::getGPGName(id,&ok); + name = AuthPGP::getPgpName(id,&ok); if(!ok) return 0 ; - email = AuthPGP::getGPGEmail(id,&ok); + email = AuthPGP::getPgpEmail(id,&ok); if(!ok) return 0 ; diff --git a/libretroshare/src/rsserver/rsinit.cc b/libretroshare/src/rsserver/rsinit.cc index d4d87ba60..2dc034f56 100644 --- a/libretroshare/src/rsserver/rsinit.cc +++ b/libretroshare/src/rsserver/rsinit.cc @@ -910,8 +910,8 @@ int RsServer::StartupRetroShare() /* History Manager */ mHistoryMgr = new p3HistoryMgr(); mPeerMgr = new p3PeerMgrIMPL( AuthSSL::getAuthSSL()->OwnId(), - AuthPGP::getPGPOwnId(), - AuthPGP::getPGPOwnName(), + AuthPGP::getPgpOwnId(), + AuthPGP::getPgpOwnName(), AuthSSL::getAuthSSL()->getOwnLocation()); mNetMgr = new p3NetMgrIMPL(); mLinkMgr = new p3LinkMgrIMPL(mPeerMgr, mNetMgr); diff --git a/libretroshare/src/services/p3idservice.cc b/libretroshare/src/services/p3idservice.cc index bffdaccde..b89c963b6 100644 --- a/libretroshare/src/services/p3idservice.cc +++ b/libretroshare/src/services/p3idservice.cc @@ -1067,7 +1067,7 @@ bool p3IdService::createIdentity(uint32_t& token, RsIdentityParameters ¶ms) if(params.isPgpLinked) { - ssdata.pgp.pgpId = AuthPGP::getPGPOwnId(); + ssdata.pgp.pgpId = AuthPGP::getPgpOwnId(); ssdata.pgp.lastCheckTs = time(nullptr); } From 7821b29893cf58a7246b9c6c90d9d5647878db3a Mon Sep 17 00:00:00 2001 From: csoler Date: Fri, 29 Oct 2021 20:29:18 +0200 Subject: [PATCH 023/113] fixed additional GPG->Pgp names --- libretroshare/src/gossipdiscovery/p3gossipdiscovery.cc | 2 +- libretroshare/src/gxs/rsgxsnetservice.cc | 2 +- libretroshare/src/gxs/rsgxsnetutils.cc | 4 ++-- libretroshare/src/pgp/pgpauxutils.cc | 4 ++-- libretroshare/src/pgp/pgpauxutils.h | 8 ++++---- libretroshare/src/pqi/authgpg.cc | 8 ++++---- libretroshare/src/pqi/authgpg.h | 8 ++++---- libretroshare/src/rsserver/p3peers.cc | 2 +- libretroshare/src/rsserver/rsaccounts.cc | 6 +++--- libretroshare/src/rsserver/rsinit.cc | 2 +- libretroshare/src/services/p3idservice.cc | 4 ++-- .../libretroshare/gxs/nxs_test/nxsdummyservices.cc | 4 ++-- .../libretroshare/gxs/nxs_test/nxsdummyservices.h | 4 ++-- .../libretroshare/services/gxs/FakePgpAuxUtils.cc | 8 ++++---- .../libretroshare/services/gxs/FakePgpAuxUtils.h | 4 ++-- 15 files changed, 35 insertions(+), 35 deletions(-) diff --git a/libretroshare/src/gossipdiscovery/p3gossipdiscovery.cc b/libretroshare/src/gossipdiscovery/p3gossipdiscovery.cc index 30e71763a..948fa3ccc 100644 --- a/libretroshare/src/gossipdiscovery/p3gossipdiscovery.cc +++ b/libretroshare/src/gossipdiscovery/p3gossipdiscovery.cc @@ -1098,7 +1098,7 @@ void p3discovery2::recvPGPCertificate(const RsPeerId& fromId, RsDiscPgpKeyItem* std::string cert_name; std::list cert_signers; - if(!AuthPGP::getGPGDetailsFromBinaryBlock( (unsigned char*)item->bin_data,item->bin_len, cert_pgp_id, cert_name, cert_signers )) + if(!AuthPGP::getPgpDetailsFromBinaryBlock( (unsigned char*)item->bin_data,item->bin_len, cert_pgp_id, cert_name, cert_signers )) { std::cerr << "(EE) cannot parse own PGP key sent by " << fromId << std::endl; return; diff --git a/libretroshare/src/gxs/rsgxsnetservice.cc b/libretroshare/src/gxs/rsgxsnetservice.cc index e1b70a670..6e61c72c4 100644 --- a/libretroshare/src/gxs/rsgxsnetservice.cc +++ b/libretroshare/src/gxs/rsgxsnetservice.cc @@ -4688,7 +4688,7 @@ bool RsGxsNetService::checkPermissionsForFriendGroup(const RsPeerId& sslId,const if(!grpMeta.mInternalCircle.isNull()) { RsGroupInfo ginfo ; - RsPgpId pgpId = mPgpUtils->getPGPId(sslId) ; + RsPgpId pgpId = mPgpUtils->getPgpId(sslId) ; #ifdef NXS_NET_DEBUG_4 GXSNETDEBUG_PG(sslId,grpMeta.mGroupId) << " Group internal circle: " << grpMeta.mInternalCircle << ", We're owner. Sending to everyone in the group." << std::endl; diff --git a/libretroshare/src/gxs/rsgxsnetutils.cc b/libretroshare/src/gxs/rsgxsnetutils.cc index b74abcb0f..6d759da7e 100644 --- a/libretroshare/src/gxs/rsgxsnetutils.cc +++ b/libretroshare/src/gxs/rsgxsnetutils.cc @@ -223,7 +223,7 @@ bool GrpCircleVetting::canSend( { if(mCircles->isLoaded(circleId)) { - const RsPgpId& pgpId = mPgpUtils->getPGPId(peerId); + const RsPgpId& pgpId = mPgpUtils->getPgpId(peerId); return mCircles->canSend(circleId, pgpId,should_encrypt); } @@ -302,7 +302,7 @@ bool MsgCircleIdsRequestVetting::cleared() if(filtered_out_msgs>0) std::cerr << "(WW) " << filtered_out_msgs << " messages not sent because they are signed by author(s) not member of that circle " << mCircleId << std::endl; - RsPgpId pgpId = mPgpUtils->getPGPId(mPeerId); + RsPgpId pgpId = mPgpUtils->getPgpId(mPeerId); bool can_send_res = mCircles->canSend(mCircleId, pgpId,mShouldEncrypt); if(mShouldEncrypt) // that means the circle is external diff --git a/libretroshare/src/pgp/pgpauxutils.cc b/libretroshare/src/pgp/pgpauxutils.cc index 377e5261d..c87985fab 100644 --- a/libretroshare/src/pgp/pgpauxutils.cc +++ b/libretroshare/src/pgp/pgpauxutils.cc @@ -37,7 +37,7 @@ const RsPgpId& PgpAuxUtilsImpl::getPGPOwnId() return AuthPGP::getPgpOwnId(); } -RsPgpId PgpAuxUtilsImpl::getPGPId(const RsPeerId& sslid) +RsPgpId PgpAuxUtilsImpl::getPgpId(const RsPeerId& sslid) { return rsPeers->getGPGId(sslid); } @@ -57,7 +57,7 @@ bool PgpAuxUtilsImpl::VerifySignBin(const void *data, return AuthPGP::VerifySignBin(data, len, sign, signlen, withfingerprint); } -bool PgpAuxUtilsImpl::getGPGAllList(std::list &ids) +bool PgpAuxUtilsImpl::getPgpAllList(std::list &ids) { return AuthPGP::getPgpAllList(ids); } diff --git a/libretroshare/src/pgp/pgpauxutils.h b/libretroshare/src/pgp/pgpauxutils.h index 4b188e3ae..aa897c0e1 100644 --- a/libretroshare/src/pgp/pgpauxutils.h +++ b/libretroshare/src/pgp/pgpauxutils.h @@ -35,8 +35,8 @@ class PgpAuxUtils virtual ~PgpAuxUtils(){} virtual const RsPgpId &getPGPOwnId() = 0; - virtual RsPgpId getPGPId(const RsPeerId& sslid) = 0; - virtual bool getGPGAllList(std::list &ids) = 0; + virtual RsPgpId getPgpId(const RsPeerId& sslid) = 0; + virtual bool getPgpAllList(std::list &ids) = 0; virtual bool getKeyFingerprint(const RsPgpId& id,PGPFingerprintType& fp) const = 0; virtual bool parseSignature(unsigned char *sign, unsigned int signlen, RsPgpId& issuer) const =0; @@ -49,12 +49,12 @@ public: PgpAuxUtilsImpl(); virtual const RsPgpId &getPGPOwnId(); - virtual RsPgpId getPGPId(const RsPeerId& sslid); + virtual RsPgpId getPgpId(const RsPeerId& sslid); virtual bool parseSignature(unsigned char *sign, unsigned int signlen, RsPgpId& issuer) const ; virtual bool getKeyFingerprint(const RsPgpId& id,PGPFingerprintType& fp) const; virtual bool VerifySignBin(const void *data, uint32_t len, unsigned char *sign, unsigned int signlen, const PGPFingerprintType& withfingerprint); - virtual bool getGPGAllList(std::list &ids); + virtual bool getPgpAllList(std::list &ids); }; diff --git a/libretroshare/src/pqi/authgpg.cc b/libretroshare/src/pqi/authgpg.cc index 9cbcade21..f7a6fb6c3 100644 --- a/libretroshare/src/pqi/authgpg.cc +++ b/libretroshare/src/pqi/authgpg.cc @@ -54,11 +54,11 @@ void cleanupZombies(int numkill); // function to cleanup zombies under OSX. /* Function to sign X509_REQ via GPGme. */ -int AuthPGP::availableGPGCertificatesWithPrivateKeys(std::list& pgpIds) +int AuthPGP::availablePgpCertificatesWithPrivateKeys(std::list& pgpIds) { return instance()->mPgpHandler->availableGPGCertificatesWithPrivateKeys(pgpIds); } -bool AuthPGP::getGPGDetailsFromBinaryBlock(const unsigned char *mem,size_t mem_size,RsPgpId& key_id, std::string& name, std::list& signers) +bool AuthPGP::getPgpDetailsFromBinaryBlock(const unsigned char *mem,size_t mem_size,RsPgpId& key_id, std::string& name, std::list& signers) { return instance()->mPgpHandler->getGPGDetailsFromBinaryBlock(mem,mem_size,key_id,name,signers); } @@ -178,7 +178,7 @@ AuthPGP::AuthPGP(const std::string& path_to_public_keyring,const std::string& pa * This function must be called successfully (return == 1) * before anything else can be done. (except above fn). */ -int AuthPGP::GPGInit(const RsPgpId &ownId) +int AuthPGP::PgpInit(const RsPgpId &ownId) { #ifdef DEBUG_AUTHGPG std::cerr << "AuthGPG::GPGInit() called with own gpg id : " << ownId.toStdString() << std::endl; @@ -365,7 +365,7 @@ bool AuthPGP::active() return instance()->gpgKeySelected; } -bool AuthPGP::GeneratePGPCertificate(const std::string& name, const std::string& email, const std::string& passwd, RsPgpId& pgpId, const int keynumbits, std::string& errString) +bool AuthPGP::GeneratePgpCertificate(const std::string& name, const std::string& email, const std::string& passwd, RsPgpId& pgpId, const int keynumbits, std::string& errString) { RsStackMutex stack(instance()->gpgMtxEngine); /******* LOCKED ******/ diff --git a/libretroshare/src/pqi/authgpg.h b/libretroshare/src/pqi/authgpg.h index 5a8839b67..1db1ad482 100644 --- a/libretroshare/src/pqi/authgpg.h +++ b/libretroshare/src/pqi/authgpg.h @@ -129,11 +129,11 @@ public: /* Init by generating new Own PGP Cert, or selecting existing PGP Cert */ - static int GPGInit(const RsPgpId &ownId); - static bool GeneratePGPCertificate(const std::string& name, const std::string& email, const std::string& passwd, RsPgpId &pgpId, const int keynumbits, std::string &errString); + static int PgpInit(const RsPgpId &ownId); + static bool GeneratePgpCertificate(const std::string& name, const std::string& email, const std::string& passwd, RsPgpId &pgpId, const int keynumbits, std::string &errString); - static bool getGPGDetailsFromBinaryBlock(const unsigned char *mem,size_t mem_size,RsPgpId& key_id, std::string& name, std::list& signers) ; - static int availableGPGCertificatesWithPrivateKeys(std::list& pgpIds); + static bool getPgpDetailsFromBinaryBlock(const unsigned char *mem,size_t mem_size,RsPgpId& key_id, std::string& name, std::list& signers) ; + static int availablePgpCertificatesWithPrivateKeys(std::list& pgpIds); /*********************************************************************************/ /************************* STAGE 3 ***********************************************/ diff --git a/libretroshare/src/rsserver/p3peers.cc b/libretroshare/src/rsserver/p3peers.cc index 50d4dc3dc..ff50ec091 100644 --- a/libretroshare/src/rsserver/p3peers.cc +++ b/libretroshare/src/rsserver/p3peers.cc @@ -1670,7 +1670,7 @@ bool p3Peers::loadDetailsFromStringCert( const std::string &certstr, RsCertificate& cert = *certPtr; - if(!AuthPGP::getGPGDetailsFromBinaryBlock( cert.pgp_key(), cert.pgp_key_size(), pd.gpg_id, pd.name, pd.gpgSigners )) + if(!AuthPGP::getPgpDetailsFromBinaryBlock( cert.pgp_key(), cert.pgp_key_size(), pd.gpg_id, pd.name, pd.gpgSigners )) return false; Dbg4() << __PRETTY_FUNCTION__ << " Parsing cert for sslid, location, ext " diff --git a/libretroshare/src/rsserver/rsaccounts.cc b/libretroshare/src/rsserver/rsaccounts.cc index 737254f73..32ecd1e2a 100644 --- a/libretroshare/src/rsserver/rsaccounts.cc +++ b/libretroshare/src/rsserver/rsaccounts.cc @@ -853,7 +853,7 @@ static bool checkAccount(const std::string &accountdir, AccountDetails &account, /* Generating GPGme Account */ int RsAccountsDetail::GetPGPLogins(std::list& pgpIds) { - AuthPGP::availableGPGCertificatesWithPrivateKeys(pgpIds); + AuthPGP::availablePgpCertificatesWithPrivateKeys(pgpIds); return 1; } @@ -887,7 +887,7 @@ bool RsAccountsDetail::SelectPGPAccount(const RsPgpId& pgpId) { bool retVal = false; - if (0 < AuthPGP::GPGInit(pgpId)) + if (0 < AuthPGP::PgpInit(pgpId)) { retVal = true; #ifdef DEBUG_ACCOUNTS @@ -907,7 +907,7 @@ bool RsAccountsDetail::SelectPGPAccount(const RsPgpId& pgpId) bool RsAccountsDetail::GeneratePGPCertificate(const std::string& name, const std::string& email, const std::string& passwd, RsPgpId &pgpId, const int keynumbits, std::string &errString) { - return AuthPGP::GeneratePGPCertificate(name, email, passwd, pgpId, keynumbits, errString); + return AuthPGP::GeneratePgpCertificate(name, email, passwd, pgpId, keynumbits, errString); } // PGP Support Functions. diff --git a/libretroshare/src/rsserver/rsinit.cc b/libretroshare/src/rsserver/rsinit.cc index 2dc034f56..84d2b659b 100644 --- a/libretroshare/src/rsserver/rsinit.cc +++ b/libretroshare/src/rsserver/rsinit.cc @@ -510,7 +510,7 @@ RsInit::LoadCertificateStatus RsInit::LockAndLoadCertificates( if(!RsAccounts::GetAccountDetails(accountId, pgpId, pgpName, pgpEmail, location)) throw RsInit::ERR_UNKNOWN; // invalid PreferredAccount; - if(0 == AuthPGP::GPGInit(pgpId)) + if(0 == AuthPGP::PgpInit(pgpId)) throw RsInit::ERR_UNKNOWN; // PGP Error. LoadCertificateStatus retVal = diff --git a/libretroshare/src/services/p3idservice.cc b/libretroshare/src/services/p3idservice.cc index b89c963b6..bf034bcb2 100644 --- a/libretroshare/src/services/p3idservice.cc +++ b/libretroshare/src/services/p3idservice.cc @@ -4096,7 +4096,7 @@ void p3IdService::getPgpIdList() #endif // DEBUG_IDS std::list list; - mPgpUtils->getGPGAllList(list); + mPgpUtils->getPgpAllList(list); RsStackMutex stack(mIdMtx); /********** STACK LOCKED MTX ******/ @@ -4593,7 +4593,7 @@ void p3IdService::generateDummy_FriendPGP() // Now Generate for friends. std::list gpgids; std::list::const_iterator it; - mPgpUtils->getGPGAllList(gpgids); + mPgpUtils->getPgpAllList(gpgids); RsGxsIdGroup id; diff --git a/tests/unittests/libretroshare/gxs/nxs_test/nxsdummyservices.cc b/tests/unittests/libretroshare/gxs/nxs_test/nxsdummyservices.cc index 925e90be2..442a25cc1 100644 --- a/tests/unittests/libretroshare/gxs/nxs_test/nxsdummyservices.cc +++ b/tests/unittests/libretroshare/gxs/nxs_test/nxsdummyservices.cc @@ -134,11 +134,11 @@ const RsPgpId& rs_nxs_test::RsDummyPgpUtils::getPGPOwnId() { return mOwnId; } -RsPgpId rs_nxs_test::RsDummyPgpUtils::getPGPId(const RsPeerId& /*sslid*/) { +RsPgpId rs_nxs_test::RsDummyPgpUtils::getPgpId(const RsPeerId& /*sslid*/) { return RsPgpId().random(); } -bool rs_nxs_test::RsDummyPgpUtils::getGPGAllList(std::list& /*ids*/) { +bool rs_nxs_test::RsDummyPgpUtils::getPgpAllList(std::list& /*ids*/) { return true; } diff --git a/tests/unittests/libretroshare/gxs/nxs_test/nxsdummyservices.h b/tests/unittests/libretroshare/gxs/nxs_test/nxsdummyservices.h index aee8f989e..6e993a658 100644 --- a/tests/unittests/libretroshare/gxs/nxs_test/nxsdummyservices.h +++ b/tests/unittests/libretroshare/gxs/nxs_test/nxsdummyservices.h @@ -164,8 +164,8 @@ namespace rs_nxs_test virtual ~RsDummyPgpUtils(){} const RsPgpId &getPGPOwnId() ; - RsPgpId getPGPId(const RsPeerId& sslid) ; - bool getGPGAllList(std::list &ids) ; + RsPgpId getPgpId(const RsPeerId& sslid) ; + bool getPgpAllList(std::list &ids) ; bool getKeyFingerprint(const RsPgpId& id,PGPFingerprintType& fp) const; bool parseSignature(unsigned char *sign, unsigned int signlen, RsPgpId& issuer) const; diff --git a/tests/unittests/libretroshare/services/gxs/FakePgpAuxUtils.cc b/tests/unittests/libretroshare/services/gxs/FakePgpAuxUtils.cc index 2d274897a..49e440e5e 100644 --- a/tests/unittests/libretroshare/services/gxs/FakePgpAuxUtils.cc +++ b/tests/unittests/libretroshare/services/gxs/FakePgpAuxUtils.cc @@ -24,7 +24,7 @@ FakePgpAuxUtils::FakePgpAuxUtils(const RsPeerId& ownId) { - mOwnId = getPGPId(ownId); + mOwnId = getPgpId(ownId); addPeerIdToPgpList(ownId); } @@ -39,7 +39,7 @@ void FakePgpAuxUtils::addPeerListToPgpList(const std::list &ids) void FakePgpAuxUtils::addPeerIdToPgpList(const RsPeerId &id) { - RsPgpId pgpId = getPGPId(id); + RsPgpId pgpId = getPgpId(id); if (mPgpList.end() == std::find(mPgpList.begin(), mPgpList.end(), pgpId)) { mPgpList.push_back(pgpId); @@ -51,7 +51,7 @@ const RsPgpId & FakePgpAuxUtils::getPGPOwnId() return mOwnId; } -RsPgpId FakePgpAuxUtils::getPGPId(const RsPeerId& sslid) +RsPgpId FakePgpAuxUtils::getPgpId(const RsPeerId& sslid) { /* convert an sslId */ std::string idstring = sslid.toStdString(); @@ -95,7 +95,7 @@ bool FakePgpAuxUtils::VerifySignBin(const void* /*data*/, uint32_t /*len*/, unsi return true; } -bool FakePgpAuxUtils::getGPGAllList(std::list &ids) +bool FakePgpAuxUtils::getPgpAllList(std::list &ids) { ids = mPgpList; return true; diff --git a/tests/unittests/libretroshare/services/gxs/FakePgpAuxUtils.h b/tests/unittests/libretroshare/services/gxs/FakePgpAuxUtils.h index 63b20b85d..f866164a6 100644 --- a/tests/unittests/libretroshare/services/gxs/FakePgpAuxUtils.h +++ b/tests/unittests/libretroshare/services/gxs/FakePgpAuxUtils.h @@ -28,7 +28,7 @@ public: FakePgpAuxUtils(const RsPeerId& ownId); virtual const RsPgpId &getPGPOwnId(); - virtual RsPgpId getPGPId(const RsPeerId& sslid); + virtual RsPgpId getPgpId(const RsPeerId& sslid); virtual bool getKeyFingerprint(const RsPgpId& id,PGPFingerprintType& fp) const; virtual bool parseSignature(unsigned char *sign, unsigned int signlen, RsPgpId& issuer) const; @@ -36,7 +36,7 @@ public: virtual void addPeerListToPgpList(const std::list &ids); virtual void addPeerIdToPgpList(const RsPeerId &id); - virtual bool getGPGAllList(std::list &ids); + virtual bool getPgpAllList(std::list &ids); private: RsPgpId mOwnId; std::list mPgpList; From a072b151f5dca8beac6a47e064eb5fca843fa17c Mon Sep 17 00:00:00 2001 From: Phenom Date: Sat, 6 Nov 2021 14:10:17 +0100 Subject: [PATCH 024/113] Add ConnectFriendWizard improvement. Add cert details in friendCertCleanLabel tooltip. Use qss for background color of friendCertCleanLabel. Add Known IP in final view. --- libretroshare/src/pgp/rscertificate.cc | 20 ++++---- libretroshare/src/pgp/rscertificate.h | 2 +- libretroshare/src/retroshare/rspeers.h | 2 +- libretroshare/src/rsserver/p3peers.cc | 4 +- libretroshare/src/rsserver/p3peers.h | 2 +- .../src/gui/connect/ConnectFriendWizard.cpp | 49 ++++++++++++------- .../src/gui/connect/ConnectFriendWizard.ui | 14 +++++- 7 files changed, 57 insertions(+), 36 deletions(-) diff --git a/libretroshare/src/pgp/rscertificate.cc b/libretroshare/src/pgp/rscertificate.cc index f3007bb01..23c7f2dab 100644 --- a/libretroshare/src/pgp/rscertificate.cc +++ b/libretroshare/src/pgp/rscertificate.cc @@ -552,26 +552,24 @@ unsigned short RsCertificate::loc_port_us() const return (int)ipv4_internal_ip_and_port[4]*256 + (int)ipv4_internal_ip_and_port[5] ; } -bool RsCertificate::cleanCertificate( const std::string& input, std::string& output, Format& format, uint32_t& error_code, bool check_content ) +bool RsCertificate::cleanCertificate( const std::string& input, std::string& output, Format& format, uint32_t& error_code, bool check_content, RsPeerDetails& details) { if(cleanRadix64(input,output,error_code)) { - RsPeerDetails details; - if(rsPeers->parseShortInvite(output,details,error_code)) - { - format = RS_CERTIFICATE_SHORT_RADIX; - return true; - } + if(rsPeers->parseShortInvite(output,details,error_code)) + { + format = RS_CERTIFICATE_SHORT_RADIX; + return true; + } + //Clear details. As parseShortInvite may make it dirty. + details = RsPeerDetails(); format = RS_CERTIFICATE_RADIX; if(!check_content) return true; - uint32_t errCode; - auto crt = RsCertificate::fromString(input, errCode); - error_code = static_cast(errCode); - return crt != nullptr; + return rsPeers->loadDetailsFromStringCert(input,details,error_code); } return false; diff --git a/libretroshare/src/pgp/rscertificate.h b/libretroshare/src/pgp/rscertificate.h index 1ba3db633..977493e69 100644 --- a/libretroshare/src/pgp/rscertificate.h +++ b/libretroshare/src/pgp/rscertificate.h @@ -84,7 +84,7 @@ public: static bool cleanCertificate( const std::string& input, std::string& output, - RsCertificate::Format& format, uint32_t& error_code, bool check_content); + RsCertificate::Format& format, uint32_t& error_code, bool check_content, RsPeerDetails& details); const std::set& locators() const { return mLocators; } diff --git a/libretroshare/src/retroshare/rspeers.h b/libretroshare/src/retroshare/rspeers.h index f49ef7fc2..e00576908 100644 --- a/libretroshare/src/retroshare/rspeers.h +++ b/libretroshare/src/retroshare/rspeers.h @@ -887,7 +887,7 @@ public: // Certificate utils virtual bool cleanCertificate( const std::string& certstr, std::string& cleanCert, - bool& is_short_format, uint32_t& error_code ) = 0; + bool& is_short_format, uint32_t& error_code, RsPeerDetails& details) = 0; virtual std::string saveCertificateToString(const RsPeerId &id) = 0; virtual bool signGPGCertificate(const RsPgpId &gpg_id,const std::string& gpg_passphrase) = 0; diff --git a/libretroshare/src/rsserver/p3peers.cc b/libretroshare/src/rsserver/p3peers.cc index 7011d7aef..14359a08d 100644 --- a/libretroshare/src/rsserver/p3peers.cc +++ b/libretroshare/src/rsserver/p3peers.cc @@ -1758,11 +1758,11 @@ bool p3Peers::loadDetailsFromStringCert( const std::string &certstr, return true; } -bool p3Peers::cleanCertificate(const std::string &certstr, std::string &cleanCert,bool& is_short_format,uint32_t& error_code) +bool p3Peers::cleanCertificate(const std::string &certstr, std::string &cleanCert,bool& is_short_format,uint32_t& error_code,RsPeerDetails& details) { RsCertificate::Format format ; - bool res = RsCertificate::cleanCertificate(certstr,cleanCert,format,error_code,true) ; + bool res = RsCertificate::cleanCertificate(certstr,cleanCert,format,error_code,true,details) ; if(format == RsCertificate::RS_CERTIFICATE_RADIX) is_short_format = false; diff --git a/libretroshare/src/rsserver/p3peers.h b/libretroshare/src/rsserver/p3peers.h index c2ff96d10..91630e12d 100644 --- a/libretroshare/src/rsserver/p3peers.h +++ b/libretroshare/src/rsserver/p3peers.h @@ -163,7 +163,7 @@ public: virtual bool loadPgpKeyFromBinaryData( const unsigned char *bin_key_data,uint32_t bin_key_len, RsPgpId& gpg_id, std::string& error_string ) override; virtual bool loadDetailsFromStringCert(const std::string &cert, RsPeerDetails &pd, uint32_t& error_code) override; - virtual bool cleanCertificate(const std::string &certstr, std::string &cleanCert, bool &is_short_format, uint32_t& error_code) override; + virtual bool cleanCertificate(const std::string &certstr, std::string &cleanCert, bool &is_short_format, uint32_t& error_code, RsPeerDetails& details) override; virtual std::string saveCertificateToString(const RsPeerId &id) override; virtual bool signGPGCertificate(const RsPgpId &id,const std::string& gpg_passphrase) override; diff --git a/retroshare-gui/src/gui/connect/ConnectFriendWizard.cpp b/retroshare-gui/src/gui/connect/ConnectFriendWizard.cpp index c3463a79b..15456bbd5 100755 --- a/retroshare-gui/src/gui/connect/ConnectFriendWizard.cpp +++ b/retroshare-gui/src/gui/connect/ConnectFriendWizard.cpp @@ -39,6 +39,7 @@ #include "ConnectFriendWizard.h" #include "ui_ConnectFriendWizard.h" #include "gui/common/PeerDefs.h" +#include "gui/connect/ConfCertDialog.h" #include "gui/notifyqt.h" #include "gui/common/GroupDefs.h" #include "gui/msgs/MessageComposer.h" @@ -572,6 +573,16 @@ void ConnectFriendWizard::initializePage(int id) ui->ipEdit->setText(s); ui->signersEdit->setPlainText(ts); + ui->knownIpLabel->setHidden(peerDetails.ipAddressList.empty()); + ui->knownIpEdit->setHidden(peerDetails.ipAddressList.empty()); + { + QString ipList; + for(auto& it : peerDetails.ipAddressList) + ipList.append(QString::fromStdString(it) + "\n"); + + ui->knownIpEdit->setPlainText(ipList); + } + fillGroups(this, ui->groupComboBox, groupId); if(peerDetails.isHiddenNode) @@ -587,15 +598,16 @@ void ConnectFriendWizard::initializePage(int id) } if(mIsShortInvite) { - ui->nameEdit->setText(tr("[Unknown]")); - ui->addKeyToKeyring_CB->setChecked(false); - ui->addKeyToKeyring_CB->setEnabled(false); + if(ui->nameEdit->text().isEmpty()) + ui->nameEdit->setText(tr("[Unknown]")); + ui->addKeyToKeyring_CB->setChecked(false); + ui->addKeyToKeyring_CB->setEnabled(false); ui->signersEdit->hide(); ui->signersLabel->hide(); - ui->signGPGCheckBox->setChecked(false); - ui->signGPGCheckBox->setEnabled(false); - ui->acceptNoSignGPGCheckBox->setChecked(true); - ui->acceptNoSignGPGCheckBox->setEnabled(false); + ui->signGPGCheckBox->setChecked(false); + ui->signGPGCheckBox->setEnabled(false); + ui->acceptNoSignGPGCheckBox->setChecked(true); + ui->acceptNoSignGPGCheckBox->setEnabled(false); } ui->ipEdit->setTextInteractionFlags(Qt::TextSelectableByMouse); @@ -856,30 +868,30 @@ void ConnectFriendWizard::cleanFriendCert() { bool certValid = false; QString errorMsg ; + QString certDetail; std::string cert = ui->friendCertEdit->toPlainText().toUtf8().constData(); if (cert.empty()) { - ui->friendCertCleanLabel->setPixmap(FilesDefs::getPixmapFromQtResourcePath(":/images/delete.png")); ui->friendCertCleanLabel->setToolTip(""); - ui->friendCertCleanLabel->setStyleSheet(""); errorMsg = tr(""); } else { std::string cleanCert; uint32_t error_code; + RsPeerDetails details; - if (rsPeers->cleanCertificate(cert, cleanCert, mIsShortInvite, error_code)) - { + if (rsPeers->cleanCertificate(cert, cleanCert, mIsShortInvite, error_code, details)) + { certValid = true; if (cert != cleanCert) - { + { QTextCursor textCursor = ui->friendCertEdit->textCursor(); whileBlocking(ui->friendCertEdit)->setPlainText(QString::fromUtf8(cleanCert.c_str())); whileBlocking(ui->friendCertEdit)->setTextCursor(textCursor); - ui->friendCertCleanLabel->setStyleSheet(""); + certDetail = ConfCertDialog::getCertificateDescription(details,false,mIsShortInvite,!details.ipAddressList.empty()); } if (mIsShortInvite) @@ -887,7 +899,7 @@ void ConnectFriendWizard::cleanFriendCert() else errorMsg = tr("Valid certificate") ; - ui->friendCertCleanLabel->setPixmap(FilesDefs::getPixmapFromQtResourcePath(":/images/accepted16.png")); + ui->friendCertCleanLabel->setPixmap(FilesDefs::getPixmapFromQtResourcePath(":/images/accepted16.png")); } else { if (error_code > 0) { switch (error_code) { @@ -903,16 +915,17 @@ void ConnectFriendWizard::cleanFriendCert() default: errorMsg = tr("Not a valid Retroshare certificate!") ; - ui->friendCertCleanLabel->setStyleSheet("QLabel#friendCertCleanLabel {border: 1px solid #DCDC41; border-radius: 6px; background-color: qlineargradient(x1:0, y1:0, x2:0, y2:1, stop:0 #FFFFD7, stop:1 #FFFFB2);}"); } } - ui->friendCertCleanLabel->setPixmap(FilesDefs::getPixmapFromQtResourcePath(":/images/delete.png")); } } - ui->friendCertCleanLabel->setPixmap(certValid ? FilesDefs::getPixmapFromQtResourcePath(":/images/accepted16.png") : FilesDefs::getPixmapFromQtResourcePath(":/images/delete.png")); - ui->friendCertCleanLabel->setToolTip(errorMsg); + ui->friendCertCleanLabel->setPixmap(certValid ? FilesDefs::getPixmapFromQtResourcePath(":/images/accepted16.png") : FilesDefs::getPixmapFromQtResourcePath(":/images/delete.png")); + ui->friendCertCleanLabel->setToolTip("

" + errorMsg + (certValid ? "\n" + certDetail : "") + "

"); ui->friendCertCleanLabel->setText(errorMsg); + ui->friendCertCleanLabel->setProperty("WrongValue", !certValid && !errorMsg.isEmpty()); + ui->friendCertCleanLabel->style()->unpolish(ui->friendCertCleanLabel); + ui->friendCertCleanLabel->style()->polish( ui->friendCertCleanLabel); ui->TextPage->setComplete(certValid); } diff --git a/retroshare-gui/src/gui/connect/ConnectFriendWizard.ui b/retroshare-gui/src/gui/connect/ConnectFriendWizard.ui index f6ac10b5e..65b736762 100644 --- a/retroshare-gui/src/gui/connect/ConnectFriendWizard.ui +++ b/retroshare-gui/src/gui/connect/ConnectFriendWizard.ui @@ -590,7 +590,7 @@ - Email + ProfilId @@ -629,7 +629,7 @@ - Signers + Signers: @@ -675,6 +675,16 @@ + + + + Known IP: + + + + + + From 11f17fef40dd9e08f56ce5cabfec811094914182 Mon Sep 17 00:00:00 2001 From: Gioacchino Mazzurco Date: Fri, 12 Nov 2021 16:02:53 +0100 Subject: [PATCH 025/113] libretroshare Android Qt network dependency optional One of the reason libretroshare dependend on Qt on Android and in particular in networking module is the lack of `getifaddrs` with API level < 24, we included Android Gingerbread internal implementation so this dependency can be avoided at compile time. The code depending on Qt has been placed under `#if` and can be enabled at compile time by appending `DEFINES+=LIBRETROSHARE_ANDROID_IFADDRS_QT` to `qmake` command line. --- .../src/android_ifaddrs/LocalArray.h | 75 ++++++ libretroshare/src/android_ifaddrs/README.adoc | 45 ++++ libretroshare/src/android_ifaddrs/ScopedFd.h | 46 ++++ .../src/android_ifaddrs/ifaddrs-android.h | 228 ++++++++++++++++++ libretroshare/src/libretroshare.pro | 13 +- libretroshare/src/pqi/pqinetwork.cc | 17 +- libretroshare/src/use_libretroshare.pri | 11 +- 7 files changed, 426 insertions(+), 9 deletions(-) create mode 100644 libretroshare/src/android_ifaddrs/LocalArray.h create mode 100644 libretroshare/src/android_ifaddrs/README.adoc create mode 100644 libretroshare/src/android_ifaddrs/ScopedFd.h create mode 100644 libretroshare/src/android_ifaddrs/ifaddrs-android.h diff --git a/libretroshare/src/android_ifaddrs/LocalArray.h b/libretroshare/src/android_ifaddrs/LocalArray.h new file mode 100644 index 000000000..2ab708aff --- /dev/null +++ b/libretroshare/src/android_ifaddrs/LocalArray.h @@ -0,0 +1,75 @@ +/* + * Copyright (C) 2009 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef LOCAL_ARRAY_H_included +#define LOCAL_ARRAY_H_included + +#include +#include + +/** + * A fixed-size array with a size hint. That number of bytes will be allocated + * on the stack, and used if possible, but if more bytes are requested at + * construction time, a buffer will be allocated on the heap (and deallocated + * by the destructor). + * + * The API is intended to be a compatible subset of C++0x's std::array. + */ +template +class LocalArray { +public: + /** + * Allocates a new fixed-size array of the given size. If this size is + * less than or equal to the template parameter STACK_BYTE_COUNT, an + * internal on-stack buffer will be used. Otherwise a heap buffer will + * be allocated. + */ + LocalArray(size_t desiredByteCount) : mSize(desiredByteCount) { + if (desiredByteCount > STACK_BYTE_COUNT) { + mPtr = new char[mSize]; + } else { + mPtr = &mOnStackBuffer[0]; + } + } + + /** + * Frees the heap-allocated buffer, if there was one. + */ + ~LocalArray() { + if (mPtr != &mOnStackBuffer[0]) { + delete[] mPtr; + } + } + + // Capacity. + size_t size() { return mSize; } + bool empty() { return mSize == 0; } + + // Element access. + char& operator[](size_t n) { return mPtr[n]; } + const char& operator[](size_t n) const { return mPtr[n]; } + +private: + char mOnStackBuffer[STACK_BYTE_COUNT]; + char* mPtr; + size_t mSize; + + // Disallow copy and assignment. + LocalArray(const LocalArray&); + void operator=(const LocalArray&); +}; + +#endif // LOCAL_ARRAY_H_included diff --git a/libretroshare/src/android_ifaddrs/README.adoc b/libretroshare/src/android_ifaddrs/README.adoc new file mode 100644 index 000000000..ba0355df7 --- /dev/null +++ b/libretroshare/src/android_ifaddrs/README.adoc @@ -0,0 +1,45 @@ += README Android ifaddrs + +Android API level < 24 doesn't provide `getifaddrs` and related functions, we +have tested multiple ways to overcome this issue. + + +== Non Weorking alternative implementations + +https://github.com/kmackay/android-ifaddrs +https://github.com/morristech/android-ifaddrs +https://www.openhub.net/p/android-ifaddrs/ + +Compiles but then segfault at runtime. + + +== Qt implementation + +Using `QNetworkInterface::allAddresses()` provided by Qt works but at time of +writing (Q4 2021) on newer Android the log is flooded by warnings as we reported +here +https://bugreports.qt.io/browse/QTBUG-78659 +plus depending on Qt networking module just for this is frustrating. + +Update: the warning flood seems have been fixed in later Qt versions +https://bugreports.qt.io/browse/QTBUG-86394 + +This solution is the first working we implemented in our code it is disabled by +default but can be enabled passing `DEFINES+=LIBRETROSHARE_ANDROID_IFADDRS_QT` +when running `qmake` command. + + +== Code copied from Android Gingerbread release + +As explained here +https://stackoverflow.com/a/57112520 + +even older Android have `getifaddrs` implementations but doesn't make them +accessible in the API, in particular the one included in Android Gingerbread + +https://android.googlesource.com/platform/libcore/+/refs/heads/gingerbread-release/luni/src/main/native/ifaddrs-android.h +https://android.googlesource.com/platform/libcore/+/refs/heads/gingerbread-release/ + +is particularly easy to include in our code base and compile. + +This solution seems the best fitting and doesn't introduce dependency on Qt. diff --git a/libretroshare/src/android_ifaddrs/ScopedFd.h b/libretroshare/src/android_ifaddrs/ScopedFd.h new file mode 100644 index 000000000..d2b7935fa --- /dev/null +++ b/libretroshare/src/android_ifaddrs/ScopedFd.h @@ -0,0 +1,46 @@ +/* + * Copyright (C) 2009 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef SCOPED_FD_H_included +#define SCOPED_FD_H_included + +#include + +// A smart pointer that closes the given fd on going out of scope. +// Use this when the fd is incidental to the purpose of your function, +// but needs to be cleaned up on exit. +class ScopedFd { +public: + explicit ScopedFd(int fd) : fd(fd) { + } + + ~ScopedFd() { + close(fd); + } + + int get() const { + return fd; + } + +private: + int fd; + + // Disallow copy and assignment. + ScopedFd(const ScopedFd&); + void operator=(const ScopedFd&); +}; + +#endif // SCOPED_FD_H_included diff --git a/libretroshare/src/android_ifaddrs/ifaddrs-android.h b/libretroshare/src/android_ifaddrs/ifaddrs-android.h new file mode 100644 index 000000000..446d8d2be --- /dev/null +++ b/libretroshare/src/android_ifaddrs/ifaddrs-android.h @@ -0,0 +1,228 @@ +/* + * Copyright (C) 2009 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef IFADDRS_ANDROID_H_included +#define IFADDRS_ANDROID_H_included + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "LocalArray.h" +#include "ScopedFd.h" + +// Android (bionic) doesn't have getifaddrs(3)/freeifaddrs(3). +// We fake it here, so java_net_NetworkInterface.cpp can use that API +// with all the non-portable code being in this file. + +// Source-compatible subset of the BSD struct. +struct ifaddrs { + // Pointer to next struct in list, or NULL at end. + ifaddrs* ifa_next; + + // Interface name. + char* ifa_name; + + // Interface flags. + unsigned int ifa_flags; + + // Interface network address. + sockaddr* ifa_addr; + + // Interface netmask. + sockaddr* ifa_netmask; + + ifaddrs(ifaddrs* next) + : ifa_next(next), ifa_name(NULL), ifa_flags(0), ifa_addr(NULL), ifa_netmask(NULL) + { + } + + ~ifaddrs() { + delete ifa_next; + delete[] ifa_name; + delete ifa_addr; + delete ifa_netmask; + } + + // Sadly, we can't keep the interface index for portability with BSD. + // We'll have to keep the name instead, and re-query the index when + // we need it later. + bool setNameAndFlagsByIndex(int interfaceIndex) { + // Get the name. + char buf[IFNAMSIZ]; + char* name = if_indextoname(interfaceIndex, buf); + if (name == NULL) { + return false; + } + ifa_name = new char[strlen(name) + 1]; + strcpy(ifa_name, name); + + // Get the flags. + ScopedFd fd(socket(AF_INET, SOCK_DGRAM, 0)); + if (fd.get() == -1) { + return false; + } + ifreq ifr; + memset(&ifr, 0, sizeof(ifr)); + strcpy(ifr.ifr_name, name); + int rc = ioctl(fd.get(), SIOCGIFFLAGS, &ifr); + if (rc == -1) { + return false; + } + ifa_flags = ifr.ifr_flags; + return true; + } + + // Netlink gives us the address family in the header, and the + // sockaddr_in or sockaddr_in6 bytes as the payload. We need to + // stitch the two bits together into the sockaddr that's part of + // our portable interface. + void setAddress(int family, void* data, size_t byteCount) { + // Set the address proper... + sockaddr_storage* ss = new sockaddr_storage; + memset(ss, 0, sizeof(*ss)); + ifa_addr = reinterpret_cast(ss); + ss->ss_family = family; + uint8_t* dst = sockaddrBytes(family, ss); + memcpy(dst, data, byteCount); + } + + // Netlink gives us the prefix length as a bit count. We need to turn + // that into a BSD-compatible netmask represented by a sockaddr*. + void setNetmask(int family, size_t prefixLength) { + // ...and work out the netmask from the prefix length. + sockaddr_storage* ss = new sockaddr_storage; + memset(ss, 0, sizeof(*ss)); + ifa_netmask = reinterpret_cast(ss); + ss->ss_family = family; + uint8_t* dst = sockaddrBytes(family, ss); + memset(dst, 0xff, prefixLength / 8); + if ((prefixLength % 8) != 0) { + dst[prefixLength/8] = (0xff << (8 - (prefixLength % 8))); + } + } + + // Returns a pointer to the first byte in the address data (which is + // stored in network byte order). + uint8_t* sockaddrBytes(int family, sockaddr_storage* ss) { + if (family == AF_INET) { + sockaddr_in* ss4 = reinterpret_cast(ss); + return reinterpret_cast(&ss4->sin_addr); + } else if (family == AF_INET6) { + sockaddr_in6* ss6 = reinterpret_cast(ss); + return reinterpret_cast(&ss6->sin6_addr); + } + return NULL; + } + +private: + // Disallow copy and assignment. + ifaddrs(const ifaddrs&); + void operator=(const ifaddrs&); +}; + +// FIXME: use iovec instead. +struct addrReq_struct { + nlmsghdr netlinkHeader; + ifaddrmsg msg; +}; + +inline bool sendNetlinkMessage(int fd, const void* data, size_t byteCount) { + ssize_t sentByteCount = TEMP_FAILURE_RETRY(send(fd, data, byteCount, 0)); + return (sentByteCount == static_cast(byteCount)); +} + +inline ssize_t recvNetlinkMessage(int fd, char* buf, size_t byteCount) { + return TEMP_FAILURE_RETRY(recv(fd, buf, byteCount, 0)); +} + +// Source-compatible with the BSD function. +inline int getifaddrs(ifaddrs** result) { + // Simplify cleanup for callers. + *result = NULL; + + // Create a netlink socket. + ScopedFd fd(socket(AF_NETLINK, SOCK_DGRAM, NETLINK_ROUTE)); + if (fd.get() < 0) { + return -1; + } + + // Ask for the address information. + addrReq_struct addrRequest; + memset(&addrRequest, 0, sizeof(addrRequest)); + addrRequest.netlinkHeader.nlmsg_flags = NLM_F_REQUEST | NLM_F_MATCH; + addrRequest.netlinkHeader.nlmsg_type = RTM_GETADDR; + addrRequest.netlinkHeader.nlmsg_len = NLMSG_ALIGN(NLMSG_LENGTH(sizeof(addrRequest))); + addrRequest.msg.ifa_family = AF_UNSPEC; // All families. + addrRequest.msg.ifa_index = 0; // All interfaces. + if (!sendNetlinkMessage(fd.get(), &addrRequest, addrRequest.netlinkHeader.nlmsg_len)) { + return -1; + } + + // Read the responses. + LocalArray<0> buf(65536); // We don't necessarily have std::vector. + ssize_t bytesRead; + while ((bytesRead = recvNetlinkMessage(fd.get(), &buf[0], buf.size())) > 0) { + nlmsghdr* hdr = reinterpret_cast(&buf[0]); + for (; NLMSG_OK(hdr, (size_t)bytesRead); hdr = NLMSG_NEXT(hdr, bytesRead)) { + switch (hdr->nlmsg_type) { + case NLMSG_DONE: + return 0; + case NLMSG_ERROR: + return -1; + case RTM_NEWADDR: + { + ifaddrmsg* address = reinterpret_cast(NLMSG_DATA(hdr)); + rtattr* rta = IFA_RTA(address); + size_t ifaPayloadLength = IFA_PAYLOAD(hdr); + while (RTA_OK(rta, ifaPayloadLength)) { + if (rta->rta_type == IFA_LOCAL) { + int family = address->ifa_family; + if (family == AF_INET || family == AF_INET6) { + *result = new ifaddrs(*result); + if (!(*result)->setNameAndFlagsByIndex(address->ifa_index)) { + return -1; + } + (*result)->setAddress(family, RTA_DATA(rta), RTA_PAYLOAD(rta)); + (*result)->setNetmask(family, address->ifa_prefixlen); + } + } + rta = RTA_NEXT(rta, ifaPayloadLength); + } + } + break; + } + } + } + // We only get here if recv fails before we see a NLMSG_DONE. + return -1; +} + +// Source-compatible with the BSD function. +inline void freeifaddrs(ifaddrs* addresses) { + delete addresses; +} + +#endif // IFADDRS_ANDROID_H_included diff --git a/libretroshare/src/libretroshare.pro b/libretroshare/src/libretroshare.pro index d42f68328..a1a257aac 100644 --- a/libretroshare/src/libretroshare.pro +++ b/libretroshare/src/libretroshare.pro @@ -1,4 +1,4 @@ -# SPDX-FileCopyrightText: (C) 2004-2019 Retroshare Team +# SPDX-FileCopyrightText: (C) 2004-2021 Retroshare Team # SPDX-License-Identifier: CC0-1.0 !include("../../retroshare.pri"): error("Could not include file ../../retroshare.pri") @@ -1091,6 +1091,8 @@ test_bitdht { ################################# Android ##################################### android-* { + lessThan(ANDROID_API_VERSION, 24) { + ## TODO: This probably disable largefile support and maybe is not necessary with ## __ANDROID_API__ >= 24 hence should be made conditional or moved to a ## compatibility header @@ -1098,6 +1100,15 @@ android-* { DEFINES *= "fseeko64=fseeko" DEFINES *= "ftello64=ftello" + ## @See: android_ifaddrs/README.adoc + !contains(DEFINES, LIBRETROSHARE_ANDROID_IFADDRS_QT) { + HEADERS += \ + android_ifaddrs/ifaddrs-android.h \ + android_ifaddrs/LocalArray.h \ + android_ifaddrs/ScopedFd.h + } + } + ## Static library are very susceptible to order in command line sLibs = bz2 $$RS_UPNP_LIB $$RS_SQL_LIB ssl crypto diff --git a/libretroshare/src/pqi/pqinetwork.cc b/libretroshare/src/pqi/pqinetwork.cc index a5ca76035..b6c52fc27 100644 --- a/libretroshare/src/pqi/pqinetwork.cc +++ b/libretroshare/src/pqi/pqinetwork.cc @@ -27,6 +27,7 @@ # include #endif // WINDOWS_SYS +/// @See: android_ifaddrs/README.adoc #ifdef __ANDROID__ # include #endif // def __ANDROID__ @@ -276,11 +277,17 @@ int inet_aton(const char *name, struct in_addr *addr) # include # include # pragma comment(lib, "IPHLPAPI.lib") -#elif defined(__ANDROID__) && __ANDROID_API__ < 24 +#elif defined(__ANDROID__) && __ANDROID_API__ < 24 && \ + defined(LIBRETROSHARE_ANDROID_IFADDRS_QT) +/// @See: android_ifaddrs/README.adoc # include # include # include # include +#elif defined(__ANDROID__) && __ANDROID_API__ < 24 && \ + !defined(LIBRETROSHARE_ANDROID_IFADDRS_QT) +/// @See: android_ifaddrs/README.adoc +# include "android_ifaddrs/ifaddrs-android.h" #else // not __ANDROID__ nor WINDOWS => Linux and other unixes # include # include @@ -324,7 +331,9 @@ bool getLocalAddresses(std::vector& addrs) } } free(adapter_addresses); -#elif defined(__ANDROID__) && __ANDROID_API__ < 24 +#elif defined(__ANDROID__) && __ANDROID_API__ < 24 && \ + defined(LIBRETROSHARE_ANDROID_IFADDRS_QT) +/// @See: android_ifaddrs/README.adoc for(auto& qAddr: QNetworkInterface::allAddresses()) { sockaddr_storage tmpAddr; @@ -336,8 +345,8 @@ bool getLocalAddresses(std::vector& addrs) struct ifaddrs *ifsaddrs, *ifa; if(getifaddrs(&ifsaddrs) != 0) { - std::cerr << __PRETTY_FUNCTION__ << " FATAL ERROR: " << errno << " " - << strerror(errno) << std::endl; + RS_ERR( "getifaddrs failed with: ", errno, " ", + rs_errno_to_condition(errno) ); print_stacktrace(); return false; } diff --git a/libretroshare/src/use_libretroshare.pri b/libretroshare/src/use_libretroshare.pri index 0cca29150..a34951772 100644 --- a/libretroshare/src/use_libretroshare.pri +++ b/libretroshare/src/use_libretroshare.pri @@ -111,11 +111,14 @@ PRE_TARGETDEPS += $$pretargetStaticLibs(sLibs) LIBS += $$linkDynamicLibs(dLibs) android-* { -## ifaddrs is missing on Android to add them don't use the one from -## https://github.com/morristech/android-ifaddrs -## because it crash, use QNetworkInterface from Qt instead CONFIG *= qt - QT *= network + + lessThan(ANDROID_API_VERSION, 24) { + ## @See: android_ifaddrs/README.adoc + contains(DEFINES, LIBRETROSHARE_ANDROID_IFADDRS_QT) { + QT *= network + } + } } ################################### Pkg-Config Stuff ############################# From e4f25a558d48629155486d3e8517740328823f8f Mon Sep 17 00:00:00 2001 From: Gioacchino Mazzurco Date: Sat, 13 Mar 2021 20:17:11 +0100 Subject: [PATCH 026/113] Implement pull request mechanism in RsGxsNetService This could be used to request the online peers to pull updates from us ASAP, as an exaple when a group is created a pull request can be emitted too so the online peers pull the groups from us ASAP instead of waiting for the usual 60 seconds. A mechanism like this is especially useful on mobile phones where the internet connection is usually turned on only in a few moments (as an example while the user is interacting with the app). Cleanup a few old corners in the code keeping retro-compatibility and make the code more welcoming to new developers. Put a bunch of dead code under #ifdef. --- libretroshare/src/gxs/rsgxsnetservice.cc | 115 +++++++++++++++------ libretroshare/src/gxs/rsgxsnetservice.h | 22 +++- libretroshare/src/libretroshare.pro | 3 +- libretroshare/src/rsitems/itempriorities.h | 8 +- libretroshare/src/rsitems/rsitem.h | 37 +++++-- libretroshare/src/rsitems/rsnxsitems.h | 55 ++++++---- libretroshare/src/serialiser/rsserial.cc | 33 +++--- libretroshare/src/util/cxx23retrocompat.h | 34 ++++++ 8 files changed, 233 insertions(+), 74 deletions(-) create mode 100644 libretroshare/src/util/cxx23retrocompat.h diff --git a/libretroshare/src/gxs/rsgxsnetservice.cc b/libretroshare/src/gxs/rsgxsnetservice.cc index e664b580c..adea14205 100644 --- a/libretroshare/src/gxs/rsgxsnetservice.cc +++ b/libretroshare/src/gxs/rsgxsnetservice.cc @@ -35,7 +35,7 @@ // | // +----------- sharePublishKeys() // | -// +----------- syncWithPeers() +// +----------- pullFromPeers() // | | // | +--if AutoSync--- send global UpdateTS of each peer to itself => the peer knows the last // | | time current peer has received an updated from himself @@ -127,14 +127,14 @@ // (Set at server side to be mGrpServerUpdateItem->grpUpdateTS) // // Only updated in processCompletedIncomingTransaction() from Grp list transaction. -// Used in syncWithPeers() sending in RsNxsSyncGrp once to all peers: peer will send data if +// Used in pullFromPeers() sending in RsNxsSyncGrp once to all peers: peer will send data if // has something new. All time comparisons are in the friends' clock time. // // mClientMsgUpdateMap: map< RsPeerId, map > // // Last msg list modification time sent by that peer Id // Updated in processCompletedIncomingTransaction() from Grp list trans. -// Used in syncWithPeers() sending in RsNxsSyncGrp once to all peers. +// Used in pullFromPeers() sending in RsNxsSyncGrp once to all peers. // Set at server to be mServerMsgUpdateMap[grpId]->msgUpdateTS // // mGrpServerUpdateItem: TimeStamp Last group local modification timestamp over all groups @@ -150,7 +150,7 @@ // // tick() tick() // | | -// +---- SyncWithPeers +-- recvNxsItemQueue() +// +---- pullFromPeers +-- recvNxsItemQueue() // | | // +---------------- Send global UpdateTS of each peer to itself => the peer knows +---------> +------ handleRecvSyncGroup( RsNxsSyncGrp*) // | the last msg sent (stored in mClientGrpUpdateMap[peer_id]), | | - parse all subscribed groups. For each, send a RsNxsSyncGrpItem with publish TS @@ -457,7 +457,7 @@ int RsGxsNetService::tick() if((elapsed) < now) { - syncWithPeers(); + pullFromPeers(); syncGrpStatistics(); checkDistantSyncState(); @@ -570,39 +570,39 @@ RsGxsGroupId RsGxsNetService::hashGrpId(const RsGxsGroupId& gid,const RsPeerId& return RsGxsGroupId( RsDirUtil::sha1sum(tmpmem,SIZE).toByteArray() ); } -void RsGxsNetService::syncWithPeers() +void RsGxsNetService::pullFromPeers(std::set peers) { #ifdef NXS_NET_DEBUG_0 - GXSNETDEBUG___ << "RsGxsNetService::syncWithPeers() this=" << (void*)this << ". serviceInfo=" << mServiceInfo << std::endl; + RS_DBG("this=", (void*)this, ". serviceInfo=", mServiceInfo); #endif - static RsNxsSerialiser ser(mServType) ; // this is used to estimate bandwidth. - - RS_STACK_MUTEX(mNxsMutex) ; - - std::set peers; - mNetMgr->getOnlineList(mServiceInfo.mServiceType, peers); - - if(mAllowDistSync && mGxsNetTunnel != NULL) + /* If specific peers are passed as paramether ask only to them */ + if(peers.empty()) { - // Grab all online virtual peers of distant tunnels for the current service. + mNetMgr->getOnlineList(mServiceInfo.mServiceType, peers); - std::list vpids ; - mGxsNetTunnel->getVirtualPeers(vpids); + if(mAllowDistSync && mGxsNetTunnel != nullptr) + { + /* Grab all online virtual peers of distant tunnels for the current + * service. */ - for(auto it(vpids.begin());it!=vpids.end();++it) - peers.insert(RsPeerId(*it)) ; + std::list vpids ; + mGxsNetTunnel->getVirtualPeers(vpids); + + for(auto it(vpids.begin());it!=vpids.end();++it) + peers.insert(RsPeerId(*it)) ; + } } - if (peers.empty()) { - // nothing to do - return; - } + // Still empty? Then nothing to do + if (peers.empty()) return; + + + RS_STACK_MUTEX(mNxsMutex); // for now just grps for(auto sit = peers.begin(); sit != peers.end(); ++sit) { - const RsPeerId peerId = *sit; ClientGrpMap::const_iterator cit = mClientGrpUpdateMap.find(peerId); @@ -624,8 +624,7 @@ void RsGxsNetService::syncWithPeers() generic_sendItem(grp); } - if(!mAllowMsgSync) - return ; + if(!mAllowMsgSync) return; #ifndef GXS_DISABLE_SYNC_MSGS @@ -746,7 +745,7 @@ void RsGxsNetService::syncWithPeers() #endif } -void RsGxsNetService::generic_sendItem(RsNxsItem *si) +void RsGxsNetService::generic_sendItem(rs_owner_ptr si) { // check if the item is to be sent to a distant peer or not @@ -1718,13 +1717,25 @@ RsItem *RsGxsNetService::generic_recvItem() void RsGxsNetService::recvNxsItemQueue() { - RsItem *item ; + RsItem* item; - while(NULL != (item=generic_recvItem())) - { + while(nullptr != (item=generic_recvItem())) + { #ifdef NXS_NET_DEBUG_1 - GXSNETDEBUG_P_(item->PeerId()) << "Received RsGxsNetService Item:" << (void*)item << " type=" << std::hex << item->PacketId() << std::dec << std::endl ; + RS_DBG( "Received RsGxsNetService Item: ", (void*)item, " type=", + item->PacketId() ); #endif + /* Handle pull request and other new items here to not mess with all the + * old nested code and items hell */ + switch(static_cast(item->PacketSubType())) + { + case RsNxsSubtype::PULL_REQUEST: + std::unique_ptr pullItem( + static_cast(item) ); + handlePullRequest(std::move(pullItem)); + continue; + } + // RsNxsItem needs dynamic_cast, since they have derived siblings. // RsNxsItem *ni = dynamic_cast(item) ; @@ -5075,6 +5086,46 @@ void RsGxsNetService::handleRecvPublishKeys(RsNxsGroupPublishKeyItem *item) } } +std::error_condition RsGxsNetService::requestPull(std::set peers) +{ + /* If specific peers are passed as paramether ask only to them */ + if(peers.empty()) + { + mNetMgr->getOnlineList(mServiceInfo.mServiceType, peers); + + if(mAllowDistSync && mGxsNetTunnel != nullptr) + { + /* Grab all online virtual peers of distant tunnels for the current + * service. */ + + std::list vpids ; + mGxsNetTunnel->getVirtualPeers(vpids); + + for(auto it(vpids.begin());it!=vpids.end();++it) + peers.insert(RsPeerId(*it)) ; + } + } + + // Still empty? Reports there are no available peers + if (peers.empty()) return std::errc::network_down; + + for(auto& peerId: std::as_const(peers)) + { + auto item = new RsNxsPullRequestItem( + static_cast(mServType) ); + item->PeerId(peerId); + generic_sendItem(item); + } + + return std::error_condition(); +} + +void RsGxsNetService::handlePullRequest( + std::unique_ptr item ) +{ + pullFromPeers(std::set{item->PeerId()}); +} + bool RsGxsNetService::getGroupServerUpdateTS(const RsGxsGroupId& gid,rstime_t& group_server_update_TS, rstime_t& msg_server_update_TS) { RS_STACK_MUTEX(mNxsMutex) ; diff --git a/libretroshare/src/gxs/rsgxsnetservice.h b/libretroshare/src/gxs/rsgxsnetservice.h index a4b448003..406531852 100644 --- a/libretroshare/src/gxs/rsgxsnetservice.h +++ b/libretroshare/src/gxs/rsgxsnetservice.h @@ -423,6 +423,8 @@ private: */ void handleRecvPublishKeys(RsNxsGroupPublishKeyItem*) ; + void handlePullRequest(std::unique_ptr item); + /** E: item handlers **/ @@ -459,7 +461,23 @@ private: void locked_pushMsgRespFromList(std::list& itemL, const RsPeerId& sslId, const RsGxsGroupId &grp_id, const uint32_t& transN); void checkDistantSyncState(); - void syncWithPeers(); + + /** + * @brief Pull new stuff from peers + * @param peers peers to pull from, if empty all available peers are pulled + */ + void pullFromPeers(std::set peers = std::set()); + + /** + * @brief request online peers to pull updates from our node ASAP + * @param peers peers to which request pull from, if empty all available + * peers are requested to pull + * @return success or error details + * TODO: should this be exposed via RsNetworkExchangeService? + */ + std::error_condition requestPull( + std::set peers = std::set() ); + void syncGrpStatistics(); void addGroupItemToList(NxsTransaction*& tr, const RsGxsGroupId& grpId, uint32_t& transN, @@ -559,7 +577,7 @@ private: void cleanRejectedMessages(); void processObserverNotifications(); - void generic_sendItem(RsNxsItem *si); + void generic_sendItem(rs_owner_ptr si); RsItem *generic_recvItem(); private: diff --git a/libretroshare/src/libretroshare.pro b/libretroshare/src/libretroshare.pro index d42f68328..9358d8147 100644 --- a/libretroshare/src/libretroshare.pro +++ b/libretroshare/src/libretroshare.pro @@ -507,7 +507,8 @@ HEADERS += util/folderiterator.h \ util/cxx11retrocompat.h \ util/cxx14retrocompat.h \ util/cxx17retrocompat.h \ - util/rsurl.h + util/cxx23retrocompat.h \ + util/rsurl.h SOURCES += ft/ftchunkmap.cc \ ft/ftcontroller.cc \ diff --git a/libretroshare/src/rsitems/itempriorities.h b/libretroshare/src/rsitems/itempriorities.h index a376a9d64..7c2b92cb6 100644 --- a/libretroshare/src/rsitems/itempriorities.h +++ b/libretroshare/src/rsitems/itempriorities.h @@ -3,7 +3,9 @@ * * * libretroshare: retroshare core library * * * - * Copyright 2011-2011 by Cyril Soler * + * Copyright (C) 2011-2018 Cyril Soler * + * Copyright (C) 2021 Gioacchino Mazzurco * + * Copyright (C) 2021 Asociación Civil Altermundi * * * * This program is free software: you can redistribute it and/or modify * * it under the terms of the GNU Lesser General Public License as * @@ -21,7 +23,9 @@ *******************************************************************************/ #pragma once -#include +#include + +using RsItemPriority = uint8_t; // This file centralises QoS priorities for all transfer RsItems // diff --git a/libretroshare/src/rsitems/rsitem.h b/libretroshare/src/rsitems/rsitem.h index 3ef44f859..70844f840 100644 --- a/libretroshare/src/rsitems/rsitem.h +++ b/libretroshare/src/rsitems/rsitem.h @@ -3,7 +3,8 @@ * * * libretroshare: retroshare core library * * * - * Copyright (C) 2018 Gioacchino Mazzurco * + * Copyright (C) 2018-2021 Gioacchino Mazzurco * + * Copyright (C) 2021 Asociación Civil Altermundi * * * * This program is free software: you can redistribute it and/or modify * * it under the terms of the GNU Lesser General Public License as * @@ -28,6 +29,9 @@ #include "serialiser/rsserializer.h" #include "serialiser/rsserializable.h" #include "util/stacktrace.h" +#include "rsitems/itempriorities.h" +#include "rsitems/rsserviceids.h" + #include @@ -42,8 +46,13 @@ struct RsItem : RsMemoryManagement::SmallObject, RsSerializable virtual ~RsItem(); - /// TODO: Do this make sense with the new serialization system? - virtual void clear() = 0; + /** TODO: Does the existence of this method make sense with the new + * serialization system? **/ + virtual void clear() + { + RS_ERR("Called without being overridden, report to developers"); + print_stacktrace(); + } /// @deprecated use << ostream operator instead RS_DEPRECATED_FOR("<< ostream operator") @@ -70,14 +79,21 @@ struct RsItem : RsMemoryManagement::SmallObject, RsSerializable uint8_t PacketType(); uint8_t PacketSubType() const; + /** For Service Packets, @deprecated use the costructor with priority + * paramether instead */ + RS_DEPRECATED RsItem(uint8_t ver, uint16_t service, uint8_t subtype); + /// For Service Packets - RsItem(uint8_t ver, uint16_t service, uint8_t subtype); + RsItem( uint8_t ver, RsServiceType service, uint8_t subtype, + RsItemPriority prio ); + uint16_t PacketService() const; /* combined Packet class/type (mid 16bits) */ void setPacketService(uint16_t service); inline uint8_t priority_level() const { return _priority_level ;} inline void setPriorityLevel(uint8_t l) { _priority_level = l ;} +#ifdef RS_DEAD_CODE /* * TODO: This default implementation should be removed and childs structs * implement ::serial_process(...) as soon as all the codebase is ported to @@ -90,11 +106,12 @@ struct RsItem : RsMemoryManagement::SmallObject, RsSerializable "overriding Class is: ", typeid(*this).name() ); print_stacktrace(); } +#endif //def RS_DEAD_CODE protected: uint32_t type; RsPeerId peerId; - uint8_t _priority_level; + RsItemPriority _priority_level; }; /// TODO: Do this make sense with the new serialization system? @@ -108,9 +125,17 @@ public: uint32_t getRawLength() { return len; } void * getRawData() { return data; } - virtual void clear() {} +// virtual void clear() override {} virtual std::ostream &print(std::ostream &out, uint16_t indent = 0); + virtual void serial_process(RsGenericSerializer::SerializeJob, + RsGenericSerializer::SerializeContext&) override + { + RS_ERR( "called by an item using new serialization system ", + typeid(*this).name() ); + print_stacktrace(); + } + private: void *data; uint32_t len; diff --git a/libretroshare/src/rsitems/rsnxsitems.h b/libretroshare/src/rsitems/rsnxsitems.h index 2b6731bfc..8be63f74c 100644 --- a/libretroshare/src/rsitems/rsnxsitems.h +++ b/libretroshare/src/rsitems/rsnxsitems.h @@ -3,7 +3,10 @@ * * * libretroshare: retroshare core library * * * - * Copyright 2012 Christopher Evi-Parker,Robert Fernie* + * Copyright (C) 2012 Christopher Evi-Parker * + * Copyright (C) 2012 Robert Fernie * + * Copyright (C) 2021 Gioacchino Mazzurco * + * Copyright (C) 2021 Asociación Civil Altermundi * * * * This program is free software: you can redistribute it and/or modify * * it under the terms of the GNU Lesser General Public License as * @@ -19,8 +22,7 @@ * along with this program. If not, see . * * * *******************************************************************************/ -#ifndef RSNXSITEMS_H -#define RSNXSITEMS_H +#pragma once #include #include @@ -35,6 +37,7 @@ // These items have "flag type" numbers, but this is not used. +// TODO: refactor as C++11 enum class const uint8_t RS_PKT_SUBTYPE_NXS_SYNC_GRP_REQ_ITEM = 0x01; const uint8_t RS_PKT_SUBTYPE_NXS_SYNC_GRP_ITEM = 0x02; const uint8_t RS_PKT_SUBTYPE_NXS_SYNC_GRP_STATS_ITEM = 0x03; @@ -47,14 +50,19 @@ const uint8_t RS_PKT_SUBTYPE_NXS_MSG_ITEM = 0x20; const uint8_t RS_PKT_SUBTYPE_NXS_TRANSAC_ITEM = 0x40; const uint8_t RS_PKT_SUBTYPE_NXS_GRP_PUBLISH_KEY_ITEM = 0x80; -// possibility create second service to deal with this functionality +enum class RsNxsSubtype : uint8_t +{ + PULL_REQUEST = 0x90 /// @see RsNxsPullRequestItem +}; +#ifdef RS_DEAD_CODE +// possibility create second service to deal with this functionality const uint8_t RS_PKT_SUBTYPE_EXT_SEARCH_GRP = 0x0001; const uint8_t RS_PKT_SUBTYPE_EXT_SEARCH_MSG = 0x0002; const uint8_t RS_PKT_SUBTYPE_EXT_DELETE_GRP = 0x0004; const uint8_t RS_PKT_SUBTYPE_EXT_DELETE_MSG = 0x0008; const uint8_t RS_PKT_SUBTYPE_EXT_SEARCH_REQ = 0x0010; - +#endif // def RS_DEAD_CODE /*! * Base class for Network exchange service @@ -65,17 +73,14 @@ const uint8_t RS_PKT_SUBTYPE_EXT_SEARCH_REQ = 0x0010; */ class RsNxsItem : public RsItem { - public: - RsNxsItem(uint16_t servtype, uint8_t subtype) : RsItem(RS_PKT_VERSION_SERVICE, servtype, subtype), transactionNumber(0) - { - setPriorityLevel(QOS_PRIORITY_RS_GXS_NET); - return; - } - virtual ~RsNxsItem(){} - virtual void clear() = 0; + RsNxsItem(uint16_t servtype, uint8_t subtype): + RsItem(RS_PKT_VERSION_SERVICE, servtype, subtype), transactionNumber(0) + { setPriorityLevel(QOS_PRIORITY_RS_GXS_NET); } - uint32_t transactionNumber; // set to zero if this is not a transaction item + virtual ~RsNxsItem() = default; + + uint32_t transactionNumber; // set to zero if this is not a transaction item }; @@ -362,6 +367,22 @@ public: }; +/*! + * Used to request to a peer pull updates from us ASAP without waiting GXS sync + * timer */ +struct RsNxsPullRequestItem: RsItem +{ + explicit RsNxsPullRequestItem(RsServiceType servtype): + RsItem( RS_PKT_VERSION_SERVICE, + servtype, + static_cast(RsNxsSubtype::PULL_REQUEST), + QOS_PRIORITY_RS_GXS_NET ) {} + + /// @see RsSerializable + void serial_process( RsGenericSerializer::SerializeJob, + RsGenericSerializer::SerializeContext& ) override {} +}; + /*! * Used to respond to a RsGrpMsgsReq @@ -401,6 +422,7 @@ struct RsNxsMsg : RsNxsItem RsGxsMsgMetaData* metaData; }; +#ifdef RS_DEAD_CODE /*! * Used to request a search of user data */ @@ -422,7 +444,7 @@ public: RsTlvBinaryData serviceSearchItem; // service aware of item class uint32_t expiration; // expiration date }; - +#endif //def RS_DEAD_CODE #ifdef UNUSED_CODE @@ -511,6 +533,3 @@ public: protected: const uint16_t SERVICE_TYPE; }; - - -#endif // RSNXSITEMS_H diff --git a/libretroshare/src/serialiser/rsserial.cc b/libretroshare/src/serialiser/rsserial.cc index 52123abf1..4d3cda811 100644 --- a/libretroshare/src/serialiser/rsserial.cc +++ b/libretroshare/src/serialiser/rsserial.cc @@ -3,7 +3,9 @@ * * * libretroshare: retroshare core library * * * - * Copyright 2007-2008 by Robert Fernie * + * Copyright (C) 2007-2008 Robert Fernie * + * Copyright (C) 2021 Gioacchino Mazzurco * + * Copyright (C) 2021 Asociación Civil Altermundi * * * * This program is free software: you can redistribute it and/or modify * * it under the terms of the GNU Lesser General Public License as * @@ -20,21 +22,20 @@ * * *******************************************************************************/ -#include "serialiser/rsbaseserial.h" - -#include "util/rsthreads.h" -#include "util/rsstring.h" -#include "util/rsprint.h" - -#include "rsitems/rsitem.h" -#include "rsitems/itempriorities.h" - -#include +#include #include #include #include #include +#include "serialiser/rsbaseserial.h" +#include "util/cxx23retrocompat.h" +#include "util/rsthreads.h" +#include "util/rsstring.h" +#include "util/rsprint.h" +#include "rsitems/rsitem.h" +#include "rsitems/itempriorities.h" + /*** * #define RSSERIAL_DEBUG 1 @@ -166,11 +167,17 @@ uint8_t RsItem::PacketSubType() const /* For Service Packets */ RsItem::RsItem(uint8_t ver, uint16_t service, uint8_t subtype) { - _priority_level = QOS_PRIORITY_UNKNOWN ; // This value triggers PQIInterface to complain about undefined priorities + // This value triggers PQIInterface to complain about undefined priorities + _priority_level = QOS_PRIORITY_UNKNOWN; type = (ver << 24) + (service << 8) + subtype; - return; } +RsItem::RsItem( uint8_t ver, RsServiceType service, uint8_t subtype, + RsItemPriority prio ): + type(static_cast( + (ver << 24) + (std::to_underlying(service) << 8) + subtype )), + _priority_level(prio) {} + uint16_t RsItem::PacketService() const { return (type >> 8) & 0xFFFF; diff --git a/libretroshare/src/util/cxx23retrocompat.h b/libretroshare/src/util/cxx23retrocompat.h new file mode 100644 index 000000000..cd96b7cbf --- /dev/null +++ b/libretroshare/src/util/cxx23retrocompat.h @@ -0,0 +1,34 @@ +/******************************************************************************* + * RetroShare C++23 backwards compatibility utilities * + * * + * libretroshare: retroshare core library * + * * + * Copyright (C) 2021 Gioacchino Mazzurco * + * Copyright (C) 2021 Asociación Civil Altermundi * + * * + * 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 + +#include + +#if ! defined(__cpp_lib_to_underlying) +namespace std +{ +template +constexpr underlying_type_t to_underlying(Enum e) noexcept +{ return static_cast>(e); } +} +#endif // ! defined(__cpp_lib_to_underlying) From a374f1dc6bc5a60407460f4d621a75c3c9f0340d Mon Sep 17 00:00:00 2001 From: Gioacchino Mazzurco Date: Sat, 13 Mar 2021 21:11:18 +0100 Subject: [PATCH 027/113] Implement RsNxsSerialiser::create_item for RsNxsPullRequestItem --- libretroshare/src/rsitems/rsnxsitems.cc | 6 ++++++ libretroshare/src/rsitems/rsnxsitems.h | 15 ++++++++------- 2 files changed, 14 insertions(+), 7 deletions(-) diff --git a/libretroshare/src/rsitems/rsnxsitems.cc b/libretroshare/src/rsitems/rsnxsitems.cc index e8178e045..94409bc19 100644 --- a/libretroshare/src/rsitems/rsnxsitems.cc +++ b/libretroshare/src/rsitems/rsnxsitems.cc @@ -64,6 +64,12 @@ RsItem *RsNxsSerialiser::create_item(uint16_t service_id,uint8_t item_subtype) c if(service_id != SERVICE_TYPE) return NULL ; + switch(static_cast(item_subtype)) + { + case RsNxsSubtype::PULL_REQUEST: + return new RsNxsPullRequestItem(static_cast(service_id)); + } + switch(item_subtype) { case RS_PKT_SUBTYPE_NXS_SYNC_GRP_REQ_ITEM: return new RsNxsSyncGrpReqItem(SERVICE_TYPE) ; diff --git a/libretroshare/src/rsitems/rsnxsitems.h b/libretroshare/src/rsitems/rsnxsitems.h index 8be63f74c..c7b6c58e3 100644 --- a/libretroshare/src/rsitems/rsnxsitems.h +++ b/libretroshare/src/rsitems/rsnxsitems.h @@ -35,8 +35,12 @@ #include "serialiser/rstlvkeys.h" #include "gxs/rsgxsdata.h" -// These items have "flag type" numbers, but this is not used. +enum class RsNxsSubtype : uint8_t +{ + PULL_REQUEST = 0x90 /// @see RsNxsPullRequestItem +}; +// These items have "flag type" numbers, but this is not used. // TODO: refactor as C++11 enum class const uint8_t RS_PKT_SUBTYPE_NXS_SYNC_GRP_REQ_ITEM = 0x01; const uint8_t RS_PKT_SUBTYPE_NXS_SYNC_GRP_ITEM = 0x02; @@ -50,10 +54,6 @@ const uint8_t RS_PKT_SUBTYPE_NXS_MSG_ITEM = 0x20; const uint8_t RS_PKT_SUBTYPE_NXS_TRANSAC_ITEM = 0x40; const uint8_t RS_PKT_SUBTYPE_NXS_GRP_PUBLISH_KEY_ITEM = 0x80; -enum class RsNxsSubtype : uint8_t -{ - PULL_REQUEST = 0x90 /// @see RsNxsPullRequestItem -}; #ifdef RS_DEAD_CODE // possibility create second service to deal with this functionality @@ -525,8 +525,9 @@ class RsNxsSerialiser : public RsServiceSerializer { public: - explicit RsNxsSerialiser(uint16_t servtype) : RsServiceSerializer(servtype), SERVICE_TYPE(servtype) {} - virtual ~RsNxsSerialiser() {} + explicit RsNxsSerialiser(uint16_t servtype): + RsServiceSerializer(servtype), SERVICE_TYPE(servtype) {} + virtual ~RsNxsSerialiser() = default; virtual RsItem *create_item(uint16_t service_id,uint8_t item_subtype) const ; From a7f1e94ceae97cae75db2466cb2a0618f23a1121 Mon Sep 17 00:00:00 2001 From: Gioacchino Mazzurco Date: Sat, 13 Mar 2021 22:39:59 +0100 Subject: [PATCH 028/113] Request pull from peers when GXS group is created --- libretroshare/src/gxs/rsgenexchange.cc | 17 +++++++++++++---- libretroshare/src/gxs/rsgxsnetservice.h | 24 ++++++++---------------- libretroshare/src/gxs/rsnxs.h | 16 ++++++++++++++++ 3 files changed, 37 insertions(+), 20 deletions(-) diff --git a/libretroshare/src/gxs/rsgenexchange.cc b/libretroshare/src/gxs/rsgenexchange.cc index da8973eb1..152198da2 100644 --- a/libretroshare/src/gxs/rsgenexchange.cc +++ b/libretroshare/src/gxs/rsgenexchange.cc @@ -41,6 +41,7 @@ #include "rsserver/p3face.h" #include "retroshare/rsevents.h" #include "util/radix64.h" +#include "util/cxx17retrocompat.h" #define PUB_GRP_MASK 0x000f #define RESTR_GRP_MASK 0x00f0 @@ -2723,7 +2724,8 @@ bool RsGenExchange::checkKeys(const RsTlvSecurityKeySet& keySet) void RsGenExchange::publishGrps() { - std::list groups_to_subscribe ; + bool atLeastOneGroupCreatedSuccessfully = false; + std::list groups_to_subscribe; { RS_STACK_MUTEX(mGenMtx) ; @@ -2954,6 +2956,8 @@ void RsGenExchange::publishGrps() // add to published to allow acknowledgement toNotify.insert(std::make_pair(token, GrpNote(true,ggps.mIsUpdate,grpId))); + + atLeastOneGroupCreatedSuccessfully = true; } } @@ -2972,9 +2976,14 @@ void RsGenExchange::publishGrps() // This is done off-mutex to avoid possible cross deadlocks with the net service. - if(mNetService!=NULL) - for(std::list::const_iterator it(groups_to_subscribe.begin());it!=groups_to_subscribe.end();++it) - mNetService->subscribeStatusChanged((*it),true) ; + if(mNetService != nullptr) + { + for(auto& grpId : std::as_const(groups_to_subscribe)) + mNetService->subscribeStatusChanged(grpId, true); + + if(atLeastOneGroupCreatedSuccessfully) + mNetService->requestPull(); + } } uint32_t RsGenExchange::generatePublicToken() diff --git a/libretroshare/src/gxs/rsgxsnetservice.h b/libretroshare/src/gxs/rsgxsnetservice.h index 406531852..308f9b067 100644 --- a/libretroshare/src/gxs/rsgxsnetservice.h +++ b/libretroshare/src/gxs/rsgxsnetservice.h @@ -250,6 +250,14 @@ public: void threadTick() override; /// @see RsTickingThread + + /// @see RsNetworkExchangeService + void pullFromPeers(std::set peers = std::set()) override; + + /// @see RsNetworkExchangeService + std::error_condition requestPull( + std::set peers = std::set() ) override; + private: /*! @@ -462,22 +470,6 @@ private: void checkDistantSyncState(); - /** - * @brief Pull new stuff from peers - * @param peers peers to pull from, if empty all available peers are pulled - */ - void pullFromPeers(std::set peers = std::set()); - - /** - * @brief request online peers to pull updates from our node ASAP - * @param peers peers to which request pull from, if empty all available - * peers are requested to pull - * @return success or error details - * TODO: should this be exposed via RsNetworkExchangeService? - */ - std::error_condition requestPull( - std::set peers = std::set() ); - void syncGrpStatistics(); void addGroupItemToList(NxsTransaction*& tr, const RsGxsGroupId& grpId, uint32_t& transN, diff --git a/libretroshare/src/gxs/rsnxs.h b/libretroshare/src/gxs/rsnxs.h index 2f9bb25a6..d74254749 100644 --- a/libretroshare/src/gxs/rsnxs.h +++ b/libretroshare/src/gxs/rsnxs.h @@ -325,4 +325,20 @@ public: return RsReputationLevel::NEUTRAL; } } + + /** + * @brief Pull new stuff from peers + * @param peers peers to pull from, if empty all available peers are pulled + */ + virtual void pullFromPeers( + std::set peers = std::set() ) = 0; + + /** + * @brief request online peers to pull updates from our node ASAP + * @param peers peers to which request pull from, if empty all available + * peers are requested to pull + * @return success or error details + */ + virtual std::error_condition requestPull( + std::set peers = std::set() ) = 0; }; From b42323013eecf9ac73660ef2841f88af30d951c2 Mon Sep 17 00:00:00 2001 From: Gioacchino Mazzurco Date: Sun, 14 Mar 2021 09:28:50 +0100 Subject: [PATCH 029/113] Fix includes in rsnxs.h --- libretroshare/src/gxs/rsnxs.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libretroshare/src/gxs/rsnxs.h b/libretroshare/src/gxs/rsnxs.h index d74254749..5933d4572 100644 --- a/libretroshare/src/gxs/rsnxs.h +++ b/libretroshare/src/gxs/rsnxs.h @@ -26,7 +26,7 @@ #include #include -#include +#include #include #include From 6295e91304963a45094ebe9c8443120b86b28b1e Mon Sep 17 00:00:00 2001 From: Gioacchino Mazzurco Date: Sun, 14 Mar 2021 17:15:00 +0100 Subject: [PATCH 030/113] Request pull from peers when GXS message is created --- libretroshare/src/gxs/rsgenexchange.cc | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/libretroshare/src/gxs/rsgenexchange.cc b/libretroshare/src/gxs/rsgenexchange.cc index 152198da2..fb1b4c295 100644 --- a/libretroshare/src/gxs/rsgenexchange.cc +++ b/libretroshare/src/gxs/rsgenexchange.cc @@ -2286,8 +2286,9 @@ bool RsGenExchange::processGrpMask(const RsGxsGroupId& grpId, ContentValue &grpC void RsGenExchange::publishMsgs() { + bool atLeastOneMessageCreatedSuccessfully = false; - RS_STACK_MUTEX(mGenMtx) ; + RS_STACK_MUTEX(mGenMtx); rstime_t now = time(NULL); @@ -2464,6 +2465,8 @@ void RsGenExchange::publishMsgs() // add to published to allow acknowledgement mMsgNotify.insert(std::make_pair(mit->first, std::make_pair(grpId, msgId))); mDataAccess->updatePublicRequestStatus(mit->first, RsTokenService::COMPLETE); + + atLeastOneMessageCreatedSuccessfully = true; } else { @@ -2497,6 +2500,8 @@ void RsGenExchange::publishMsgs() mNotifications.push_back(ch); } + + if(atLeastOneMessageCreatedSuccessfully) mNetService->requestPull(); } RsGenExchange::ServiceCreate_Return RsGenExchange::service_CreateGroup(RsGxsGrpItem* /* grpItem */, From fc404bd5d87a46d93d5a816a42f66d8023a97f1b Mon Sep 17 00:00:00 2001 From: Gioacchino Mazzurco Date: Tue, 16 Mar 2021 17:51:59 +0100 Subject: [PATCH 031/113] RsGxsNetService trigger pulling on group subscribe --- libretroshare/src/gxs/rsgxsnetservice.cc | 32 +++++++++++------------ libretroshare/src/services/p3gxsforums.cc | 15 ++++++++--- 2 files changed, 28 insertions(+), 19 deletions(-) diff --git a/libretroshare/src/gxs/rsgxsnetservice.cc b/libretroshare/src/gxs/rsgxsnetservice.cc index adea14205..c8295f80b 100644 --- a/libretroshare/src/gxs/rsgxsnetservice.cc +++ b/libretroshare/src/gxs/rsgxsnetservice.cc @@ -1021,32 +1021,32 @@ void RsGxsNetService::locked_resetClientTS(const RsGxsGroupId& grpId) it->second.msgUpdateInfos.erase(grpId) ; } -void RsGxsNetService::subscribeStatusChanged(const RsGxsGroupId& grpId,bool subscribed) +void RsGxsNetService::subscribeStatusChanged( + const RsGxsGroupId& grpId, bool subscribed ) { - RS_STACK_MUTEX(mNxsMutex) ; - - if(!subscribed) - return ; + if(!subscribed) return; // When we subscribe, we reset the time stamps, so that the entire group list // gets requested once again, for a proper update. + RS_STACK_MUTEX(mNxsMutex); + #ifdef NXS_NET_DEBUG_0 - GXSNETDEBUG__G(grpId) << "Changing subscribe status for grp " << grpId << " to " << subscribed << ": reseting all server msg time stamps for this group, and server global TS." << std::endl; - std::map::iterator it = mServerMsgUpdateMap.find(grpId) ; + RS_DBG( "Changing subscribe status for grp", grpId, " to ", subscribed, + ": reseting all server msg time stamps for this group, and " + "server global TS." ); #endif - RsGxsServerMsgUpdate& item(mServerMsgUpdateMap[grpId]) ; + RsGxsServerMsgUpdate& item(mServerMsgUpdateMap[grpId]); + item.msgUpdateTS = static_cast(time(nullptr)); - item.msgUpdateTS = time(NULL) ; + /* We also update mGrpServerUpdateItem so as to trigger a new grp list + * exchange with friends (friends will send their known ClientTS which + * will be lower than our own grpUpdateTS, triggering our sending of the + * new subscribed grp list. */ + mGrpServerUpdate.grpUpdateTS = static_cast(time(nullptr)); - // We also update mGrpServerUpdateItem so as to trigger a new grp list exchange with friends (friends will send their known ClientTS which - // will be lower than our own grpUpdateTS, triggering our sending of the new subscribed grp list. - - mGrpServerUpdate.grpUpdateTS = time(NULL) ; - - if(subscribed) - locked_resetClientTS(grpId) ; + locked_resetClientTS(grpId); } bool RsGxsNetService::fragmentMsg(RsNxsMsg& msg, MsgFragments& msgFragments) const diff --git a/libretroshare/src/services/p3gxsforums.cc b/libretroshare/src/services/p3gxsforums.cc index 6cb3ae5c6..c930046a9 100644 --- a/libretroshare/src/services/p3gxsforums.cc +++ b/libretroshare/src/services/p3gxsforums.cc @@ -900,10 +900,19 @@ bool p3GxsForums::markRead(const RsGxsGrpMsgIdPair& msgId, bool read) bool p3GxsForums::subscribeToForum(const RsGxsGroupId& groupId, bool subscribe ) { uint32_t token; - if( !RsGenExchange::subscribeToGroup(token, groupId, subscribe) || waitToken(token) != RsTokenService::COMPLETE ) return false; + if( !RsGenExchange::subscribeToGroup(token, groupId, subscribe) || + waitToken(token) != RsTokenService::COMPLETE ) return false; - RsGxsGroupId grp; - acknowledgeGrp(token,grp); + RsGxsGroupId grp; + acknowledgeGrp(token, grp); + + /* Since subscribe has been requested, the caller is most probably + * interested in getting the group messages ASAP so pull from peers without + * waiting GXS sync timer. + * Do it here as this is meaningful or not depending on the service. + * Do it only after the token has been completed otherwise the pull have no + * effect. */ + if(subscribe) RsGenExchange::netService()->pullFromPeers(); return true; } From ebbd8cf938ef4fd913bc2bc036eae2dd5ebe4bec Mon Sep 17 00:00:00 2001 From: Gioacchino Mazzurco Date: Mon, 22 Mar 2021 17:46:46 +0100 Subject: [PATCH 032/113] Forums expose API to request syncronization --- libretroshare/src/retroshare/rsgxsforums.h | 11 +++++++++++ libretroshare/src/services/p3gxsforums.cc | 6 ++++++ libretroshare/src/services/p3gxsforums.h | 2 ++ 3 files changed, 19 insertions(+) diff --git a/libretroshare/src/retroshare/rsgxsforums.h b/libretroshare/src/retroshare/rsgxsforums.h index 4967d46c5..ba13bd16e 100644 --- a/libretroshare/src/retroshare/rsgxsforums.h +++ b/libretroshare/src/retroshare/rsgxsforums.h @@ -450,6 +450,17 @@ public: const std::string& matchString, std::vector& searchResults ) = 0; + /** + * @brief Request Synchronization with available peers + * Usually syncronization already happen automatically so be carefull + * to call this method only if necessary. + * It has been thinked for use cases like mobile phone where internet + * connection is intermittent and calling this may be useful when a system + * event about connection being available or about to go offline is received + * @jsonapi{development} + * @return Success or error details + */ + virtual std::error_condition requestSynchronization() = 0; //////////////////////////////////////////////////////////////////////////// /* Following functions are deprecated and should not be considered a stable diff --git a/libretroshare/src/services/p3gxsforums.cc b/libretroshare/src/services/p3gxsforums.cc index c930046a9..81f03b6ec 100644 --- a/libretroshare/src/services/p3gxsforums.cc +++ b/libretroshare/src/services/p3gxsforums.cc @@ -1159,6 +1159,12 @@ std::error_condition p3GxsForums::setPostKeepForever( } } +std::error_condition p3GxsForums::requestSynchronization() +{ + RsGenExchange::netService()->pullFromPeers(); + return RsGenExchange::netService()->requestPull(); +} + /* so we need the same tick idea as wiki for generating dummy forums */ diff --git a/libretroshare/src/services/p3gxsforums.h b/libretroshare/src/services/p3gxsforums.h index b499e7b0d..9400de652 100644 --- a/libretroshare/src/services/p3gxsforums.h +++ b/libretroshare/src/services/p3gxsforums.h @@ -175,6 +175,8 @@ public: rs_owner_ptr& resultData, uint32_t& resultSize ) override; #endif + std::error_condition requestSynchronization() override; + /// implementation of rsGxsGorums /// bool getGroupData(const uint32_t &token, std::vector &groups) override; From cd5dad6a753406e61d869dd0385a3d6d184f01a7 Mon Sep 17 00:00:00 2001 From: Gioacchino Mazzurco Date: Fri, 12 Nov 2021 19:03:02 +0100 Subject: [PATCH 033/113] Rename GXS pullFromPeers to pullFromPeers According to what discussed with Cyril --- libretroshare/src/gxs/rsgxsnetservice.cc | 25 +++++++++++++---------- libretroshare/src/gxs/rsgxsnetservice.h | 3 ++- libretroshare/src/gxs/rsnxs.h | 6 +++--- libretroshare/src/services/p3gxsforums.cc | 9 ++++---- 4 files changed, 24 insertions(+), 19 deletions(-) diff --git a/libretroshare/src/gxs/rsgxsnetservice.cc b/libretroshare/src/gxs/rsgxsnetservice.cc index c8295f80b..c93d8e1e1 100644 --- a/libretroshare/src/gxs/rsgxsnetservice.cc +++ b/libretroshare/src/gxs/rsgxsnetservice.cc @@ -35,7 +35,7 @@ // | // +----------- sharePublishKeys() // | -// +----------- pullFromPeers() +// +----------- checkUpdatesFromPeers() // | | // | +--if AutoSync--- send global UpdateTS of each peer to itself => the peer knows the last // | | time current peer has received an updated from himself @@ -127,14 +127,14 @@ // (Set at server side to be mGrpServerUpdateItem->grpUpdateTS) // // Only updated in processCompletedIncomingTransaction() from Grp list transaction. -// Used in pullFromPeers() sending in RsNxsSyncGrp once to all peers: peer will send data if +// Used in checkUpdatesFromPeers() sending in RsNxsSyncGrp once to all peers: peer will send data if // has something new. All time comparisons are in the friends' clock time. // // mClientMsgUpdateMap: map< RsPeerId, map > // // Last msg list modification time sent by that peer Id // Updated in processCompletedIncomingTransaction() from Grp list trans. -// Used in pullFromPeers() sending in RsNxsSyncGrp once to all peers. +// Used in checkUpdatesFromPeers() sending in RsNxsSyncGrp once to all peers. // Set at server to be mServerMsgUpdateMap[grpId]->msgUpdateTS // // mGrpServerUpdateItem: TimeStamp Last group local modification timestamp over all groups @@ -150,7 +150,7 @@ // // tick() tick() // | | -// +---- pullFromPeers +-- recvNxsItemQueue() +// +---- checkUpdatesFromPeers() +-- recvNxsItemQueue() // | | // +---------------- Send global UpdateTS of each peer to itself => the peer knows +---------> +------ handleRecvSyncGroup( RsNxsSyncGrp*) // | the last msg sent (stored in mClientGrpUpdateMap[peer_id]), | | - parse all subscribed groups. For each, send a RsNxsSyncGrpItem with publish TS @@ -457,7 +457,7 @@ int RsGxsNetService::tick() if((elapsed) < now) { - pullFromPeers(); + checkUpdatesFromPeers(); syncGrpStatistics(); checkDistantSyncState(); @@ -570,7 +570,8 @@ RsGxsGroupId RsGxsNetService::hashGrpId(const RsGxsGroupId& gid,const RsPeerId& return RsGxsGroupId( RsDirUtil::sha1sum(tmpmem,SIZE).toByteArray() ); } -void RsGxsNetService::pullFromPeers(std::set peers) +std::error_condition RsGxsNetService::checkUpdatesFromPeers( + std::set peers ) { #ifdef NXS_NET_DEBUG_0 RS_DBG("this=", (void*)this, ". serviceInfo=", mServiceInfo); @@ -594,8 +595,8 @@ void RsGxsNetService::pullFromPeers(std::set peers) } } - // Still empty? Then nothing to do - if (peers.empty()) return; + // Still empty? Reports there are no available peers + if (peers.empty()) return std::errc::network_down; RS_STACK_MUTEX(mNxsMutex); @@ -624,7 +625,7 @@ void RsGxsNetService::pullFromPeers(std::set peers) generic_sendItem(grp); } - if(!mAllowMsgSync) return; + if(!mAllowMsgSync) return std::error_condition(); #ifndef GXS_DISABLE_SYNC_MSGS @@ -742,7 +743,9 @@ void RsGxsNetService::pullFromPeers(std::set peers) } } -#endif +#endif // ndef GXS_DISABLE_SYNC_MSGS + + return std::error_condition(); } void RsGxsNetService::generic_sendItem(rs_owner_ptr si) @@ -5123,7 +5126,7 @@ std::error_condition RsGxsNetService::requestPull(std::set peers) void RsGxsNetService::handlePullRequest( std::unique_ptr item ) { - pullFromPeers(std::set{item->PeerId()}); + checkUpdatesFromPeers(std::set{item->PeerId()}); } bool RsGxsNetService::getGroupServerUpdateTS(const RsGxsGroupId& gid,rstime_t& group_server_update_TS, rstime_t& msg_server_update_TS) diff --git a/libretroshare/src/gxs/rsgxsnetservice.h b/libretroshare/src/gxs/rsgxsnetservice.h index 308f9b067..0baee2a2f 100644 --- a/libretroshare/src/gxs/rsgxsnetservice.h +++ b/libretroshare/src/gxs/rsgxsnetservice.h @@ -252,7 +252,8 @@ public: /// @see RsNetworkExchangeService - void pullFromPeers(std::set peers = std::set()) override; + std::error_condition checkUpdatesFromPeers( + std::set peers = std::set() ) override; /// @see RsNetworkExchangeService std::error_condition requestPull( diff --git a/libretroshare/src/gxs/rsnxs.h b/libretroshare/src/gxs/rsnxs.h index 5933d4572..2197d0e7a 100644 --- a/libretroshare/src/gxs/rsnxs.h +++ b/libretroshare/src/gxs/rsnxs.h @@ -327,10 +327,10 @@ public: } /** - * @brief Pull new stuff from peers - * @param peers peers to pull from, if empty all available peers are pulled + * @brief Check if new stuff is available from peers + * @param peers peers to check, if empty all available peers are checked */ - virtual void pullFromPeers( + virtual std::error_condition checkUpdatesFromPeers( std::set peers = std::set() ) = 0; /** diff --git a/libretroshare/src/services/p3gxsforums.cc b/libretroshare/src/services/p3gxsforums.cc index 81f03b6ec..97d880880 100644 --- a/libretroshare/src/services/p3gxsforums.cc +++ b/libretroshare/src/services/p3gxsforums.cc @@ -907,12 +907,12 @@ bool p3GxsForums::subscribeToForum(const RsGxsGroupId& groupId, bool subscribe ) acknowledgeGrp(token, grp); /* Since subscribe has been requested, the caller is most probably - * interested in getting the group messages ASAP so pull from peers without - * waiting GXS sync timer. + * interested in getting the group messages ASAP so check updates from peers + * without waiting GXS sync timer. * Do it here as this is meaningful or not depending on the service. * Do it only after the token has been completed otherwise the pull have no * effect. */ - if(subscribe) RsGenExchange::netService()->pullFromPeers(); + if(subscribe) RsGenExchange::netService()->checkUpdatesFromPeers(); return true; } @@ -1161,7 +1161,8 @@ std::error_condition p3GxsForums::setPostKeepForever( std::error_condition p3GxsForums::requestSynchronization() { - RsGenExchange::netService()->pullFromPeers(); + auto errc = RsGenExchange::netService()->checkUpdatesFromPeers(); + if(errc) return errc; return RsGenExchange::netService()->requestPull(); } From 1146a0bf2750641563a3a1a2effd611ce21651ca Mon Sep 17 00:00:00 2001 From: Phenom Date: Fri, 12 Nov 2021 19:28:48 +0100 Subject: [PATCH 034/113] Fix QSplitter and TitleBar StyleSheet. --- retroshare-gui/src/gui/chat/ChatWidget.cpp | 2 +- retroshare-gui/src/gui/chat/ChatWidget.ui | 4 +-- .../src/gui/qss/stylesheet/Standard_Dark.qss | 12 ++++---- .../src/gui/qss/stylesheet/Standard_Light.qss | 29 ++++++++++++------- .../src/gui/qss/stylesheet/default.qss | 28 ------------------ 5 files changed, 28 insertions(+), 47 deletions(-) diff --git a/retroshare-gui/src/gui/chat/ChatWidget.cpp b/retroshare-gui/src/gui/chat/ChatWidget.cpp index d4a20fe74..a909e3e27 100644 --- a/retroshare-gui/src/gui/chat/ChatWidget.cpp +++ b/retroshare-gui/src/gui/chat/ChatWidget.cpp @@ -381,7 +381,7 @@ void ChatWidget::init(const ChatId &chat_id, const QString &title) hist_chat_type = RS_HISTORY_TYPE_PUBLIC; messageCount = Settings->getPublicChatHistoryCount(); - ui->titleBarFrame->setVisible(false); + ui->headerBFrame->setVisible(false); } if (rsHistory->getEnable(hist_chat_type)) diff --git a/retroshare-gui/src/gui/chat/ChatWidget.ui b/retroshare-gui/src/gui/chat/ChatWidget.ui index 88e501335..879c99d00 100644 --- a/retroshare-gui/src/gui/chat/ChatWidget.ui +++ b/retroshare-gui/src/gui/chat/ChatWidget.ui @@ -32,7 +32,7 @@ QLayout::SetMaximumSize - + 0 @@ -51,7 +51,7 @@ QFrame::Plain - + 2 diff --git a/retroshare-gui/src/gui/qss/stylesheet/Standard_Dark.qss b/retroshare-gui/src/gui/qss/stylesheet/Standard_Dark.qss index f2097d0be..fc95d1d46 100644 --- a/retroshare-gui/src/gui/qss/stylesheet/Standard_Dark.qss +++ b/retroshare-gui/src/gui/qss/stylesheet/Standard_Dark.qss @@ -2248,13 +2248,13 @@ QTreeView:branch:selected:!active { /**** Fix QSplitter ****/ QSplitter { - background-color: #19232D; + background-color: rgba(0,0,0,0); } - QSplitter::handle { - background-color: #455364; - border: 0px solid #455364; - border-radius: 4px; + background-color: rgba(0,0,0,0); + border: 0px; + border-radius: 2px; + padding: 0px; } @@ -2286,7 +2286,7 @@ QFrame#bottomFrame,/* Frame used at the bottom of dialog*/ QFrame#toasterFrame,/* Frame used in Toasters*/ QFrame#toolBarFrame {/* Frame used for buttons*/ background-color: qlineargradient(x1:0, y1:0, x2:0, y2:1, stop:0 #19232D, stop:1 #32414B); - border: 1px solid #CCCCCC; + border: 1px solid #455364; } QFrame#toolBarFrame > LineEditClear { background-color: #29333D; diff --git a/retroshare-gui/src/gui/qss/stylesheet/Standard_Light.qss b/retroshare-gui/src/gui/qss/stylesheet/Standard_Light.qss index 85f601e3e..e6616c855 100644 --- a/retroshare-gui/src/gui/qss/stylesheet/Standard_Light.qss +++ b/retroshare-gui/src/gui/qss/stylesheet/Standard_Light.qss @@ -2248,13 +2248,13 @@ QTreeView:branch:selected:!active { /**** Fix QSplitter ****/ QSplitter { - background-color: white; + background-color: rgba(0,0,0,0); } - QSplitter::handle { - background-color: #C9CDD0; - border: 0px solid #C9CDD0; - border-radius: 4px; + background-color: rgba(0,0,0,0); + border: 0px; + border-radius: 2px; + padding: 0px; } @@ -2307,12 +2307,11 @@ QLabel#avatarLabel{ } -/* HeaderFrame & TitleBarFrame */ +/* HeaderFrame */ QFrame[objectName^="headerFrame"], QFrame[objectName^="headerBFrame"], -QToolBar#headerToolBar, -QFrame#titleBarFrame { +QToolBar#headerToolBar { background-color: qlineargradient(x1:0, y1:0, x2:0, y2:1, stop:0 #9BDBF9, stop:1 #1592CD); border: 0px; } @@ -2321,11 +2320,21 @@ QFrame[objectName^="#headerBFrame"] { border-radius: 4px; } QFrame[objectName^="headerFrame"] > *:!hover, -QFrame[objectName^="headerBFrame"] > *:!hover, -QFrame#titleBarFrame > *:!hover { +QFrame[objectName^="headerBFrame"] > *:!hover { background: transparent; color: white; } + +/* TitleBarFrame */ + +QFrame#titleBarFrame { + background-color: qlineargradient(x1:0, y1:0, x2:0, y2:1, stop:0 #F0F8FD, stop:1 #E6F2FD); + border: 0px; +} +QFrame#titleBarFrame > *:!hover { + background: transparent; + color: black; +} QFrame#titleBarFrame QComboBox, QFrame#titleBarFrame QLineEdit, QFrame#titleBarFrame QTextEdit { diff --git a/retroshare-gui/src/gui/qss/stylesheet/default.qss b/retroshare-gui/src/gui/qss/stylesheet/default.qss index 40d0b06ea..d1730bfef 100644 --- a/retroshare-gui/src/gui/qss/stylesheet/default.qss +++ b/retroshare-gui/src/gui/qss/stylesheet/default.qss @@ -418,31 +418,3 @@ OpModeStatus[opMode="Minimal"] { [WrongValue="true"] { background-color: #FF8080; } - -/* HeaderFrame & TitleBarFrame */ - -QFrame[objectName^="headerFrame"], -QFrame[objectName^="headerBFrame"] { - background-color: qlineargradient(x1:0, y1:0, x2:0, y2:1, stop:0 #9BDBF9, stop:1 #1592CD); - border: 1px; - border-radius: 4px; -} -QFrame[objectName^="#headerBFrame"] { - border: 1px; - border-radius: 4px; -} -QFrame[objectName^="headerFrame"] > *:!hover, -QFrame[objectName^="headerBFrame"] > *:!hover{ - background: transparent; - color: white; -} - -QFrame#toolBarFrame, QFrame#toolBarFrameTop { - background-color: qlineargradient(x1:0, y1:0, x2:0, y2:1, stop:0 #FEFEFE, stop:1 #E8E8E8); - border: 1px solid #CCCCCC; -} - -ChatWidget QFrame#titleBarFrame { - background-color: qlineargradient(x1:0, y1:0, x2:0, y2:1, stop:0 #FEFEFE, stop:1 #E8E8E8); - border: 1px solid #CCCCCC; -} From 1e9a26893cdfe5f92a833d03a75d970baab2d8b2 Mon Sep 17 00:00:00 2001 From: Gioacchino Mazzurco Date: Tue, 16 Nov 2021 10:52:18 +0100 Subject: [PATCH 035/113] Forum deep search support wildcard* search Xapian have support for wildcard search wild* matches wild, wildcard, wildcat, wilderness but it need to be enabled by passing a specific flag to the query parser, this is very useful for forum search so enable it in addition to default Xapian search capabilities --- libretroshare/src/deep_search/forumsindex.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/libretroshare/src/deep_search/forumsindex.cpp b/libretroshare/src/deep_search/forumsindex.cpp index acc7aed9a..a04f2ecac 100644 --- a/libretroshare/src/deep_search/forumsindex.cpp +++ b/libretroshare/src/deep_search/forumsindex.cpp @@ -46,7 +46,9 @@ std::error_condition DeepForumsIndex::search( // End of prefix configuration. // And parse the query. - Xapian::Query query = queryparser.parse_query(queryStr); + using XQP = Xapian::QueryParser; + Xapian::Query query = queryparser.parse_query( + queryStr, XQP::FLAG_WILDCARD | XQP::FLAG_DEFAULT ); // Use an Enquire object on the database to run the query. Xapian::Enquire enquire(db); From 3845dc1ea7fa759793f76cb55ae66f6979006a2b Mon Sep 17 00:00:00 2001 From: csoler Date: Mon, 22 Nov 2021 20:06:01 +0100 Subject: [PATCH 036/113] 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 037/113] 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: Tue, 9 Nov 2021 16:24:22 +0100 Subject: [PATCH 038/113] Remove unused skins. --- plugins/VOIP/gui/AudioWizard.cpp | 4 +- retroshare-gui/src/main.cpp | 4 - .../src/release/skin/Bliss/maxButton.png | Bin 494 -> 0 bytes .../src/release/skin/Bliss/maxButton1.png | Bin 248 -> 0 bytes .../src/release/skin/Bliss/maxButton2.png | Bin 248 -> 0 bytes .../src/release/skin/Bliss/minButton.png | Bin 324 -> 0 bytes .../src/release/skin/Bliss/minButton1.png | Bin 208 -> 0 bytes .../src/release/skin/Bliss/minButton2.png | Bin 208 -> 0 bytes .../src/release/skin/Bliss/quiButton.png | Bin 873 -> 0 bytes .../src/release/skin/Bliss/quiButton1.png | Bin 516 -> 0 bytes .../src/release/skin/Bliss/quiButton2.png | Bin 438 -> 0 bytes retroshare-gui/src/release/skin/Bliss/sl.png | Bin 764 -> 0 bytes retroshare-gui/src/release/skin/Bliss/so.png | Bin 1047 -> 0 bytes retroshare-gui/src/release/skin/Bliss/sr.png | Bin 394 -> 0 bytes retroshare-gui/src/release/skin/Bliss/su.png | Bin 583 -> 0 bytes .../src/release/skin/Glassy/maxButton.png | Bin 290 -> 0 bytes .../src/release/skin/Glassy/minButton.png | Bin 272 -> 0 bytes .../src/release/skin/Glassy/quiButton.png | Bin 395 -> 0 bytes retroshare-gui/src/release/skin/Glassy/sl.png | Bin 154 -> 0 bytes retroshare-gui/src/release/skin/Glassy/so.png | Bin 426 -> 0 bytes retroshare-gui/src/release/skin/Glassy/sr.png | Bin 154 -> 0 bytes retroshare-gui/src/release/skin/Glassy/su.png | Bin 233 -> 0 bytes .../src/release/skin/Green/maxButton.png | Bin 1002 -> 0 bytes .../src/release/skin/Green/minButton.png | Bin 991 -> 0 bytes .../src/release/skin/Green/quiButton.png | Bin 1019 -> 0 bytes retroshare-gui/src/release/skin/Green/sl.png | Bin 101 -> 0 bytes retroshare-gui/src/release/skin/Green/so.png | Bin 5795 -> 0 bytes retroshare-gui/src/release/skin/Green/sr.png | Bin 102 -> 0 bytes retroshare-gui/src/release/skin/Green/su.png | Bin 153 -> 0 bytes .../release/skin/Night Vision/maxButton.png | Bin 3120 -> 0 bytes .../release/skin/Night Vision/minButton.png | Bin 3051 -> 0 bytes .../release/skin/Night Vision/quiButton.png | Bin 4536 -> 0 bytes .../src/release/skin/Night Vision/sl.png | Bin 263 -> 0 bytes .../src/release/skin/Night Vision/so.png | Bin 2314 -> 0 bytes .../src/release/skin/Night Vision/sr.png | Bin 262 -> 0 bytes .../src/release/skin/Night Vision/su.png | Bin 292 -> 0 bytes .../src/release/skin/Vista/maxButton.png | Bin 3120 -> 0 bytes .../src/release/skin/Vista/maxButton1.png | Bin 690 -> 0 bytes .../src/release/skin/Vista/maxButton2.png | Bin 1072 -> 0 bytes .../src/release/skin/Vista/minButton.png | Bin 3051 -> 0 bytes .../src/release/skin/Vista/minButton1.png | Bin 678 -> 0 bytes .../src/release/skin/Vista/minButton2.png | Bin 993 -> 0 bytes .../src/release/skin/Vista/quiButton.png | Bin 4536 -> 0 bytes .../src/release/skin/Vista/quiButton1.png | Bin 950 -> 0 bytes .../src/release/skin/Vista/quiButton2.png | Bin 1443 -> 0 bytes retroshare-gui/src/release/skin/Vista/sl.png | Bin 700 -> 0 bytes retroshare-gui/src/release/skin/Vista/so.png | Bin 8890 -> 0 bytes retroshare-gui/src/release/skin/Vista/sr.png | Bin 661 -> 0 bytes retroshare-gui/src/release/skin/Vista/su.png | Bin 352 -> 0 bytes .../src/release/skin/VistaAlpha/bg.png | Bin 19839 -> 0 bytes .../src/release/skin/VistaAlpha/maxButton.png | Bin 3201 -> 0 bytes .../release/skin/VistaAlpha/maxButton1.png | Bin 690 -> 0 bytes .../release/skin/VistaAlpha/maxButton2.png | Bin 1072 -> 0 bytes .../src/release/skin/VistaAlpha/minButton.png | Bin 3063 -> 0 bytes .../release/skin/VistaAlpha/minButton1.png | Bin 678 -> 0 bytes .../release/skin/VistaAlpha/minButton2.png | Bin 993 -> 0 bytes .../src/release/skin/VistaAlpha/quiButton.png | Bin 4637 -> 0 bytes .../release/skin/VistaAlpha/quiButton1.png | Bin 950 -> 0 bytes .../release/skin/VistaAlpha/quiButton2.png | Bin 1443 -> 0 bytes .../src/release/skin/VistaAlpha/sl.png | Bin 2161 -> 0 bytes .../src/release/skin/VistaAlpha/so.png | Bin 8160 -> 0 bytes .../src/release/skin/VistaAlpha/sr.png | Bin 1847 -> 0 bytes .../src/release/skin/VistaAlpha/su.png | Bin 4735 -> 0 bytes retroshare-gui/src/release/skin/skin.dat | 7 - retroshare-gui/src/retroshare-process.nsi | 502 --------------- retroshare-gui/src/retroshare-ultramodern.nsi | 501 --------------- retroshare-gui/src/retroshare.in | 594 ----------------- retroshare-gui/src/retroshare.nsi | 595 ------------------ 68 files changed, 2 insertions(+), 2205 deletions(-) delete mode 100644 retroshare-gui/src/release/skin/Bliss/maxButton.png delete mode 100644 retroshare-gui/src/release/skin/Bliss/maxButton1.png delete mode 100644 retroshare-gui/src/release/skin/Bliss/maxButton2.png delete mode 100644 retroshare-gui/src/release/skin/Bliss/minButton.png delete mode 100644 retroshare-gui/src/release/skin/Bliss/minButton1.png delete mode 100644 retroshare-gui/src/release/skin/Bliss/minButton2.png delete mode 100644 retroshare-gui/src/release/skin/Bliss/quiButton.png delete mode 100644 retroshare-gui/src/release/skin/Bliss/quiButton1.png delete mode 100644 retroshare-gui/src/release/skin/Bliss/quiButton2.png delete mode 100644 retroshare-gui/src/release/skin/Bliss/sl.png delete mode 100644 retroshare-gui/src/release/skin/Bliss/so.png delete mode 100644 retroshare-gui/src/release/skin/Bliss/sr.png delete mode 100644 retroshare-gui/src/release/skin/Bliss/su.png delete mode 100644 retroshare-gui/src/release/skin/Glassy/maxButton.png delete mode 100644 retroshare-gui/src/release/skin/Glassy/minButton.png delete mode 100644 retroshare-gui/src/release/skin/Glassy/quiButton.png delete mode 100644 retroshare-gui/src/release/skin/Glassy/sl.png delete mode 100644 retroshare-gui/src/release/skin/Glassy/so.png delete mode 100644 retroshare-gui/src/release/skin/Glassy/sr.png delete mode 100644 retroshare-gui/src/release/skin/Glassy/su.png delete mode 100644 retroshare-gui/src/release/skin/Green/maxButton.png delete mode 100644 retroshare-gui/src/release/skin/Green/minButton.png delete mode 100644 retroshare-gui/src/release/skin/Green/quiButton.png delete mode 100644 retroshare-gui/src/release/skin/Green/sl.png delete mode 100644 retroshare-gui/src/release/skin/Green/so.png delete mode 100644 retroshare-gui/src/release/skin/Green/sr.png delete mode 100644 retroshare-gui/src/release/skin/Green/su.png delete mode 100644 retroshare-gui/src/release/skin/Night Vision/maxButton.png delete mode 100644 retroshare-gui/src/release/skin/Night Vision/minButton.png delete mode 100644 retroshare-gui/src/release/skin/Night Vision/quiButton.png delete mode 100644 retroshare-gui/src/release/skin/Night Vision/sl.png delete mode 100644 retroshare-gui/src/release/skin/Night Vision/so.png delete mode 100644 retroshare-gui/src/release/skin/Night Vision/sr.png delete mode 100644 retroshare-gui/src/release/skin/Night Vision/su.png delete mode 100644 retroshare-gui/src/release/skin/Vista/maxButton.png delete mode 100644 retroshare-gui/src/release/skin/Vista/maxButton1.png delete mode 100644 retroshare-gui/src/release/skin/Vista/maxButton2.png delete mode 100644 retroshare-gui/src/release/skin/Vista/minButton.png delete mode 100644 retroshare-gui/src/release/skin/Vista/minButton1.png delete mode 100644 retroshare-gui/src/release/skin/Vista/minButton2.png delete mode 100644 retroshare-gui/src/release/skin/Vista/quiButton.png delete mode 100644 retroshare-gui/src/release/skin/Vista/quiButton1.png delete mode 100644 retroshare-gui/src/release/skin/Vista/quiButton2.png delete mode 100644 retroshare-gui/src/release/skin/Vista/sl.png delete mode 100644 retroshare-gui/src/release/skin/Vista/so.png delete mode 100644 retroshare-gui/src/release/skin/Vista/sr.png delete mode 100644 retroshare-gui/src/release/skin/Vista/su.png delete mode 100644 retroshare-gui/src/release/skin/VistaAlpha/bg.png delete mode 100644 retroshare-gui/src/release/skin/VistaAlpha/maxButton.png delete mode 100644 retroshare-gui/src/release/skin/VistaAlpha/maxButton1.png delete mode 100644 retroshare-gui/src/release/skin/VistaAlpha/maxButton2.png delete mode 100644 retroshare-gui/src/release/skin/VistaAlpha/minButton.png delete mode 100644 retroshare-gui/src/release/skin/VistaAlpha/minButton1.png delete mode 100644 retroshare-gui/src/release/skin/VistaAlpha/minButton2.png delete mode 100644 retroshare-gui/src/release/skin/VistaAlpha/quiButton.png delete mode 100644 retroshare-gui/src/release/skin/VistaAlpha/quiButton1.png delete mode 100644 retroshare-gui/src/release/skin/VistaAlpha/quiButton2.png delete mode 100644 retroshare-gui/src/release/skin/VistaAlpha/sl.png delete mode 100644 retroshare-gui/src/release/skin/VistaAlpha/so.png delete mode 100644 retroshare-gui/src/release/skin/VistaAlpha/sr.png delete mode 100644 retroshare-gui/src/release/skin/VistaAlpha/su.png delete mode 100644 retroshare-gui/src/release/skin/skin.dat delete mode 100644 retroshare-gui/src/retroshare-process.nsi delete mode 100644 retroshare-gui/src/retroshare-ultramodern.nsi delete mode 100644 retroshare-gui/src/retroshare.in delete mode 100644 retroshare-gui/src/retroshare.nsi diff --git a/plugins/VOIP/gui/AudioWizard.cpp b/plugins/VOIP/gui/AudioWizard.cpp index cbf24d9b4..8c0841d1f 100644 --- a/plugins/VOIP/gui/AudioWizard.cpp +++ b/plugins/VOIP/gui/AudioWizard.cpp @@ -104,8 +104,8 @@ AudioWizard::AudioWizard(QWidget *p) : QWizard(p) { iMaxPeak = 0; iTicks = 0; - qpTalkingOn = QPixmap::fromImage(QImage(QLatin1String("skin:talking_on.svg")).scaled(64,64)); - qpTalkingOff = QPixmap::fromImage(QImage(QLatin1String("skin:talking_off.svg")).scaled(64,64)); + qpTalkingOn = QPixmap::fromImage(QImage(QLatin1String(":/images/talking_on.svg")).scaled(64,64)); + qpTalkingOff = QPixmap::fromImage(QImage(QLatin1String(":/images/talking_off.svg")).scaled(64,64)); bInit = false; diff --git a/retroshare-gui/src/main.cpp b/retroshare-gui/src/main.cpp index cfb9932ca..e7c191487 100644 --- a/retroshare-gui/src/main.cpp +++ b/retroshare-gui/src/main.cpp @@ -99,10 +99,6 @@ __declspec(dllexport) __cdecl BOOL _OPENSSL_isservice(void) #endif #endif -/*** WINDOWS DON'T LIKE THIS - REDEFINES VER numbers. -#include -****/ - #include #include #include diff --git a/retroshare-gui/src/release/skin/Bliss/maxButton.png b/retroshare-gui/src/release/skin/Bliss/maxButton.png deleted file mode 100644 index 4d83bcd3509bdc5ef02a0419609b5833860ddc07..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 494 zcmV5!Kc0+J7(zeDIC*C@Hf%|P_~2L@(lX2=YdpMMxsmE=Iqmy?621&T1fc=wemZh%B81OTHJ z>IQ@Sy~qrZ8Qy{Z$ExR4pN}Vpa_S1&)zc-4H$p^`i0DojEKNg zw0y-1DC-|8aCCIUBfks*163}@8Q_+TU1E|@oEG)ra@ocD)4hB}-f* zN`mv#O3D+9QW+dm@{>{(JaZG%Q-e|yQz{EjrrH1%nFaWSxN2%@nwgn7Iywpp3bM1a zdwY8a1qFTo_3!7eUw{Apm64Ho@$T#E58uCh{eJJ+`+eu1JbUx`-@kvIUjj>jCU|(d zIEGZ*3OT{a*I>Zma`ED-D^0im>T8$y@ai|#9GLp>OhL+uL}mRqiK_ZGiE^{Qo0$Fj ta68&%mdU5KnWDcPL&cZN-?^!MfWh2>qgHL>Z7rag44$rjF6*2UngDWeVX^=K diff --git a/retroshare-gui/src/release/skin/Bliss/maxButton2.png b/retroshare-gui/src/release/skin/Bliss/maxButton2.png deleted file mode 100644 index aaba43674236f3754092a1a5d04fe59ceaaacb9e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 248 zcmeAS@N?(olHy`uVBq!ia0vp^{6NgZ!3-q3=7?VdQY`6?zK#qG>ra@ocD)4hB}-f* zN`mv#O3D+9QW+dm@{>{(JaZG%Q-e|yQz{EjrrH1%nFaWSxT>UYH^|>>Rep#+Y%QDr z3eVkr?*eEoj!+53IxpFDf>`QN{P%^POf0!{Gn zba4!+xD|4Oldr*m!{y?|Ra=^F|JBzn@!{2PtT{0C;hBPz6^W|)ZxWUDZ4%{Xe>XAv v_2G83%Pf;mZ8JrGJBErcm%npU`v8N*EsomHKaCQAW-@rX`njxgN@xNAy6|YL diff --git a/retroshare-gui/src/release/skin/Bliss/minButton.png b/retroshare-gui/src/release/skin/Bliss/minButton.png deleted file mode 100644 index 7f1553a6e9254aa144f2fc69040868aa53c30813..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 324 zcmeAS@N?(olHy`uVBq!ia0vp^{6MV2!NkD8xbDXBIv|I=#M9T6{W_PhC@)_#M~E3v zh_k>WvY3HET>yj`r(_070tH#p9eo`c7&i8E|4C#8@-KV3IEGZ*O1@M6kCU01`SJJo z{|;B~@2_tZIepOk{6v<{04Bi}h7}?#4x$d0Cr&LmmNYT(=hx|i2QBNqN`9SUSoibS zTt?}HKi}WWhjC5|mv^v|S?l}2>39FUg-0}IpK>l(sQk7pq)fDEh0q5xF9XG%w3L)1 zO20nyo2A$M`6PRjS0Meuecls}T%1=O1^K?u+ncT+W$^FM*KU@pJA&B44!GwCX+xyd}>85?%U&Xku2|SZ`oSa^$88v0Kwb9|0UoTl0?(IJ+ UQ}v9u59mDxPgg&ebxsLQ0B3=H^#A|> diff --git a/retroshare-gui/src/release/skin/Bliss/minButton1.png b/retroshare-gui/src/release/skin/Bliss/minButton1.png deleted file mode 100644 index a3c564cddce1de210d719b6267048bd732c3d8f2..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 208 zcmeAS@N?(olHy`uVBq!ia0vp^{6NgZ!3-q3=7?VdQY`6?zK#qG>ra@ocD)4hB}-f* zN`mv#O3D+9QW+dm@{>{(JaZG%Q-e|yQz{EjrrH1%sRa0hxW0Jz_4SAEK|w*9nwnp} ze*gLF*S%-&_nm+8_wV2Dzy3XY^ZDPue|uxkv;)-}dAc};RNQJgzLJqaQQ*Jzopr E06mda-~a#s diff --git a/retroshare-gui/src/release/skin/Bliss/minButton2.png b/retroshare-gui/src/release/skin/Bliss/minButton2.png deleted file mode 100644 index 01af810b0d024d23f5074f6b3a5b7984afa99415..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 208 zcmeAS@N?(olHy`uVBq!ia0vp^{6NgZ!3-q3=7?VdQY`6?zK#qG>ra@ocD)4hB}-f* zN`mv#O3D+9QW+dm@{>{(JaZG%Q-e|yQz{EjrrH1%sRa0hxW0Jz_4SAEp3SFJ(zk#4 z`u*pxU-zE9-*^7W-@kvq|N8gr&F6pr{$2XLSpcZs$kW9!q~cb~@s*4WiUJ1?=oIYv z`@LF0Ah5?P!_BnoqvYL)Z+{Y9Ty~Xhe){^%miPunhP&HYnfTu->;~#)@O1TaS?83{ F1OVIES84zN diff --git a/retroshare-gui/src/release/skin/Bliss/quiButton.png b/retroshare-gui/src/release/skin/Bliss/quiButton.png deleted file mode 100644 index 6a657ae1a1224fe21cfdb0906e651f68fb55fa23..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 873 zcmV-v1D5=WP)>;2|d(FH_UeifFLZmk}^t@+@__su-L zQ!!25z1k#^_u3y-EG;4oq^KSD{1=9h2n1nhSllvSHvH-8c=uils8Xr+X5d8*)M|BK zUmucOBMb(E75et}b~c+0hr`?o`1i~MP16v?q$mo<@!D;aVqjoEVEFm9$dt|d)KZ}7 z$|9p1u6s9-Vj*bq8!-2Y5%aqAvz-F^mzW;-wT+zhD z1VDYs<#G!P3xPl&7K=6LkMg&*wRLuO>U27`FCO&EDK!l`3nCow;WWb(X@M1shQ}=3 zb5jqIj^z0Deu_#9GTE~{_O6TN>Uw$JEX~cjoL8*3+s|I8$4P`%!JQdjo|e|`Q7Q7p z~uQ>H-$?*@}Yi_qLzrE(nm$hfVEZYC*|Ns9Dp4LS`zc`cx`2_>H zlmLc9)f-)aX4QGRIEGZ*$~k^rsL4RY^`dil$box|)#7`(%0B6}nH5q9UMI2k(OK!0JS9_D!B*|wI%y-at=i)N2@U?97 zA4-;+p#OXe%ScwNr++q|Y+GQxIde9^gW$8Y#IFfwfUVR~Y>>Cvq~moRv` L`njxgN@xNA7Y!Z+ diff --git a/retroshare-gui/src/release/skin/Bliss/quiButton2.png b/retroshare-gui/src/release/skin/Bliss/quiButton2.png deleted file mode 100644 index f379e9431435ec318536e642aaa2d7019acb452d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 438 zcmeAS@N?(olHy`uVBq!ia0vp^;y}#9!3-q#J-v1cNU@|l`Z_W&tUqDS+Vv91mn?CO zC<)F_D=AMbN@Z|N$xljE@XSq2PYp^~vj0|yR7M@Jt&e*F3K=ik14%g)Yz`SRue|NqylS@Yz{lcc1iuCA`Tcke!a{CMNW zjq&mEOP4M^c<|th7cVYdy7cACmxzdnr%#`L|NcEDCZ@Nyck$xIixw@)&(9AH4ULP7 ztEi|54-YRXDG3V;i;azqii*m~$tf={ud1p7T5(Fl(+ub^{gNQRU?7(Sz!0_6;yX}l ziKmNWNX4y^6WPK}4h*diH|OnCbrlM_sWa`{|Nnc=+%Qd!I=}q0Tu+q9k5_O0C-1hH z?e}_)PNc{|6~X^`LZTvN%UzCt-=$f_+B$o^>HnNYgXDLr(@I$%OQ|{@ZntM&+?4+L r*Ji`}=8PXb=3j36>ecdt(|}>Wzq;#_lhbU0_A_|8`njxgN@xNA0UF|D diff --git a/retroshare-gui/src/release/skin/Bliss/sl.png b/retroshare-gui/src/release/skin/Bliss/sl.png deleted file mode 100644 index 851821b6a77cd1b803a66a58bac96507f2221437..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 764 zcmV4}jDM=m8<_Js_R|aVae;BxpBTJFyuj z**1yn-FWlUrOIk|J)W^Ye=`&RDe&R+3j+X#h*Tn#z!(>WOgj2uP0q?%y{^NO?hbp4 z&Vya%R?@@Avvc<2;uix0nGgTb4=L_S8|%vTO-$ZEZm=ceTx2!GJTqk*=E}7VDz!@C z>;NuX4RZsu4gA(74N$5!*xI401So3L=>$(deS7xwg#BGcPaYq$D3*dV21S#x7>nTw zA;f$p?9`qg9xEBYef`Q#o6Rl*bQ)aY@SCUpOt0N&vG&9DiB%yBxY@j%Q)dw4; zQ5vOD8l_Qs;1cbqw1*18>^XvSKAleOHQ@Qn7gv{yM6IaJ;`jCYcW>;8U2Bj^$(1CT zw%CLD#A=P!w9Up+L3T-)i0pK4w_24-nUG8Z!Dm`)(DcdBG}QKc2g9lsp?TX5v;oYV zT6AkUced>-4sE^g_~zlz&uG3lxJJVeg!VCOor@0m_LK_`GwdtJ&2e$q84wWPF0wgj zd^=cE+vlw(j{_nZmbZQ)xet4QZ_c;H4PxdTt%D2&`R3*@kpYFdO)U*VjtWcC?_F?d|&DY}qd9H>0000>+9>seay@q&Wvd#7TH`QPu00UDUl*8&Y5%1eDj?%4g+y|KGLYjU(!i5O(-ZkyK?kOX+Fq1F#^#DleS`aolf%=Y_<@aN;C@SJ+~vAaquU zz5nsqe2GtbLOM zc!9GQ&%u7bnCS<1`#9`2UB~7GbN2uA@`jEt(&~eD%hsr`ygvxRrIMJ=-3oy} z(3mg$(1qK`L!ffMrBBT!R+Q?j8M|!o%$$Y!9y89;03XG>QK7IDY=D;>xM_~_z zEb+_v47u<_H4oa{9-+UTp5x2UK4xr|WIA4DxD&R}Yy__3+Z*QCTxAkx<0ZcS=6i5X zi+^mC?kH?|uMownPwkn1z1{$w>D4U2s9iXD(fb;}T}S_&P1nVEb=& z-XxTw_EV6LD1^UT!(fJuybuyu;CDrA6Hy2R+7It=8zp&2o>L+`&jTfbdX21*kjxKT zeQP49t*{kQXbCeoT#&=`!BUi@2>}c6U~p`Wq^XGiEIUrty3yd)U}<{E44Ta)j^9%H zcA@B*n$}{mOcBKiM#C$7@%gjYb->OpuXRWc^C;}vQ{-~8L`lEYYzCFD5^LUUj4~9W zwDYJQ5PZN0fGLXiPCE87e6^uQBWScy zkRl9@yJ&KMrZP2KT1}us-;9?SM@s}bb)KeD>SFL0^Xz*aPQ}5&6-h<17GxpoW5Q=l z4Jf6-jXFrBAf(qLOYbo?U`JD?t+aEx+;vDbE-^J=x(}-mg;2;mALaXwX+t%MgY^(a zDZzB@A$+Eg+72PPF3o^~427r_!e>OuwwD=-j*L7PpptMMQ;kDPG`5#IMkefk1(e$^ z!(8r|j|U9yp5XZC5KYsYdh{`(w;8EQ2r`fHBEjS)La)=pVZXC|G2r&d_y_hPF|LSU RPu2hc002ovPDHLkV1j!f@H7Ab diff --git a/retroshare-gui/src/release/skin/Bliss/sr.png b/retroshare-gui/src/release/skin/Bliss/sr.png deleted file mode 100644 index 6689549b3843f8be45082ade41bccfa74ed319d6..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 394 zcmV;50d@X~P)6P5%Yfftbf4P3p?2SsWhnH%c|d6h%?vs- z)Q}}Z!Gegk+#h79u8<0>XfnBHa?iS8YHp9Ye`=-((qEU;1YgK>ZH&=9eGA3ehI8PF zea59HL*2Ww*xK7OBK{O3e%3`cy|*3000SaNLh0L08StP08StQ7JZrC00004XF*Lt006O%3;baP0005jNkl$Rf=|Xkp2U%;v_nXtACQStE=cF9V$pgL6mgSV)l=uwOcboxSqb#%k1_^f|2D z0h^nTX07{UMD0wxXm=^>9-ObQEJM_;#EPSn3(AtSt6S5uqIM=m=-F)lRcbs{zdM~| zlJ-oKI8i%=#27=#(N_IFrI1uM?Up3nrDk~W7-j&7qENormw;di?vL*Wyb9hdSTm^O zufmnd+KXNZE`ih*gfU32!&!o)1xzst!B#%0;iKR>o@8Pr9tii8Z|iG!d|j_TJhE`T zy}3pZBm@?xXEGU6EeuwRxmmqbxwLINYR8bc(|=+X=JSSWC8*^%_{1P`SV(hRkxSp- zUfn!V!KXSP(B4ZRkpP)oAVI}IMub}-fQCv3GO+^i#uc>X!atEm{ISvj1c5L{jR6GQ zAftpxxF@oS4XDGBB1Sf`vQD_ciT81M%Jxdo`+9z9vh5PfiZ!<}QpJosQnU28{Q(Rhf*n;A?5cec%&kzLpr~GY`*cwu68NWQN VbR3NSF~|S_002ovPDHLkV1jWd2XO!Z diff --git a/retroshare-gui/src/release/skin/Glassy/maxButton.png b/retroshare-gui/src/release/skin/Glassy/maxButton.png deleted file mode 100644 index 469d21e4014e3c2b6fe5401e2131733520e7b22b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 290 zcmeAS@N?(olHy`uVBq!ia0vp^;vmey1|%P7U0DF67>k44ofy`glX(f`u%tWsIx;Y9 z?C1WI$O_~uBzpw;GB8xBF)%c=FfjZA3N^f7U???UV0e|lz+g24Xjs9VU4b@03C;qK z$YKTtZXpn6ymYtj4^U8|#5JNMI6tkVJh3R1As{g`uSCz!HAJDzSkJ&vW}S*FP))k0 zi(`m~ck-YA|LvL2GMp%gO5AbK;d=8P2T`74oiiW)SMK~9a!`St&-n1dIHt;O9R{wb zIR~3`9NoB>j^AAI@Wsr0lZXw|+!r4-deqc9iHkY^rc*B$bM`^kFv;#{;T;(ZBA@aY a$uMZH&O0w@d<*Di1_n=8KbLh*2~7ZKkXvj3 diff --git a/retroshare-gui/src/release/skin/Glassy/minButton.png b/retroshare-gui/src/release/skin/Glassy/minButton.png deleted file mode 100644 index 40c6ba78cc865921ebb37790b945d8350e3d3230..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 272 zcmeAS@N?(olHy`uVBq!ia0vp^;vmey1|%P7U0DF67>k44ofy`glX(f`u%tWsIx;Y9 z?C1WI$O_~uBzpw;GB8xBF)%c=FfjZA3N^f7U???UV0e|lz+g24Xjs9VU4b@03C;qK z$YKTtZXpn6ymYtj4^U8|#5JNMI6tkVJh3R1As{g`uSCz!HAJDzSkJ&vW}S*FP)(?( zi(`m~ck-YA|LvL2GMp%gN}MIh!zUQEv+7F097k)ZXA#Z`CJ}DUtv`Z9EZ6*7y=vCP z7EaMBjkf1czx`JiYnCy}vT!SyD5JB$K}GO^u3bjdHU@^jb*F#*KfWOqXaR$#tDnm{ Hr-UW|hz?WK diff --git a/retroshare-gui/src/release/skin/Glassy/quiButton.png b/retroshare-gui/src/release/skin/Glassy/quiButton.png deleted file mode 100644 index da6390211efc6352f600574854915e3dd8f95127..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 395 zcmeAS@N?(olHy`uVBq!ia0vp^;vmey1|%P7U0DF67>k44ofy`glX(f`u%tWsIx;Y9 z?C1WI$O_~uBzpw;GB8xBF)%c=FfjZA3N^f7U???UV0e|lz+g24Xjs9VU4b@03C;qK z$YKTtzQZ8Qcszea3Q$m@#5JNMI6tkVJh3R1As{g`uSCz!HAJDzSkJ&vW}S*FP|XET z7sn6}@3~WZd5j}Ki9V$zr}}sZ}gqz#(bYyFe+Nn{1`6_P!Id>I(3)EF2VS{N990fib~Fff!FFfhDIU|_JC!N4G1FlSew4N!u! zz$3Dlfq`2Hgc&d0t@{HMlqhkHC<)F_D=AMbN@WO0%*-p%^K%VRC^ObGFqB!R;tEvr z-qXb~B*Oje>MPjuLGj*H@qLTAQcEve31ALF;TW$L@(1ONpFbELHprfC&v@Brw* Obp}sYKbLh*2~7aCVx;c? diff --git a/retroshare-gui/src/release/skin/Glassy/sr.png b/retroshare-gui/src/release/skin/Glassy/sr.png deleted file mode 100644 index f259a74c78218862e7df21bb077787c7b5cc96ab..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 154 zcmeAS@N?(olHy`uVBq!ia0vp^tUzqX!2~38Hn`mZQk(@Ik;M!Q+`=Ht$S`Y;1W?e& z)5S5Q;#TsMn?EKpa&9pAlkV_%F~^2K?x78u{io8C5)u?#ZMm7-e)2S*u48(|KJ)L3 zZ;3nFH~f9^%=p5!x~6~98NW5X=d=8Ej{VKJzC6$7OUe00pt%g5u6{1-oD!MNn{1`6_P!Id>I(3)EF2VS{N990fib~Fff!FFfhDIU|_JC!N4G1FlSew4N!u! zz$3Dlfq`2Hgc&d0t@{HMlqhkHC<)F_D=AMbN@WO0%*-p%^K%VRC^ObGFqB!R;tEuw z=jq}YV&R`G5?Arw{%`=hQn%b6`ByU>OFl0C?<{NFp;!B-enm3d##I0R{G~h$3%VG7 UyR5Md1?pt*boFyt=akR{09wsJ@&Et; diff --git a/retroshare-gui/src/release/skin/Green/maxButton.png b/retroshare-gui/src/release/skin/Green/maxButton.png deleted file mode 100644 index 73f1fc27d0fcb579368f31f47ccb0710db1397b1..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1002 zcmV^GrBXAoK*@|1i;`f}1Vv5sLBK#F3B(|im^R)p!CTadiI+qxD8Wco zCRB?$6K+wkyf7Jqmkee?!;E;T)Y2BF@K3DS`@wlykopkp(x4IIJ)-(@@+afy1J`hzsz z+Ni?G-^$~{XFl$!~bptjbX*mz5htAjP@4%|XV@CG_UP3R1h z#y=@C-SeFH>|;OYI3EK`&^1j-*wecKp7-^*7jVK8x`MU{Y21mn392!1PjlW2ANlw6 ztVb^8zku3Xb|dFbGLF5h!0iv`(fqLvu5cZ{YjI^-V?>kx6qy#c@ z1&dKNQ7poHCyTLnYFgDS>Uqw4;UhoiR&=F;ITCbrqZ!M)r=d9Qn= z6MoKdeioDmnuavU9;qPvQ-jn&EtLNlpnkIqT7NppD60DHGAM`BAg4Y1WRF$gT-^VD zY^bQ$Be_S7X0}o3US2yJC_Vj|w?6YM`$dbSiv()bU@>2WYSKjwmePE#%r~L)1?SuS Y4;?laGZC~q`Tzg`07*qoM6N<$f{7;9>;M1& diff --git a/retroshare-gui/src/release/skin/Green/minButton.png b/retroshare-gui/src/release/skin/Green/minButton.png deleted file mode 100644 index 1c9adaa6c1b2feaeae464a7e09cabfb3b3c8132d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 991 zcmV<510ei~P)r0by7%d3J%bdGw8j+VtwQQE4RG>ydeaHlb1Vzk1Ho6&T7pSGs1!`$Yk<$!Uvm2UX z+WJxyR+179E4!#`&dqn$A8~q~ckNZv>`Q~g`90@3=e$4I_AUpo?7x4w^l!N4tj57R zc__G%h#YIU$UL*YRBqA2lMjlqvr&OVoq4$0e+2hkm(Vk66Zsm=he_YjsKlv<#fz3N zC@r=bQDjfW&37l^9B+fuZO1cr8=ie|Cyf3or!TvvQJ+HLLmX1P48tfw%@sz@S zo>ugE7Xj(KzeB!4haQELn_DcEn%eeYTeBQj2CLBRZbql)20Fdh@py{h{|#SoW}Wx! zV?XCOA1angH(ifFS>IMTzSZNd+X{#GGTMCvzZLD%#3ArZI`2gv`OA8@AcOMrO3khN zkbWx?#|KK#GJXzC-)mu;szvj39h!w&v;^u1Atucq+&6hh8$XW|luN%A0rTyBVzGGB zT}>Gc=6mx@02bB^=eBbDk~;;^PW2D=BdQU0|6<(|DLpWci8 zLIL*A5dR3Gg2A&8+>1W)b8byn47f)s-PowdsxCP)UZ)^`bUX6h+xdm?PvlRKm;4$1 z$w=&$gL|aXEK4SI9kED!u0p1319Hc*kn7Dxu0TAKjl3U(pF!q1SI9<=Hw!uB%XAsU zoUTKTEX(HEQf^n>Q$XWXBH?X3)_+Wc(QSZnY6FbZ!~x8= zgRDmh*-JHI1~pK8h==O)N@&Is2#F%AzN~~|Bo1=gvrqO!3C=D0-w%ng^*TiMsu1~H zji|R;M7<{rljdUnJr8KaePpj1u?@PV-%_Dsc}*O`9;*@N)FAu?;guHQ{e)KRtf-7gLTG5vvl@O%IO N002ovPDHLkV1mL5(Zv7& diff --git a/retroshare-gui/src/release/skin/Green/quiButton.png b/retroshare-gui/src/release/skin/Green/quiButton.png deleted file mode 100644 index 6134015efdcae1e813b16d4444402b39945f6af5..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1019 zcmVr2~r6vkH=ikBF3*J>HwBAe00R#4V~m#)ygm=_c(Sc+PZgkEMrdx0&Duy(Mex=PE8 zmtnftUC=6>E`8InVyjds2HVJ{|I!Tif%0Tyq1sHYHyp#*$0*8jd6VdUOnv4^ z(5wL&^rJE~&sE~ovj%*<(ty^$5u6T3#4uK?*c*h`8ayI$oaY|*nIl2aG;XZYd%ASB<0@4HS=3p?bO-n#D9yx|pi} zc0)0r0y*6|C;LkY?rr@F5S-m zrJ`VYdkSK1suAPTAod^9T`giKNq04f;oU_yy35(C>o?s0ch7rKk`qAXNeB5V3$r6Qs9DOK3{(B`DIHihvM8Kopb~A=D5+ zq)7>(gd##{lF&j6C4>MkKF@oubIymo_uAbrvorVX{QeX7L|=>R)P++30Dw#T(F3ES zx$I~NonSxuR<++i98D}fMq2j(WxbacjuyvZ8hRQ4KzRx$(~j+Eec9oWksbgLEDQid zyaoUmM_Uo|0D#{u0ATSM0HFK<0O0e?#u};~9h~%hWZ?qa)E|fX9pzv17QZMavMR&$e&lK9xF0CO2uj4VMVq zaT&O-c*vwh_Vn~zR#Q`RK7IIHxl!tb%;2la)0z%9xcZC%GNrdKCpF*QX5K_gyxx-5 zJh3ElZamBhp?L!5b)T_0Xb@?jzI$CUV8wcEy#vIdfslXx#fQ>M#J~&|2Mc+&@GClD zd-4w|)WGn`H>1YtzkKcLhl$VRVw8J39-I&p6Z<&e zGUz#TbUsGBRfmLa;WD*5l-P`5RM_ znj<`q^FiDO`Jfb?{EH%=`|)iqzB(?-6EfG3S@_3=WX$YbVM*lm3XO~&^3qbm2(B|U zf|DLW6G_|=Zs%ftVciPNSbB$z0(M7vi{K(=-$*apfQa1iIIa*U#@yE3(0_`VntM+6 zdbn0?v^xrkUqUzh-s*3&xD?#91osuzI-1`8+5BEa zc<@~mr^_sZYje4pYFy(}_;UqW@4O?m9AGGjuFtD+bH;?PO}2%fZMh0d?U>(mUzP&9 zUlle$!j@zTZfr^QemubZ9?b1ZmixqDxloS1nDlEjvK>5>aH>XC7nrjmD8gnHeCGOF zF07+G1Oma4B}WHjrv<;Wg?`V3>|N%v+19yW+^=yI51S5>lOh0|Eau4PYf$tkkpz|M=d%Jf1PnH|Kz02%TY@;>Ky|6r!j>5%FMy}vzDSB7P|0gq6shPs zoLW&qDs%M-UjujjKUcN86k6Ie4jj|e6MXP+?wSi@BTf$9Vr+>mO*CD$zUu}te{j+E zYk|m)RKDI`dPs%QwpGb%`FyjN6U(Vf_d#H|FKA0cDwU@;f=AJeYI)a$@ZNB@-NlGw zQQ-ES5l=w)d+}~yt<1RS2zl9exGcNKwpLTBiNm`(tn!kM)T;hM>bCBl)5y1&_~uP* zPd9=!qy?8XN#r93$U3gdnlC4sGt1bK3UwVsFM8jVoPIMWQ$90Oqi-ce@i`&>91T^6 zdMumG3xmGfn|r?7VI_qNthNse#ocEd+7_qt?cG;(N>+<0JkKz7ZDj#LK_cl%p9F?d zzk0XmT9!Aw8eaWcAc-Ctz`#fEs_>{k^n;J-hH!&hDyj@mda{5#j}i$z*7)deD(NWQ z4t?p?5;M)u9K%#0g!t9(lXSB;yS!1(Y1v{@Xlh=oTZ$)4E@QiWH7%3pkM0!Ouht@# zP`Dm%q7>Vkj0AZIt%2u2+p83du=JuJXk<}ag3F#Pp|5cSQkcKmsI!Vx)F@PKw(u*L z-_lw1QB^nl_~B_siq^_&gK6fpG1mT=iF=mj9Tmy|HiNIfVE;}f6=@l~G9NtVXMc^V zR2R3Xum0=H@xPIH$ye)^gOK#g6(XMRM#Hyv;}`R-5TF@KGD~F<4AtP)vrx*0dPwCytdDnTE0%Shu%bB+)~8i&(a(+@kc`H{ zi?Hh_XOF2*9k-og4=271ev+~AacfVNk=;fEQMImylt@`{LqNZEK#-52alu)qbgXl( zS#w^0(SDY28VWoz%EsJ6qnTOfvruzUzAtCOuM$3~9!#Ou%>Kz8+7;gxi}j+g3X^JL z_E^s#X!jHOIQHLcLIVF-KR{^K_+^&h+QfPL6CS=aX!+QgH zGPrQ`?2c>}-+H@r>jfk*pJ!c*@?fRHFS>3thGs7hhnR_Al;JCvPCd7m+>U>l-0+ncxE#ft8xLRgDpHjFAVwg6esg6w*<>fqq3bER>)Nbr zYia+U-T@oTn+@dItEhO_(_ozT?a1{E(@H09U1T(8H)+nb8NO_$kVs}8sKnoNFV z_lFiqGjkiJSoNpaRt>+AIS{4SJkx1A>5!%a#YX$!spUQq%+T+`HQQA2 z<$$n;#}gqQFV0S&s}ww=eYbBRJ{b16t^=Qnit;NYlY4XY#9dumzxfS9$FNaOG~VE> zNrNf1wn1FSDdd@a1F^H{gDiqdVLU~}QW6(EhTdoQ8#|C(+@A3xx*hI(A)pSB6$aJ@ z`=q9qjIcnp{l$C`QG6fFXdEryJ`}Bj7ljIEbOI3u1XgwC%l~XIlMc5!dR2BLaPoip zHr(mSb4t;W4wqvj;8?9ek(L2)>v?y<2ch7GG=A~;L40&db9?Kyszpl8bp)yvvn98& z(eOd9M-*E1Y&`IkX7bO%fv-h0M|t?JvmEG?V-C0B!NTEvgTep!JEXEDno zqx?SUiuk@Hf&-}Z)w+=Z!362N`Vq)ui>CU-u_osEMbD{X;_lBm;ui5dk-B`I zxZi~S6myXMSjr=U$J=`7Zqw-A%NFzL3;tMw_v(7k|rC`fj8G9l~QohVsgoF4{C?;kHV zEz5n#DL$v*Os87B0lV|>7kqjx#w(GV<<#x$M-{WguLil92{c=nDvgYp_*LbBe!Hqo z4i%eTfd9E)f{$zHbh`0wa?E_BWbqi*VU~^P4FkIFTLN8u*6v|fN27cXGYg38`30Nb zJM*RFGtlPmo#k3 z{K<}f)W_2;p4{s9^`m6z^iZWqI_Z(^^dR9Rcu;}L8k{OoNWPm$YRH;2Q*P*u!c!>y zDo;`opair1>=cwpfo7&4aRtu~#bm=OU&H+9-ylzKIsW`7OSLYRykX#~!z=lAy7X(= zTfd+?t6tH>(ev^oX-dZPb;J4+O_;ZF%x&*&?>H1A_;$CVruT4PO0n#h-KUwpzgKjz z4j#f)s_(S}P^u}G@IaxeeOeH41y0D{JMb2A3VMY(wdtB-1N>!Aqr)a4J8>(~RNHnx zo>|u35dMErk$!U|5}O`*|BR=-Yr2{udC1f98dJJPRcx|XA=-l)S<)5u2|gy>NZ4Wz z2|<;FL(Ty`O||wCNjis;{z%r$GecL}d*X=&=GTXNJ|Lvstjc7`gtXS-zO&&TDjvO; za)vtPeAk|x+VJ*q8ECy1^z&l{?p;y3#I(Y9lM1OeQrCdk1SV-mXSasWM5ib_gp`lwgQ08?l{Vq&3%-L7~f9wHf0BPa_Q(WjmG)gLb@*nk8uJwPo)Z zDtJS{CUyiLjkxWx{V7?j=+C6W)D>hLQ1}TcSL592p3b~=ChJ(G%Tt#FT#zd6{LFES zFCn(;c^*y=>rU5x9-OX??{yp~1vwefQi3k`uDkyKSAD}w{EO4j_B~MIQC44q&i|| z+dVH#cjY`3Q4J1tgI9{A%kn`wRfEUfxa(MhH=D`mwGd$4{ncVQwHBLyR;m`@=g^&n zvJvJzuaW2B?8kk48}E&~&Z_Jy&8U9ByD$%UF$_h5`>otVzy&o|xisCI=~~@n0#b`M z>LO%%FxScqlE6|-dOsq>)m`tOes>XBj<8-cL&A1wqvrI4Z`7p(nR%-vnR%?Bz-B{6 z?ShBX09VZJ`K1P3Mn6ZU?=_x|q{G1zQC|PC*MA~Lhu+7K%=m$fB_OFRwa|vm);0?% zBzU<%p#rO(Wlm*t&+4FO9?%T*dZtm&^=?}wuhvD32D1;vYo<&igkj-=2 z4l-J;8(b5ZoTp(o5)0H57ADrEIR_RNO%{Cd!@dkl8}|L*O9GootOA?(7F9rp?ELRS zbJF2nmmlncC+Pn$&jH#?@C%1u6d@;?ASoWOB4DzID^|}aB1j-8fh{nbZfIH^4B0|) z*~)a;lPH@MS+jxWG;^V9pz!`HX!0No)&g^ISd}Lj#SmT~vY{{jWV(fsN9~7UZ>qv+ z*8cRKZ|Vu|IU3bL%a|XZKYv!u2i^pOQ6NV`L9PKx%Xz*pPcAPv;&FU}Q((SP7wmkv zs==}%&C+$J!g89kl|y+bA=yE7!gsiB5=h>CY@uvpi_|xJ@dpYnQ6hmmgE)5qpLLLS#1K#r+x=lskJyP@C4xME8iwVp}f2d89D zyRDL$83)k_>l}TE&0BplX8Oe@Bu50Kt}Hk+ieqL`!D4$v+N_}y?R_&;JwWB(@Q}o- z1^!CVT&Wfh^Ws_Sx|=L~U2i8iDd`YTF{Kjyy7$?`Af+QZLW5eu`PnxsTeoqqR~15# zEKSnNJpK=}r;I~M6TvCl@4-Kemc2#RYA-mf*h6qPJZW~6!q}$$ThLACA2BC+z~c$8 zgm}~*&{>}Ui9KU%ZhqHORLnlp*m39KM%u~#I3aO&39RxYKbT&GPkGu<-$DAUUee@v z??PBm@C6&wPA*655{hhCe zl7B9 zW>$a6LMtUkbe>dtvFR7ppoPwN#-SrI?_^Ze)u=beJa`(^9HO|?XO{MqtX`JWqJ%|y zB^H<3V)bU0yC?}-pZha}X=@t+wNj;1?KChZV`$?a_bI#4)>nB`J4s3U5ee%oB5TJK z*7CWDk=WN99dU&6>Bm8A0p+SOICFt+xI^2fQuMMx{@j>WQLa7GKQXb#f2GI}P*2J_$g2AmGU9>cY!j$&e}OE6K*2Rq>=`Y7OoBd;VQDX@mYj@AB zDL01i8rivm{y2YuEQg((r5DeCkEuB>Q}Va0{e?}-8c00>O)wE7ts52)4!<4W@6QpY zBB>r%Ln;nhXG*1ct7{oJQpfN`vJCAN4IL!!L*JK#Zn5P2nmX9~{d8w#;wA!ovAa{? zQC(2o`;K>r3=#40_!i|4X8GN-23HclLz!MskS&K!;#MShhAJSw@l&Au=QVYC(8lPc z4Gs zdrIO5dMz&$VX|vd#x8Ewl|cp823%6H)eCR&7`-;j7hl&x|3X@DNBIirqMxHar|@FP zwBQ(vTe4?+Q+i{2QxO6xklsl=DiheYP5=IK(|p@Org*2u!$8B-l-F;jhEpwg^G$}` zY0s<8F^!$>MTe?kS(T6Sg-dJupPP>%nvM-t0(n^21>h3}zrjz0HdeNGz7r>AT5@G< z1x(vhl%Mb{K5ml=vP8}o<&Zc?y%I0I1{88CTLFc3Tm>ljYIfYiguUzX| x6m$5c;KxdaGd`ilC-;80P4{~Fedq3(wn>%-v(DdmX#_Nu!PC{xWt~$(69CKYGCcqQ diff --git a/retroshare-gui/src/release/skin/Night Vision/maxButton.png b/retroshare-gui/src/release/skin/Night Vision/maxButton.png deleted file mode 100644 index cbb27c3cbbafb11db9bb631394ae4f5a2150beb2..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3120 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 KMNUMnLSTXtP}ODt diff --git a/retroshare-gui/src/release/skin/Night Vision/minButton.png b/retroshare-gui/src/release/skin/Night Vision/minButton.png deleted file mode 100644 index 5892a982cab8bc077a56fe4e243d27ff4cf9e424..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3051 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 diff --git a/retroshare-gui/src/release/skin/Night Vision/sr.png b/retroshare-gui/src/release/skin/Night Vision/sr.png deleted file mode 100644 index 0d0f296ec712b0906ad4d371c30bb814755c325c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 262 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 KMNUMnLSTXtP}ODt diff --git a/retroshare-gui/src/release/skin/Vista/maxButton1.png b/retroshare-gui/src/release/skin/Vista/maxButton1.png deleted file mode 100644 index 1bed27a4958f72b8ed9bd08188110e34b238bda5..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 690 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 M07*qoM6N<$g0IUXwEzGB diff --git a/retroshare-gui/src/release/skin/Vista/minButton2.png b/retroshare-gui/src/release/skin/Vista/minButton2.png deleted file mode 100644 index b52bdb299c01937de75b08f5f4c7e03c53355d99..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 993 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 Y7cQ+qb+TK_OaK4?07*qoM6N<$f(~=C>;M1& diff --git a/retroshare-gui/src/release/skin/Vista/quiButton2.png b/retroshare-gui/src/release/skin/Vista/quiButton2.png deleted file mode 100644 index 3e79d9f0860d3b2525db673fcb76baf5a3cb2794..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1443 zcmV;U1zh@xP)RG1u#iO zK~zY`)t1?dT}2Rwzv}LD?wuu>nK&jPA+8Sr;}Vr9?jQ+nplC3NAQJFZeDziT4iQ}N zLD47(@ge%4377Q+HB`L}ED6#{UbpahUxt9aXYSiydFR+~{IyV16a_o3+`xTz zZUciuUmQn(uTGw&t}8Z=ci4UX7Px9dc3=gxS%w~hR~rCpjcHBLst>(>0v1~i+5)y~ zKNQ{IIr7_S_P(%}cAUS^@a5spG3UAK(fa|olfgK)Z$H;>o`kA~rcTgpgja)ZO#;+4 z+B5{MDp;IP$0sXbS4KOy4DBI$Zk!(DtykXW>F4$UFf|#Ndf;wW8wd7%%+B>|pzcG} zhq@j_xyit7MAg8Cpq+=hrfC{N?DuIF76{9L-B2pX0NOk70zT#K^rkT$5n=z^AMwzh z2l=n@&B3qPdBp@=RzSZ8y&hCmP7VDxunnbyX#(z5Xk8OxzehDUPh$|g;6)H8`J#~> zU;yq@{!$dsDVbQ`Vb?|D$blo=w)3`s!Jhu{FK*b-fzbf-voJpoi;K{&mZ!zig;UUU zS207)Xv9-iJ({XdI6rfQUz|f!@gfus3MY86v=-=yQ3`}Mr(0#{mM}VkuDODXlUrAf z?%b(Ax%~Y1aP9aS@;?xg--D9GPI(laH?oeD&Qo^TT_8uyxVH+@%!}ZfK%X zt5QXy(ga;AM1u-YGc0@N5UWh=Dbm?*~&oIRek3PocE7t?*D1ZF)Fx|0nuGz6|2{?4&s$CE8<-32g zWAt45kFrST-XvHt!)HYk10RiOAZBP$Vr7ZAK=5UkFun$d5}e>f(us@UbKW`+B7*o_ z0W`KA!I8&coBkYbJRiUZ494Nf}Fo~ zG@OEW9_fzK*|3EZ^F40behZ=7DcQJv2c85hOI2;Sk6?MlbGaF6J#4F=_k+^C)cdpz z&MH-H$ebA+ZJQoTGT{RkD&_d;bG*Orjozkpmpv7JzckCMZ@iWnl5{x{oEyyI99~>{ z=TdQL_tT!k$>3S?KIeyiW$<>P*YS5#jvQT xC5Ox+&N;TMn`HY_YP)Px#1ZP1_K>z@;j|==^1poj5AY({UO#lFTCIA3{ga82g0001h=l}q9FaQARU;qF* zm;eA5aGbhPJOBUy32;bRa{vGf5dZ)S5dnW>Uy%R+02p*dSaefwW^{L9a%BKeVQFr3 zE>1;MAa*k@FfkmiBt-xK0s%=xK~y+Tb(Bp~!axv(y;Xu6(JG1MLEO9dMxMhe7a$7$ zl|lef3k4yNpGiQg?IzusnE>0bUcY(srjxz>qf=P@{y}@VfV1-p*mDn0N}%d(0job~ zz0G-~iX%3_5ffC50 zaAztKRFuFHK@qG5ab|&Ih*Ar95Gn!^3`<@l25_*#d0bKi(GqU^JVMcfFe`&p1L`9P zRas$x4F!Q&WO^Kw03B;71T=dy{raRZKt8eoZv1IJLhC?^0=Rsvp{Uu4%@J(O_8`+R zg@(_;)=5p^R?!qeT@-Ttx&(9CbPM>=D;2Cw8Bj0_&Sf}@wOp?m!VN%gy8jEb{&&ONd}z{qcH;hCx50D3>K*jdL#Kc;z*33 z|HXh51P0&y$E~npI1cq)5>&iTA{%^8V+|DkVMeor0eaAnZ5$|FGJ(l_H}K$Rq2T&y iq&+?+F`Y^+tSw?HOH#=`BE~*O zsgU(+$vTpyY*S*a`Oojo|Hb*7^E~Ix=Q`JY?$3SS*K^;}!UPEyhXVkBG`)1e8UP>+ z_VW>LPIe8dY@KJ{Ai>rqhCoG+OJuU;sb}{_ldsU3Y!R-V_Zn#)a4f+zbhG z3%UVVy4~^*QL!+#J$hSR1*0Zeal#k?jvbg@Ft81GS;;lalpJyR^zm#0YMJ*NhvBk7 zt2-fw{NetU9L9;e6nq;AG#z%6z!8E*tKGo`3K3Q-yQEVnmgcK}aiB>y?Yh(2$fd%C zOYf9hZv<~2v_`c$xlT3=VJ8RG#lMvYw+v3Im;YS-RkAa5aG<{$ptCTH{D-Wi;Ss$5 zU&{UnA0_(f{bdTRK9$~oAGM2zx3�ExHVgkHJ&;c{lI4Y~ESh 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 r|JO~o{mD;z{ptSAo02+wLCg%gTe~DWM4fs#K3` diff --git a/retroshare-gui/src/release/skin/VistaAlpha/bg.png b/retroshare-gui/src/release/skin/VistaAlpha/bg.png deleted file mode 100644 index f7ead614a1e34d6bca5b569a23a83b15eba97269..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 19839 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 nd9<{&Fmd90E-?onoCT&W32_i zT1(e;04IJ=MINGYY|oO8SH@9$%B&is#%Qp&fFkB^URHk+LatyU|}&(FUHN-2?Z zCdP=h7Gq44aI@KPcXziF(0aY*?Cgx3^Gvo<3aW~zD&sgZ48sgaME+Qw7$Z67R=k3# zDiUKPr9_NzW`M7fuGj0W#ixviVPG6ba?YqK0IEt#=_in?G7Q5{Ek)?Mj%t$k_xD!l z;^JcFwAVudlx~K#dSWlf9JE zfQ>OooqF#*)>=Xc^nFhV0f3a!&aSI+*9~EeX-uUu@!sQ{W3gBeLLh{|!NCDnS64fM z93CDv6{=j-$<8?>gn)>!SS;|~Hz4ml$H&KoOf|4MD4bp^=fjSWt#F3BSBRF#4EBFkGLnlrJ zLBXGyVnPTa(a<_D#t<>;+^;2*Z-p=!R#HCSsg z=J2GVs?=JkRoUD+!G%{}XK(Ms5tmt$83PhiVa$^wZ$M<4=%-8H@$TDi(KS3)EmoBe zKK_j7_TC__okfM5AZL&i3*!h*pcL>0N&|5Wk1YbQF|))F3G3e$3#2p&l?*bZ#4>^_ zAZxThRXrlv|K&E9E`QH_KBMnvhzL1nhGE5vFI-@Is{^1^Wyy3WDM1X7>m(*)46Ft) z7NnV+r3$51N(E=(*BdvPJ$s(#&u{Yt(;xx3x*xc8>o(h4PZQHL+$usy5aWcJCQ-R^ z{U(dgf1nycTA^t=y2i78up%YJwFZOX`p|O#oC0RR3b;+nj+e%ek`KQg2{AGb z10f~SIFNHe?kxuP|2UwiqisFX2b!*BmI^6Fy0)d(LjLg^Qre}SISm_77ob01L(gsk zkWylq3j22#q}4bHg-9Ala!!af4r{;|gA@=A&hcJo+LpfW>AU{n){O(hFc3rF#@z>m zlTYGj9!(h+3$7G$DHN+n<2|#sp|mZ2qlbBenf2V?yU3@@Ke47_tYD1bsvyZ?GHA7w z+)~v69d&Dq;p|D8zFF^drQ|woZ#IakqFSL=v=*opYMGWl1fZbVq1mFrQmn-oP*unZ zxnfE|t%sb^a>!9pt!SP2rENU(zN54aZq{Mu9lFty&z$4_{2aB1(oJdcXc@p|Xad*( zb_wkQYyr~bsMbnJAYJRZxVuB?8#vZcjv1C4aBB_+mZL~X>-;**i^J{(8i8gGehaz; z$CsYd3s3i86SEp2L`1^^cjp?mYp4rB?=@&AEL!1?w+!A9oh3O#vIbp8eN{jeQN?Ga zDU~Ky`dBD2b7IVNW5SFP6Efzhm)`tH`{S5KFpb4_9&H8nLiHBJP{mT6Mb{6KnKUp8 qt|%rKYyn#o8w$h>>t17`=E~nFplf=Z2eR`30000N2bPDNB8 zb~7$8F&wTWMF0Q`bxA})RA@u(T4_*}R~DW5GgULGshLV;GRBo4Mh#*#YLtis0f}hT zfEX7BjV3OrQ3;DlM4hOKCMpJS*n_Oi+UyMtBKz7b&A#uO>=@hh<^DJ?Ff8-}hdBP4Pznf0&Ysjiv%qVj`+G71=yDdZscz6ZwBx->Ee++G>Tz zk01Z85E&VmTcN1)4#LWM5n0}c$jSjkRSqJib{KKBcOa|(0g3gakT;AXsqrq73G%0q zMEyK2quAJ*5#kLYs%lW^uwHKKi0V|(fB#=oW2Cob*VGv4zPA$vl%9WKHv$zskd)j; zh_Vmi6`cMcqHBh!9Cr{?_XA?6jImUv7(y(SO!U!MbnOTttA`Oz@!@3y2rcasI;@w` zIHW4w3eyje(=-UL+&1{+wZk{B6F11zzvwoCOZpK~Hi$4X4X+$RMAfhwBcctjWDJRM ziE;peC4GX&eAZ#To3#TfqopPmNUIxwOL{Y|XEwtvs}&wOZSdm2f^H%av4{l7G@xWa zh0;O70QE8Y#keoU`Q&%OJHJ!#S?792Gh~&$DkE(pGsvrM<5E&BzLnSEN=hS~Qk!rs zy%jE5ZTL@42Rz8sGrt?2Wb9SY1Fym!crxhTlf>O<{5r)sQ@nF}i{M{LX%Ko*$}W}B zpS6u(7plNNj)Y*^iBQb2jldj-XlR{^hvC6X*!sbNNx|sQB`i3bM7%h`pJ5x0X~#mb z*C$79w8#jyp+$K4lMuXeJRGy^qVVd;7-$iRO(uJBtkzd4&^jX%{8@HVymBlY`^Js_ zqGJq)uo6r^9)a1PN}=fx1I<$jg2d#erlv_j7&+a-yo<@0>zF_~(U@%`#mByRs*L`+ z*aVJIN@!9hS~R$jOctC=#zLobVN_dNJ1KDNLiZeKJEdX%IXUUXL(4uI)_w&lqZgNN z!g*;47CRSShW<3V98drPpIgP7`$Uo1k6Pgx5<5)bc&| z^Z4?l8oVW~z}tZ(SmmBiI+;SxKCE12WM=P-bM7HH8(RxA4+V@p6)^NK$J)pm7$i4f zHSGu8f_AJ_cHqsbE-b0-!W(tnqUC$;=kd2GZcTDMjHK0A>tBYo?h3qfH3z4oYkqyz z(ptL>4o<%CNGwK3;~@OnN8sIi7cN5&aAEXE=so-qT4Q6F{&);8{`?3pJb8pa5niCr zFH+x(v7a!HV)X7l#D(GeaJ@YWPtx$OBdvIuz+c0v!KpTIFAgga{dpuQibc977gj_p)) zS%bC8S^Kg27dZ!WN99vSE%dpAaGNlo7G?2!PhnJT%6y&-$Br8{{FV_575+&02~g5! z&a9Tuq&6GRiUrw>4Y=id=CVN-p^d->HH0dHlB!fR2ISvYXT(C8cL_AzyoY4?Gf<)q zW+Dr)7z=Yo57g}lwY}=ea0R$rT$NIuIBDe4&2SAA;oNaFwLv8y^|YdMDvX zXf?LUM)7{s05*hlV_iTCjC~taMqgzQV(z69%(_VLc23op@7e&J?>n*mTo~$Fc)2Hc z)wT3t``JJ&4(P@r&t}a3t_GTy%b@W!y>9XKb@mWm`<6_;DaZV4wOHuZ44r@;Sf06o z(Yw4Fle_NSAA{v7Pv}JSVv%1v7GAH%Yga4i&9zizbUAMrI!+Z>aHSH9UF-3NcRQAb z^~3V)4Rmz!R-D|`)lHn!o>-DFgr%X~(D9`AzVE7_O<4&em;52Dx?YQ=F11+h)q=Nz zd!QRX0t@E^cm&HJOUlB{v_jLq5Rct?2 z1hiwhM+26TnK1gkpbs1U=;e=0)&z9HAbJpnX%Da=r3dD*<=7Ul#P*ab?98l(WqvcP z3R|(Ouo)lZ)?;gWHO!OCVU|#eEeYi?$?SnX?b5aMZ0k$=py$^HeKHe9-g&(+^=*b8 zrK;!Ofp?_+Fi5=z)5La|hbv$akq3*ILRcge!$Mw)ZG^2Ur7)Kl!%U`tS!@B!rFqyA zrGUw;cC0CQ2!oUn=tuNmwJ%NHy-xjj->kx?Ndqts?SW}zKTMNGVVd^{>**X>M;pb6 zHuG9KM)YYDucqZ<=n__`TRqx4@6aY&OB>UWj*)ehPhgt!04B0wtfRFuxzVaJI(Xh= z>@xkVJfAUuFDoA73?1F4=o$Eo#E+Ah1wo&%oUmAph19;LhBmcJ32zbB5Vp`6b%IRo zNXMb#5kAkmr!rb#`k|YhN8H2H!I?NuW%)9*8fO#@_`IS8C+a$|p`{axI=b;{&uvWa z>lJvZzYl-!@5SHvb59SZcXmOewF9p=w85~d8AprjVV_-v&r+3ej4S;054U@qWu9;D z|61~@nYBd2oUro~iN=S=C36ngNM>2vN@jjyCz)a6AbG{^q`*JzRhUMfr`y;|W*(&& z>rW-K_n(kx>^UaU*l|QM$LyeF_In>m=B(Q-nYzDjiP}BCo>$;`1)jMAn>TO982z;W zJs~E!Y11Y&HZ~$RHy8Q&`6wtTKw)7aii?X;Qc{AlvND14@^XQSii!ysA1^H}74ghd zC=^16_3G->UlSWQZk!sU_3PJ9jgg6oiAXO!JslYt8OX}Y5@pQG%M_M4_$`=`MZVeq6_JTo&> z@R-j!tj7}*4}*b$fmrPL_;|=y#WE?zO#`ryta~#LB0rOdh z^@@s$R7R^;uNF^Bcz8G>BO?(N6@{3X7{tZJiNK_!BqS#%3jqd;-MV$_7twKHj^lWq zF!QBSsnFwc3L{NTO?Z2IWBc~)u(Y&L&D(6lP8k`#~wX;6bBC;6nxg1U^I8`T=@9- z2$S8rcZ(pN6_c3U(9kd`aIB4u4UQcR z0y{f9VN_jRJt=VP7hik6d|1?&XXN1E07pm1U&=R` zbz=U73l{{>-rip5u%5fSyUIvcR~KPnVK{Z_lt}&L$&)y9<_s=gyojq;ufoN}1#WI` z@bvVAmzS4#aJbam@;&$SxU;jfh-V)2S%>vFRv7VGa8Ph?un6K=am%&k*|4CmuP*`u z0uU4wB;q6ziD>zr`+1z>#toT&?%X+1O0L!~Uoo5&5Aq&*`qbvrnm04=o2NG+@0Hlt zSg~gk5)#Db6%#G5B~gHZ}&Ihdj1n z!v>g|noelBpT{}Q(9lrun9n*ZR;<9XWy_}Me;KH5{{^=J%_C(DHRAvP002ovPDHLk FV1ifv&SwAs diff --git a/retroshare-gui/src/release/skin/VistaAlpha/minButton1.png b/retroshare-gui/src/release/skin/VistaAlpha/minButton1.png deleted file mode 100644 index 79207e5dfb24af6b64603d461799dab7ba2d13b0..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 678 zcmV;X0$KfuP)SB*O2<)Xxeii}z!_3dr%9S1BpM3X;2jS| zzOi;epOhveSzfPp{qsD(8A>T(xm@aMwZb{W1AwYxyWQgL?G4NfA_5V?IhSVuAfnN1 zky6UDszOzfQp)SLZNbA2&lwB=B64<+w~Ryt-{0RLA}}+Ya}W_QGgLK8W-+u)5)t%$j~HX#&^ZTY1~WrM@&TCnzxQJxgV=M7aSS>f4%rNrjST}?m?4JQ z7(i7=ndOXPj1UogeSM8KHwlO9p@ilzJM2&{5y|f|XuscMyNLpfA6OXZwH*L8S$dO8Voe}9k3WP+5^AF2IN3d_Vf z2j?8TKb~W=*_>?S5W>i*-g^+y5yZ?0A)qWv5D`KM@ZO`UD%c&K8g*Uca5!YA8q5Pg zQ50Zi)O8J2MF;^^RiP*fTwY${@$vB_$ZR%4(=^#Q=Hd*xxVS)36lmKPpP!#7iUMU> zqONPSZHvWXktO|Iv^GQpF-G)#KXR&b?x+v|Twh<~_4O5t#R9wC4k7~Q9IC29RaF^c zj{FU>>JK3ti}T;z+J9wPf~>M{Z*TSP?haR1SD4S|qwcM$cz=IKjPXx<85T1U!F!MC zbefCaGNobXet3A$mzNiOe0<~#3^ug9^*Nh=7prAx9VewU2Awm000@PP(@EJqr2qf` M07*qoM6N<$g0IUXwEzGB diff --git a/retroshare-gui/src/release/skin/VistaAlpha/minButton2.png b/retroshare-gui/src/release/skin/VistaAlpha/minButton2.png deleted file mode 100644 index b52bdb299c01937de75b08f5f4c7e03c53355d99..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 993 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 R-+blZX{hKbS1VeD{SRPk_fh}= diff --git a/retroshare-gui/src/release/skin/VistaAlpha/quiButton1.png b/retroshare-gui/src/release/skin/VistaAlpha/quiButton1.png deleted file mode 100644 index 008b25e2e7c97aca22b7d903e38282f54766ce4b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 950 zcmV;n14;aeP)(BCwEKuoHwdi;yavH((K1u=N&H z5c>!=f)Er-ldvSav$LnjnQ=0^dx)nxXJFWwZ~mTn=bLYqTwGkFmzS6L*VD<#32tw1 z31y7o?d=W2;Sc~o2$7xCa;a3x)c-bd&Sg1G(?XjlSF2UoPDNvqB)OoXEC%RpKLO{Q zXJGVlo-Ij|Z(vc0<9Gom4?3^y{{9|=!9dmUevfzWk05>-`vQMkkLYk&{etyo_4-XHQQdQpwV@!GgWsHGyj@fKh=(~Ae z(Wh3cq19?32m$~=5Crf%4?z&fMLf?#tyYtwsGzD3t92Eaa}LJX95{|+#Bq%2bXusU z>Z>~N{{B9aB!TC7==b{ofPTL(VcYFCc6N5qY&NARI*d5>BGscPS_I~tV>+GYDw*dN zs>=xfOp*lcb{kh$SJHlVc82ZkZ8RDUgkhNL3PmoWD!%~y^74Y=aEOP8hXprKmCVZ` z%n9(Xudm$5@cH?Pr>Ca{5H(t;KC5Rn)QPZL(jg7QSWsEmD5VS8Fbo)m0YV7I<1xZ8 zM6cJwY&Mg**Xtn+LyX5`5JKb_(=;=4iM3Qwgq>0!Gud$* zxUP$Gxh!p?(FnfpLtNfYr-O}+4RkskY4d#_qtQr?DVNJwSy_SOIIwM7&a18?V1;nv z)TwEjux%Tz>&j!$W3lSfy6;vh75Kg{eXUZdU~6j&l+ujdb=|^8L65)UO9+AEI516f z4lIsiZEY9Xza?xJ3=XD(a4UeDNd7#%b(#0j-mS69Ckrj$yB_1LRM3swEU z{Q=VBt%%oZJxx;>h5^g6P_0(+@$rF!gM&G+ZQIz~+(fh4%*0$BFz>nk>CaEme}nEO z;zGZ^zT*1&8jp{U1OVv!`#VlgPYWN0qBxufzf8(|j#Z`AO|7r5V{dOy!U6zMJNysn Y7cQ+qb+TK_OaK4?07*qoM6N<$f(~=C>;M1& diff --git a/retroshare-gui/src/release/skin/VistaAlpha/quiButton2.png b/retroshare-gui/src/release/skin/VistaAlpha/quiButton2.png deleted file mode 100644 index 3e79d9f0860d3b2525db673fcb76baf5a3cb2794..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1443 zcmV;U1zh@xP)RG1u#iO zK~zY`)t1?dT}2Rwzv}LD?wuu>nK&jPA+8Sr;}Vr9?jQ+nplC3NAQJFZeDziT4iQ}N zLD47(@ge%4377Q+HB`L}ED6#{UbpahUxt9aXYSiydFR+~{IyV16a_o3+`xTz zZUciuUmQn(uTGw&t}8Z=ci4UX7Px9dc3=gxS%w~hR~rCpjcHBLst>(>0v1~i+5)y~ zKNQ{IIr7_S_P(%}cAUS^@a5spG3UAK(fa|olfgK)Z$H;>o`kA~rcTgpgja)ZO#;+4 z+B5{MDp;IP$0sXbS4KOy4DBI$Zk!(DtykXW>F4$UFf|#Ndf;wW8wd7%%+B>|pzcG} zhq@j_xyit7MAg8Cpq+=hrfC{N?DuIF76{9L-B2pX0NOk70zT#K^rkT$5n=z^AMwzh z2l=n@&B3qPdBp@=RzSZ8y&hCmP7VDxunnbyX#(z5Xk8OxzehDUPh$|g;6)H8`J#~> zU;yq@{!$dsDVbQ`Vb?|D$blo=w)3`s!Jhu{FK*b-fzbf-voJpoi;K{&mZ!zig;UUU zS207)Xv9-iJ({XdI6rfQUz|f!@gfus3MY86v=-=yQ3`}Mr(0#{mM}VkuDODXlUrAf z?%b(Ax%~Y1aP9aS@;?xg--D9GPI(laH?oeD&Qo^TT_8uyxVH+@%!}ZfK%X zt5QXy(ga;AM1u-YGc0@N5UWh=Dbm?*~&oIRek3PocE7t?*D1ZF)Fx|0nuGz6|2{?4&s$CE8<-32g zWAt45kFrST-XvHt!)HYk10RiOAZBP$Vr7ZAK=5UkFun$d5}e>f(us@UbKW`+B7*o_ z0W`KA!I8&coBkYbJRiUZ494Nf}Fo~ zG@OEW9_fzK*|3EZ^F40behZ=7DcQJv2c85hOI2;Sk6?MlbGaF6J#4F=_k+^C)cdpz z&MH-H$ebA+ZJQoTGT{RkD&_d;bG*Orjozkpmpv7JzckCMZ@iWnl5{x{oEyyI99~>{ z=TdQL_tT!k$>3S?KIeyiW$<>P*YS5#jvQT xC5Ox+&N;TMn`HYg`n0?NH0?zz;DMrB54i; zk*JFw%;zhw<$*=d+;B;5e6}(-KUJ-Owx*_M!^2oYvXROTM(bMu~*!oAF|2md*p1hi8cFR42$gZZ@?zFuYU z#GfeBjB|*p8(|k!+Z@u}G}_v;$v)-Hb8sI#fl5U3`n{E?k%}JI9{dxZTS2@zDyPTF z&qHjWs(>q!-&&#J&TmuR)RhgeaMBaaX*1Q@bl`?l{rV(b^t!DaGISsHGT=;IGo6*TOz!dN=cNg`2_Z zDkB*m^oFJ%{4T@nw;8JAn4C9<*olrG>H*e#uOE&P4G^?WdTqBLe$zPi3N_fyZfbG3 zzX^zp=gPNV3DSW^Oa&qehMs~ejB2?leqWS*Rsr0qz+C~SFac=I3}G>vSPskA9!ubQ zfL5u49a8AoDCai*s=;g0U86f)-s9#@Cux~7`sVK+-ZquI&usb4!vmb_-+0n9_#_k7&k++d5IgI@lcx!qq9L zak<0J*2HN7=&2Y<$>^u;Ww)hCRxUv;ne;l@oTMR}P13^ypHlS4Qa}~$lph7pcDYx) zlpzww!H*4*9tZ_HK_8u1bTydkV1)O`7!(ixZAmE58dVC`l6(%QvF`vv5;;&#gVj!K+fOPdkpyzzg@osgxX_Ae=t*AjQtvHB!FK<@lhdXE z#v+kmRBXiu!uHq~2)wGk{>%hSMV5E%Xf?DUd2{wc(7e3FN)$+m2@t`U{ZnUaZ1?<^Bk1|UBe@#NL?zO3g`yVj2@4W}dX1$}}S zjQaUH#7^x@{{#UIs{;~k0KSn{_x}hsw%@9p54m+GO-hvCfcN!@tqt#a&ovpexuN@I z9o`yHXC%?Wa=qOtgOO|{k18DlFASgtRMSs+z1}Mx23AQP*NcTU8~L9<{01&GxE`);G*H+gSD1I$w0l@x5^a%@vD@k zg+m$9U1wv-!)Dc*mQ}{@$akCkK{4TNjG}*OYNw(=9EN`=;y?HhwgqJBz~2KXGCW4u I5|(o0f8M}!F#rGn diff --git a/retroshare-gui/src/release/skin/VistaAlpha/so.png b/retroshare-gui/src/release/skin/VistaAlpha/so.png deleted file mode 100644 index 677255b017b16772b45f25925bc4226f86fc41e7..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 8160 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

-(FlZ;6~3;Nne4%Bh6`2m#(N{x)k79DAx)MTWV_qaThTVGr$6C8Z)BK=kXy0Gc4 z+e`NEb%eEDDf10IaY$h1*MD3w(-Zs{%O|M7#s)4c@{_B!*mIyu4~OB%W0&p@e(Zno zbT=h@imG2+(a}KtAz6Ovg*_xjLC?;Hs=zfEIBfSCo^%V}E>d@OQlV?lUUZo<8o^pC z87=q?p&BhKa=PoTn=QuDJZX4OQ2mnGT!YUzcJR{xiH7)l;E{SfFe<>QMy4l%^_+Rq z_VEj{@T7oA1<%s?t_caR+cUkd4Qe-|HSV^%Hz)6z@JJuIn>JuRdvcY(<<51x<+9nz z+tjR4!GZ(Tmf_UkVa`ileJ7G$9$!(tVd(Qg(f1)AHmf!-USX_eB(VCJY;g4+Jd(R9 znfcR1Zsv}#&k@e2L2rb#=G|)yEO1!&&PO&9CQBBKOE&OG3#P-Gy9qM_-F>@;_~3=3 zE?9-GIjGI&21vY$D6cT&_-Ae|RKL-|EjC1CBa!9Pl1-T+X<2(dh~-m9MQ2THNal`H zY{<6;p!yB{|Ek-r1gdWyS^uY6bNB?qu`&#{q+Uvd+vQz@JtQ1<(0q=6sK86Jr!G`=?<=Pjmn{`2OxkhxV< zY7@t-L?CZyij%3KwA|f-f%9*Q=K@iCMmYsLvhClFc{pBr`n2%cFYA=Xo+Pu0&t-e> zJo~dQ%IJM7jetj{30+hX^rZCf3G_!sE!*Wy#6D(Rx~DJbK@qx#g?tOSaxr9Z1e+SD zukr@V*(_ezCUwyYM{O1V=<}K9Gz!;oO`C}}>PGNm6U7iuK4*$&TKfAlj{uIdRa}0Y zApe|+r3OCPh?bqlZFP7N}u&vdigN2g5Wg^Fjl`FaIx#KR3bf6aJa)>@goaRt(AKOdt2 z#?P711K^Q$PTxn*m4kF>>EmSW#Yw%RxG&Le^gBwHzGuBoOh6EBk_!=~=9 z1_8rL8=SIR6HhafBi&M$DXWnZ^~O>2Hi1B-`ER0}t#)F^t{D#RBjO8fpPNT4Ui#u^ z;3C*w#8Ltx=#regO34u==<;?%-hz8hG4UEN_0n_R_tob##6#K1Px zhe>DIU@n{1+6R8+`e+AlUgx%2e29aGLdppWs;`qcH7kDWh)4=>4X1s>DdsNH+QG9` z?_vPMr7uU@xj0$G3>QR1&O30qfVjHp&qN!;SPxscS_2s3q5%Dc3QBzDELBWHU+HlD^o{shPae6!7By75p2{gw|x4P|M zX<@o0gz*c0gEYkJnvsyYJs*CbhkVYP2WA1)d!v+FTdt%jBQRd5i3=G|&)kpBcS7ZE zz|mt0$l+uZ9ha7+mAAVvJA2$4ekxB^cwky=9X&+xcii&8h16v#Y1PI;>8)0k?GeX4lh6 zKqZA($vu{5_kH*^0P@gd#x%=T)FmI&t%)&DZM-jU$73@HzmIN8>E|)+`WB;JRaa7t zvX`sGZWXa9h*(r0&!&k#TE!SkbQ-q%Sd-PnZsP`7fT53t*26(qDKr>wJt%m)ikyN- zo)`W!vcx~KyoB)PHBf}DKmTHDcGEQam}~KMnH@$Q1YktKcs4fj$ku5i9v{>GpO3~} zqDpXl9hdG&_{xOs(fVnArX$Q&R0bq}A*bj@;s!D_p8m$#g0BXUc?&^9lh9`Zs z27BG1jFo(D4w>J~7dgc-Tk52jnZ@>+_Sd+?8m77xBNKL!H&Q$X;v=(T`yxjRul+3V z3E%!@R{V{^>3*QxggzrQf(;NdfHL(T`;aoMseXJ-R%Ao-%2Vyh6!*@P6^7oXTk(WU zNkA_YVhJi3h2gH3jjMf)q zg*}Nq*l8b;u`rRC*Np2%XMRdM13aNg?s$G|z?_8IY;AZn@pah3*7ZTIm%#YlrG@u! z^i5OGyK?%~i&KP0k&#o*kunTcZsQ7FlLDB{fH!m6^G6F;#W(V~s_@MyHv_wXIJ)=Z z!h6ZEYIWIVic+&3B^)klYTf_P(&@`M(+3V}&8c!nF|upy(GS>oderWYuBxIKYcz-xC~w$o%GyRst9!1%T6WrxE0 zIFyyl)b3Q#2?L!NTXj!(2`IWMekfz%K`$ys;RdC@d!(kq5RA{lUa;cr5XM-RD3tz| zpI|G>*=_J|L_Sm1b*Tw~V9FeIth#Nx=#vYpz+-oxcyg`I_!+@bWwRKyFO+A3h@85d z@uV?-n7^0>d|q5ph8BpY8(02qx}C9s)-GHAb~J@}K`!-+z&F!}y<>GC4Kspi^HJC5 zzeC~x<2lDW*~yY(r8jPIa$+aG+od4{e0fdl^_UrL9wYLak!CtJs7K##r+$7i^XRdQ ztz4>~ozXdT)jw~+#~N#FO_f$a`8zcJ86%Oo3a#yW+QAZAlNV&$G;8{U71-YQMhinG zd4m*8YJ%54b~)o9y`E-s=Y?2AU|Iu1gF<*+bw0a$^*w#`3A;OzP(fByqadT5_iA21Z1SwTd%u8=3boN55f1! z`4{MC74z8>2sQca?Jt3)u_A;a1{dzqpmEi)*Xap5qmAa_n-~4r4Yh^4FE;d@SlCEj zU@pA>ReYiR*_EW){gN5I%*}RpgKw3ytgc8|#s%KgI#YU#!b8&(2|ZsPqNq~PYvW)!^^)_V}q#qnr>j(ERR@e6Cv$qyoW7gglr9Q^_Qnor;f2jM% zo-#R4I_ZTcztxe0&Mb&|Y8lU@znX66*g4EEylUs1RM103l?PGZYAXrpHJD+D_b_XG z#6w=cpjd%&bWk>psMccTF#6fk`ju_lS2H%-^EtOB zZND1vVUlbzUMp`Q-SE1Qq{#O%N(oE{9FrCl_-ELlpq}=!9gIFnLy+&kqecL$TKYj= z*EFQ*+an57)#uY@5Y$8-14z+qMDogXWThMST8OK-ckUnNrur(`0I5KB}lVe3_!nuqDV*iq4k>fzhJujx5f zyANWf*0rZ#n6+Rqe!;J^`_Mtb)aBfFc>}qxaqjF7j8$cGu5})b8Ua(u=fW3oRpn&v zfgB+1tomVR+$G9(uCi_V{B~a;@|s2V1A+hiqk9YkPAmj1+!cBUdkf8_N2=H>t2v z)9@^0&5RviaI`9?6;;WNH;S=LtR%(5k9>{zNarib5+6a>>wQk8w&Rtw^_v7?=)jj*oXJQN^IB2{k zst;~k)nk6{RV2T#yYr44f241?O9~zzV7pkH`d;?~pQ*Bt6%dT!H2_b;03b<4&x8&* zXHP))0aMDb%HzwRHbH6&kO`BWB-rUycUztvR}_3OD_eT>n~Ip=g9p1i7pD|hN*Pga ztRG9meE1hr6CM>YUpT4b!yhQfF?9$w`|!6v-t`rbQ1gZDml|b7 zAa68ZQj|8fCb@aOlB`RE{Aib0=9eALYeu1~da-!G<_cg5Czta&8dkj1*X95C0Wv!F zY#D~HENDR}O7Ex%$xSAp3JCJ3p{^3K3V-$G-9D8}_zqupGQ2dQC%kj@Qe}rE|dpJ{<%b%2Mv1Gr!!**g#M`lkw8mCRyJ@7lkH3 zXb1~lDo=$RU_BXsrfaNjBEbFq3eU;`FHbI@S{S-=nWxZ)Rp5>~5C+OY1^cj$>7NT}HiG9Q!$b}p%;g%3M_gxnCKcLVsHf_C z^wCeGpmLG$_n=N^WEMPtOY`QuMM!Fk!fS-8Htj89y9H$vN9Tu+N$&KH)+_^& z%Dy+7l_XEO&M3|hegRXEM6OrS{UkfK{+717}icrt5 zEo2k#AwyN$wuDa!RUU(QM(5c`lu*pzLemez#5N#uR(&E9mEw>iL$LfI?sg zE#jw-EM=|6Dj3@f;UGd*eH{7EWqzGhp$)=-I89g{lQ?)O9C?EVOGk$47r$+M=Xc^> zJP=k<(J?0kk%(RKj%in+1y-{kn&IKRA#Bd0=31lFQ2DNd8r#IdKH27Ur1c(@2bsfL@lHsPie zDG9Vl!USc3{uH5d5G-`8Oc4SyrxY*2VrjXlAZ4&_V`FSzVBH_*_nq^8-}k=n^Stl# zo^oka1cT;6gCK|@7KI)Lt1|?_9yS#4HgU#a1PdumC=o(XM-_ctK?dK{Y*E~42%5T#2TDvZfbd|jV# z;*Bt7sbmUnm}1}uQEh$+xt{`cKsE<+Sza6BAD)&|Khhw8x3{qUE41?vfOcKU-U8`W!tVs=H3d)4ds+NvC%wr~FvotDLKUHS5# ztHZ

(f;!-MEj>fep;+smj%O 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 Uc`1_hXAzs3v6WGY;nk>r13;ECyZ`_I diff --git a/retroshare-gui/src/release/skin/skin.dat b/retroshare-gui/src/release/skin/skin.dat deleted file mode 100644 index 7a501621c..000000000 --- a/retroshare-gui/src/release/skin/skin.dat +++ /dev/null @@ -1,7 +0,0 @@ -[Skin] -Blur=false -Hintergrundfarbe=@Variant(\0\0\0\x43\x1\xff\xff\xd5\xd5\xd5\xd5\xd5\xd5\0\0) -SkinOn=true -Skinpfad=skin/Vista/ -Titelfarbe=@Variant(\0\0\0\x43\x1\xff\xff\0\0\0\0\0\0\0\0) -Titelschrift=@Variant(\0\0\0@\0\0\0\x1a\0\x43\0o\0m\0i\0\x63\0 \0S\0\x61\0n\0s\0 \0M\0S@$\0\0\0\0\0\0\xff\xff\xff\xff\x5\x1\0K\x10) diff --git a/retroshare-gui/src/retroshare-process.nsi b/retroshare-gui/src/retroshare-process.nsi deleted file mode 100644 index 685f90214..000000000 --- a/retroshare-gui/src/retroshare-process.nsi +++ /dev/null @@ -1,502 +0,0 @@ -; Script generated with the Venis Install Wizard & modified by defnax -; This script need the http://nsis.sourceforge.net/Processes_plug-in -; This script need the http://nsis.sourceforge.net/KillProcDLL_plug-in - -; Define your application name -!define APPNAME "RetroShare" -!define VERSION "0.4.13d" -!define APPNAMEANDVERSION "${APPNAME} ${VERSION}" - - -; Main Install settings -Name "${APPNAMEANDVERSION}" -InstallDir "$PROGRAMFILES\RetroShare" -InstallDirRegKey HKLM "Software\${APPNAME}" "" -OutFile "RetroShare_${VERSION}_setup.exe" -BrandingText "${APPNAMEANDVERSION}" -; Use compression -SetCompressor LZMA - -VAR KILLEXENAME - - -; Modern interface settings -!include Sections.nsh -!include "MUI.nsh" - -;Interface Settings -!define MUI_ABORTWARNING -;!define MUI_HEADERIMAGE -;!define MUI_HEADERIMAGE_BITMAP "retroshare.bmp" ; optional - -# MUI defines -!define MUI_ICON "${NSISDIR}\Contrib\Graphics\Icons\orange-install.ico" -!define MUI_FINISHPAGE_NOAUTOCLOSE -!define MUI_LICENSEPAGE_RADIOBUTTONS -!define MUI_COMPONENTSPAGE_SMALLDESC -!define MUI_FINISHPAGE_LINK "Visit the RetroShare forum for the latest news and support" -!define MUI_FINISHPAGE_LINK_LOCATION "http://retroshare.sourceforge.net/forum/" -!define MUI_FINISHPAGE_RUN "$INSTDIR\RetroShare.exe" -!define MUI_FINISHPAGE_SHOWREADME $INSTDIR\changelog.txt -!define MUI_FINISHPAGE_SHOWREADME_TEXT changelog.txt -!define MUI_FINISHPAGE_SHOWREADME_NOTCHECKED -!define MUI_UNICON "${NSISDIR}\Contrib\Graphics\Icons\orange-uninstall.ico" -!define MUI_UNFINISHPAGE_NOAUTOCLOSE -!define MUI_LANGDLL_REGISTRY_ROOT HKLM -!define MUI_LANGDLL_REGISTRY_KEY ${REGKEY} -!define MUI_LANGDLL_REGISTRY_VALUENAME InstallerLanguage - -; !define MUI_WELCOMEPAGE_TEXT "This wizard will guide you through the installation of RetroShare. \r\n\r\nIt is recommended that you close all other applications before starting Setup. This will make it possible to update relevant system files without havinf to reboot your computer. \r\n\r\nIMPORTANT: Ensure that RetroShare is NOT RUNNING before continuing (you can exit from the taskbar menu), otherwise the installer cannot update the executables, and the installation will fail. \r\n\r\nClick Next to continue. " - -;!define MUI_WELCOMEPAGE_TEXT "This wizard will guide you through the installation of RetroShare. \r\n\r\nIMPORTANT: Ensure that RetroShare is NOT RUNNING before continuing (you can exit from the taskbar menu), otherwise the installer cannot update the executables, and the installation will fail. \r\n\r\nClick Next to continue. " - - -; Defines the un-/installer logo of RetroShare -!insertmacro MUI_DEFAULT MUI_WELCOMEFINISHPAGE_BITMAP "${NSISDIR}\Contrib\Graphics\Wizard\orange.bmp" -!insertmacro MUI_DEFAULT MUI_UNWELCOMEFINISHPAGE_BITMAP "${NSISDIR}\Contrib\Graphics\Wizard\orange-uninstall.bmp" - -; Set languages (first is default language) -!insertmacro MUI_RESERVEFILE_LANGDLL -ReserveFile "${NSISDIR}\Plugins\AdvSplash.dll" - -;-------------------------------- -;Configuration - - - ;!insertmacro MUI_RESERVEFILE_SPECIALBITMAP - - LicenseLangString myLicenseData 1033 "license\license.txt" - LicenseLangString myLicenseData 1031 "license\license-GER.txt" - LicenseLangString myLicenseData 1036 "license\license-FR.txt" - LicenseLangString myLicenseData 1055 "license\license-TR.txt" - LicenseLangString myLicenseData 2052 "license\license.txt" - LicenseLangString myLicenseData 1045 "license\license.txt" - - LicenseData $(myLicenseData) - -# Installer pages -!insertmacro MUI_PAGE_WELCOME -!insertmacro MUI_PAGE_LICENSE "$(myLicenseData)" -!insertmacro MUI_PAGE_COMPONENTS -!insertmacro MUI_PAGE_DIRECTORY -!insertmacro MUI_PAGE_INSTFILES -!insertmacro MUI_PAGE_FINISH -!insertmacro MUI_UNPAGE_CONFIRM -!insertmacro MUI_UNPAGE_INSTFILES - -# Installer languages -!define MUI_LANGDLL_ALLLANGUAGES - -!insertmacro MUI_LANGUAGE English -!insertmacro MUI_LANGUAGE German -!insertmacro MUI_LANGUAGE French -!insertmacro MUI_LANGUAGE Turkish -!insertmacro MUI_LANGUAGE SimpChinese -!insertmacro MUI_LANGUAGE Polish - - ;Component-selection page - ;Titles - - LangString sec_main ${LANG_ENGLISH} "Program Files" - LangString sec_data ${LANG_ENGLISH} "Program Skins" - LangString sec_shortcuts ${LANG_ENGLISH} "Shortcuts" - LangString sec_link ${LANG_ENGLISH} "File Association" - LangString sec_autostart ${LANG_ENGLISH} "Auto Startup" - LangString DESC_sec_main ${LANG_ENGLISH} "Installs the RetroShare program files." - LangString DESC_sec_data ${LANG_ENGLISH} "Installs RetroShare Skins" - LangString DESC_sec_shortcuts ${LANG_ENGLISH} "Create RetroShare shortcut icons." - LangString DESC_sec_link ${LANG_ENGLISH} "Associate RetroShare with .pqi file extension" - LangString DESC_sec_autostart ${LANG_ENGLISH} "Auto-Run and Login at Startup" - LangString LANGUAGEID ${LANG_ENGLISH} "1033" - - LangString sec_main ${LANG_FRENCH} "RetroShare" - LangString sec_data ${LANG_FRENCH} "Programme de Skins" - LangString sec_shortcuts ${LANG_FRENCH} "Raccourcis" - LangString sec_link ${LANG_FRENCH} "RetroShare fichiers Association" - LangString sec_startmenu ${LANG_FRENCH} "Raccourcis du menu Démarrer" - LangString sec_autostart ${LANG_FRENCH} "Démarrage automatique" - LangString DESC_sec_main ${LANG_FRENCH} "Installe les fichiers du programme." - LangString DESC_sec_data ${LANG_FRENCH} "Installe RetroShare Skins" - LangString DESC_sec_startmenu ${LANG_FRENCH} "Crée les raccourcis du menu Démarrer" - LangString DESC_sec_shortcuts ${LANG_FRENCH} "Crée une icône sur le bureau." - LangString DESC_sec_link ${LANG_FRENCH} "Associate RetroShare with .pqi file extension" - LangString DESC_sec_autostart ${LANG_FRENCH} "Run and Auto-connexion au démarrage" - LangString LANGUAGEID ${LANG_FRENCH} "1036" - - LangString sec_main ${LANG_GERMAN} "Programmdateien" - LangString sec_data ${LANG_GERMAN} "Skins f�r das Programm" - LangString sec_shortcuts ${LANG_GERMAN} "Shortcuts" - LangString sec_link ${LANG_GERMAN} "Dateiverkn�pfungen" - LangString sec_autostart ${LANG_GERMAN} "Auto Startup" - LangString DESC_sec_main ${LANG_GERMAN} "Installiert die erforderlichen Programmdateien." - LangString DESC_sec_data ${LANG_GERMAN} "Installiert RetroShare Skins" - LangString DESC_sec_shortcuts ${LANG_GERMAN} "Erstellt eine RetroShare Verkn�pfung im Startmen�, Desktop oder im Schnellstarter." - LangString DESC_sec_link ${LANG_GERMAN} "RetroShare mit .pqi Dateien verkn�pfen" - LangString DESC_sec_autostart ${LANG_GERMAN} "Beim Neustart automatisch RetroShare starten und sich anmelden" - LangString LANGUAGEID ${LANG_GERMAN} "1031" - - LangString sec_main ${LANG_TURKISH} "Program Dosyalar�" - LangString sec_data ${LANG_TURKISH} "Program Skinleri" - LangString sec_shortcuts ${LANG_TURKISH} "Shortcut'lar" - LangString sec_link ${LANG_TURKISH} ".pqi Dosya Kaydet" - LangString sec_autostart ${LANG_TURKISH} "Otomatik calistir ve baglan" - LangString DESC_sec_main ${LANG_TURKISH} "Program dosyalar�n� kurar." - LangString DESC_sec_data ${LANG_TURKISH} "RetroShare Skin'leri kurar" - LangString DESC_sec_shortcuts ${TURKISH} "Shortcut yap Start menu , Desktop veya Quicklaunchbar icin." - LangString DESC_sec_link ${LANG_TURKISH} "RetroShare .pqi almas� i�in kaydettirir" - LangString DESC_sec_autostart ${LANG_TURKISH} "Isletim sistemi acildiginda Otomatik olarak calistir ve baglan" - LangString LANGUAGEID ${LANG_TURKISH} "1055" - - LangString sec_main ${LANG_SIMPCHINESE} "程序文件" - LangString sec_data ${LANG_SIMPCHINESE} "程序皮肤" - LangString sec_shortcuts ${LANG_SIMPCHINESE} "快捷方式" - LangString sec_link ${LANG_SIMPCHINESE} "RetroShare文件关联" - LangString sec_autostart ${LANG_SIMPCHINESE} "自动启动" - LangString DESC_sec_main ${LANG_SIMPCHINESE} "安装RetroShare程序" - LangString DESC_sec_data ${LANG_SIMPCHINESE} "安装RetroShare皮肤" - LangString DESC_sec_shortcuts ${LANG_SIMPCHINESE} "建RetroShare快捷方式" - LangString DESC_sec_link ${LANG_SIMPCHINESE} "关联.pqi扩展名" - LangString DESC_sec_autostart ${LANG_SIMPCHINESE} "启动时自动运行和登录" - LangString LANGUAGEID ${LANG_SIMPCHINESE} "2052" - - LangString sec_main ${LANG_POLISH} "Pliki programu" - LangString sec_data ${LANG_POLISH} "Skórki" - LangString sec_shortcuts ${LANG_POLISH} "Skróty" - LangString sec_link ${LANG_POLISH} "Skojarz pliki" - LangString sec_autostart ${LANG_POLISH} "Automatyczne uruchamianie" - LangString DESC_sec_main ${LANG_POLISH} "Instaluje pliki programu RetroShare" - LangString DESC_sec_data ${LANG_POLISH} "Instaluje skórki programu RetroShare" - LangString DESC_sec_shortcuts ${LANG_POLISH} "Utwórz ikony skrótów na pulpicie, w menu start oraz na pasku szybkiego uruchamiania." - LangString DESC_sec_link ${LANG_POLISH} "Skojarz pliki o rozszerzeniu .pqi z RetroShare" - LangString DESC_sec_autostart ${LANG_POLISH} "Uruchom i zaloguj podczas startu systemu" - LangString LANGUAGEID ${LANG_POLISH} "1045" - - -!insertmacro MUI_RESERVEFILE_INSTALLOPTIONS - -; CloseRetroShare: this will in a loop send the RetroShare window the WM_CLOSE -; message until it does not find a valid RetroShare window -; - -!macro CloseRetroShare UN -Function ${UN}CloseRetroShare - Push $0 - - IntFmt $R4 "%u" 0 - - goto skip - killloop: - DetailPrint "Killing RetroShare" - KillProcDLL::KillProc "RetroShare.exe" - loop: - Sleep 1000 - IntOp $R4 $R4 + 1 - IntCmp $R4 5 done - skip: - DetailPrint "Looking for running copies of RetroShare" - - ;Push "wxWindowClassNR" # the wcn - ;Push "RetroShare" # the known part of the wt - ;Call ${UN}EnhancedFindWindow - ;Pop $0 # will contain the window's handle - ;Pop $1 # will containg the full wcn - # both will containg "failed", if no matching wcn was found - - ;StrCmp $0 "failed" done - ;StrCmp $0 "0" done - ;DetailPrint "Stopping RetroShare" - ;SendMessage $0 16 0 0 # WM_CLOSE == 16 - Goto loop - done: - - IntFmt $R4 "%u" 0 - Processes::FindProcess "RetroShare.exe" - StrCmp $R0 "1" killloop reallydone - - reallydone: - Pop $0 -FunctionEnd -!macroend - - -!macro CheckForIt UN -Function ${UN}CheckForIt - - Processes::FindProcess $KILLEXENAME - StrCmp $R0 "1" foundit didntfindit - - foundit: - MessageBox MB_OKCANCEL "You must quit ${APPNAME} ($KILLEXENAME) \ - before installing this version.$\r$\nPlease quit it and press \ - OK to continue." IDOK tryagain - Abort - - tryagain: - - Sleep 2000 - Processes::FindProcess $KILLEXENAME - StrCmp $R0 "1" stillthere didntfindit - - stillthere: - MessageBox MB_OKCANCEL "There is still a copy of ${APPNAME} \ - ($KILLEXENAME) running.$\r$\nPress OK to force-quit the application, \ - or Cancel to exit." IDOK killit - Abort - - killit: - KillProcDLL::KillProc $KILLEXENAME - Sleep 1000 - - didntfindit: - -FunctionEnd -!macroend - -!macro QuitIt UN -Function ${UN}QuitIt - - # try nicely first - Call ${UN}CloseRetroShare - - # kill all the old ones - StrCpy $KILLEXENAME "RetroShare.exe" - Call ${UN}CheckForIt - StrCpy $KILLEXENAME "" -FunctionEnd -!macroend - - -; This function automatically uninstalls older versions. -; It is largely copied from: -; http://nsis.sourceforge.net/archive/viewpage.php?pageid=326 - - -Section $(sec_main) sec_main - - ;Set Section required - SectionIn RO - - ; Set Section properties - SetOverwrite on - - ; Clears previous error logs - Delete "$INSTDIR\*.log" - - ; Set Section Files and Shortcuts - SetOutPath "$INSTDIR\" - File /r "release\RetroShare.exe" - File /r "D:\Qt\2009.02\mingw\bin\mingwm10.dll" - File /r "D:\Qt\2009.02\qt\bin\QtCore4.dll" - File /r "D:\Qt\2009.02\qt\bin\QtGui4.dll" - File /r "D:\Qt\2009.02\qt\bin\QtNetwork4.dll" - File /r "D:\Qt\2009.02\qt\bin\QtXml4.dll" - File /r "D:\Qt\2009.02\qt\bin\QtScript4.dll" - File /r "pthreadGCE2.dll" - File /r "pthreadGC2d.dll" - File /r "changelog.txt" - - -SectionEnd - -Section $(sec_data) sec_data - - ; Set Section properties - SetOverwrite on - - ; Set Section Files and Shortcuts - SetOutPath "$APPDATA\RetroShare\" - ;File /r "data\*" - - ; We're not ready for external skins... - ; Set Section qss need to remove svn path - SetOutPath "$INSTDIR\qss\" - File /r qss\*.* - - ; Set Section skin - ; SetOutPath "$INSTDIR\skin\" - ; File /r release\skin\*.* - - ; Add emoticons - SetOutPath "$INSTDIR\emoticons\" - File /r emoticons\*.* - - ; Add Chat Style - SetOutPath "$INSTDIR\style\" - File /r style\*.* - -SectionEnd - -Section $(sec_link) sec_link - ; Delete any existing keys - - - ; Write the file association - WriteRegStr HKCR .pqi "" retroshare - WriteRegStr HKCR retroshare "" "PQI File" - WriteRegBin HKCR retroshare EditFlags 00000100 - WriteRegStr HKCR "retroshare\shell" "" open - WriteRegStr HKCR "retroshare\shell\open\command" "" `"$INSTDIR\RetroShare.exe" "%1"` - -SectionEnd - -SectionGroup $(sec_shortcuts) sec_shortcuts -Section StartMenu SEC0001 - - SetOutPath "$INSTDIR" - CreateDirectory "$SMPROGRAMS\${APPNAME}" - CreateShortCut "$SMPROGRAMS\${APPNAME}\$(^UninstallLink).lnk" "$INSTDIR\uninstall.exe" "" "$INSTDIR\uninstall.exe" 0 - CreateShortCut "$SMPROGRAMS\${APPNAME}\${APPNAME}.lnk" "$INSTDIR\RetroShare.exe" "" "$INSTDIR\RetroShare.exe" 0 - -SectionEnd - -Section Desktop SEC0002 - - - CreateShortCut "$DESKTOP\${APPNAME}.lnk" "$INSTDIR\RetroShare.exe" "" "$INSTDIR\RetroShare.exe" 0 - -SectionEnd - -Section Quicklaunchbar SEC0003 - - - CreateShortCut "$QUICKLAUNCH\${APPNAME}.lnk" "$INSTDIR\RetroShare.exe" "" "$INSTDIR\RetroShare.exe" 0 - -SectionEnd -SectionGroupEnd - -;Section $(sec_autostart) sec_autostart - -; WriteRegStr HKCU "Software\Microsoft\Windows\CurrentVersion\Run" "RetroRun" "$INSTDIR\${APPNAME}.exe -a" - -;SectionEnd - -Section $(sec_autostart) sec_autostart - - CreateShortCut "$SMSTARTUP\${APPNAME}.lnk" "$INSTDIR\RetroShare.exe" "" "$INSTDIR\RetroShare.exe" 0 -SectionEnd - - -Section -FinishSection - - WriteRegStr HKLM "Software\${APPNAME}" "" "$INSTDIR" - WriteRegStr HKLM "Software\${APPNAME}" "Version" "${VERSION}" - WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${APPNAME}" "DisplayName" "${APPNAME}" - WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${APPNAME}" "UninstallString" "$INSTDIR\uninstall.exe" - WriteUninstaller "$INSTDIR\uninstall.exe" - -SectionEnd - - - -;-------------------------------- -;Descriptions - -!insertmacro MUI_FUNCTION_DESCRIPTION_BEGIN - !insertmacro MUI_DESCRIPTION_TEXT ${sec_main} $(DESC_sec_main) - !insertmacro MUI_DESCRIPTION_TEXT ${sec_data} $(DESC_sec_data) - !insertmacro MUI_DESCRIPTION_TEXT ${sec_shortcuts} $(DESC_sec_shortcuts) - !insertmacro MUI_DESCRIPTION_TEXT ${sec_link} $(DESC_sec_link) - !insertmacro MUI_DESCRIPTION_TEXT ${sec_autostart} $(DESC_sec_autostart) -!insertmacro MUI_FUNCTION_DESCRIPTION_END - - -;!insertmacro EnhancedFindWindow "" -;!insertmacro EnhancedFindWindow "un." - -!insertmacro CloseRetroShare "" -!insertmacro CloseRetroShare "un." - -!insertmacro CheckForIt "" -!insertmacro CheckForIt "un." - -!insertmacro QuitIt "" -!insertmacro QuitIt "un." - -;Uninstall section -Section "Uninstall" - - Call un.QuitIt - - ; Remove file association registry keys - DeleteRegKey HKCR .pqi - DeleteRegKey HKCR retroshare - - ; Remove program/uninstall regsitry keys - DeleteRegKey HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${APPNAME}" - DeleteRegKey HKLM SOFTWARE\${APPNAME} - - DeleteRegValue HKCU "Software\Microsoft\Windows\CurrentVersion\Run" "RetroRun" - - ; Remove files and uninstaller - Delete $INSTDIR\RetroShare.exe - Delete $INSTDIR\*.dll - Delete $INSTDIR\*.dat - Delete $INSTDIR\*.txt - Delete $INSTDIR\*.ini - Delete $INSTDIR\*.log - - Delete $INSTDIR\uninstall.exe - - ; Remove the kadc.ini file. - ; Don't remove the directory, otherwise - ; we lose the XPGP keys. - ; Should make this an option though... - Delete "$APPDATA\${APPNAME}\kadc.ini" - Delete "$APPDATA\${APPNAME}\*.cfg" - Delete "$APPDATA\${APPNAME}\*.conf" - Delete "$APPDATA\${APPNAME}\*.log-save" - Delete "$APPDATA\${APPNAME}\*.log" - Delete "$APPDATA\${APPNAME}\*.failed" - - RMDir /r "$APPDATA\${APPNAME}\cache" - RMDir /r "$APPDATA\${APPNAME}\Partials" - - ; Remove shortcuts, if any - Delete "$SMPROGRAMS\${APPNAME}\*.*" - - ; Remove desktop shortcut - Delete "$DESKTOP\${APPNAME}.lnk" - - ; Remove Quicklaunch shortcut - Delete "$QUICKLAUNCH\${APPNAME}.lnk" - - ; Remove Autstart - Delete "$SMSTARTUP\${APPNAME}.lnk" - - ; Remove directories used - RMDir "$SMPROGRAMS\${APPNAME}" - RMDir /r "$INSTDIR" - RMDir /r "$INSTDIR\qss" - RMDir /r "$INSTDIR\emoticons" - RMDir /r "$INSTDIR\style" - -SectionEnd - -Function .onInit - - InitPluginsDir - Push $R1 - File /oname=$PLUGINSDIR\spltmp.bmp "gui\images\splash.bmp" - advsplash::show 1200 1000 1000 -1 $PLUGINSDIR\spltmp - Pop $R1 - Pop $R1 - !insertmacro MUI_LANGDLL_DISPLAY - -FunctionEnd - - -# Installer Language Strings -# TODO Update the Language Strings with the appropriate translations. - -LangString ^UninstallLink ${LANG_ENGLISH} "Uninstall" -LangString ^UninstallLink ${LANG_GERMAN} "Deinstallieren" -LangString ^UninstallLink ${LANG_TURKISH} "Kald�r" -LangString ^UninstallLink ${LANG_FRENCH} "Désinstaller" -LangString ^UninstallLink ${LANG_SIMPCHINESE} "卸载" -LangString ^UninstallLink ${LANG_POLISH} "Odinstaluj" - - - - - -; eof diff --git a/retroshare-gui/src/retroshare-ultramodern.nsi b/retroshare-gui/src/retroshare-ultramodern.nsi deleted file mode 100644 index d224cc8f1..000000000 --- a/retroshare-gui/src/retroshare-ultramodern.nsi +++ /dev/null @@ -1,501 +0,0 @@ -; Script generated with the Venis Install Wizard & modified by defnax - -; Define your application name -!define APPNAME "RetroShare" -!define VERSION "0.5.1 4049" -!define APPNAMEANDVERSION "${APPNAME} ${VERSION}" -!define QTBASE "D:\qt\2010.01" - -; Main Install settings -Name "${APPNAMEANDVERSION}" -InstallDir "$PROGRAMFILES\RetroShare" -InstallDirRegKey HKLM "Software\${APPNAME}" "" -OutFile "RetroShare_${VERSION}_setup_ultramodern.exe" -BrandingText "${APPNAMEANDVERSION}" -; Use compression -SetCompressor /SOLID LZMA - -; Modern interface settings -!include Sections.nsh -!include "UMUI.nsh" - -;Interface Settings -!define MUI_ABORTWARNING -;!define MUI_HEADERIMAGE -;!define MUI_HEADERIMAGE_BITMAP "retroshare.bmp" ; optional - -# MUI defines -!define MUI_ICON "${NSISDIR}\Contrib\Graphics\UltraModernUI\Icon.ico" -!define MUI_FINISHPAGE_NOAUTOCLOSE -!define MUI_LICENSEPAGE_RADIOBUTTONS -!define MUI_COMPONENTSPAGE_SMALLDESC -!define MUI_FINISHPAGE_LINK "Visit the RetroShare forum for the latest news and support" -!define MUI_FINISHPAGE_LINK_LOCATION "http://retroshare.sourceforge.net/forum/" -!define MUI_FINISHPAGE_RUN "$INSTDIR\RetroShare.exe" -!define MUI_FINISHPAGE_SHOWREADME $INSTDIR\changelog.txt -!define MUI_FINISHPAGE_SHOWREADME_TEXT changelog.txt -!define MUI_FINISHPAGE_SHOWREADME_NOTCHECKED -!define MUI_UNICON "${NSISDIR}\Contrib\Graphics\UltraModernUI\UnIcon.ico" -!define MUI_UNFINISHPAGE_NOAUTOCLOSE -!define MUI_LANGDLL_REGISTRY_ROOT HKLM -!define MUI_LANGDLL_REGISTRY_KEY ${REGKEY} -!define UMUI_LANGDLL_REGISTRY_VALUENAME InstallerLanguage - -;!define MUI_WELCOMEPAGE_TEXT "This wizard will guide you through the installation of RetroShare. \r\n\r\nIt is recommended that you close all other applications before starting Setup. This will make it possible to update relevant system files without havinf to reboot your computer. \r\n\r\nIMPORTANT: Ensure that RetroShare is NOT RUNNING before continuing (you can exit from the taskbar menu), otherwise the installer cannot update the executables, and the installation will fail. \r\n\r\nClick Next to continue. " - -;!define MUI_WELCOMEPAGE_TEXT "This wizard will guide you through the installation of RetroShare. \r\n\r\nIMPORTANT: Ensure that RetroShare is NOT RUNNING before continuing (you can exit from the taskbar menu), otherwise the installer cannot update the executables, and the installation will fail. \r\n\r\nClick Next to continue. " - - -; Defines the un-/installer logo of RetroShare -!insertmacro MUI_DEFAULT MUI_WELCOMEFINISHPAGE_BITMAP "${NSISDIR}\Contrib\Graphics\Wizard\orange.bmp" -!insertmacro MUI_DEFAULT MUI_UNWELCOMEFINISHPAGE_BITMAP "${NSISDIR}\Contrib\Graphics\Wizard\orange-uninstall.bmp" - -; Set languages (first is default language) -!insertmacro MUI_RESERVEFILE_LANGDLL -ReserveFile "${NSISDIR}\Plugins\AdvSplash.dll" - -;-------------------------------- -;Configuration - - - ;!insertmacro MUI_RESERVEFILE_SPECIALBITMAP - - LicenseLangString myLicenseData 1030 "license\license.txt" - LicenseLangString myLicenseData 1033 "license\license.txt" - LicenseLangString myLicenseData 1031 "license\license-GER.txt" - LicenseLangString myLicenseData 1036 "license\license-FR.txt" - LicenseLangString myLicenseData 1055 "license\license-TR.txt" - LicenseLangString myLicenseData 2052 "license\license.txt" - LicenseLangString myLicenseData 1045 "license\license.txt" - LicenseLangString myLicenseData 1041 "license\license.txt" - LicenseLangString myLicenseData 1042 "license\license.txt" - LicenseLangString myLicenseData 1049 "license\license.txt" - LicenseLangString myLicenseData 1053 "license\license.txt" - - LicenseData $(myLicenseData) - -# Installer pages -!insertmacro MUI_PAGE_WELCOME -!insertmacro MUI_PAGE_LICENSE "$(myLicenseData)" -!insertmacro MUI_PAGE_COMPONENTS -!insertmacro MUI_PAGE_DIRECTORY -!insertmacro MUI_PAGE_INSTFILES -!insertmacro MUI_PAGE_FINISH -!insertmacro MUI_UNPAGE_CONFIRM -!insertmacro MUI_UNPAGE_INSTFILES - -# Installer languages -!define MUI_LANGDLL_ALLLANGUAGES - -!insertmacro MUI_LANGUAGE Danish -!insertmacro MUI_LANGUAGE English -!insertmacro MUI_LANGUAGE French -!insertmacro MUI_LANGUAGE German -!insertmacro MUI_LANGUAGE Japanese -!insertmacro MUI_LANGUAGE Korean -!insertmacro MUI_LANGUAGE Polish -!insertmacro MUI_LANGUAGE Russian -!insertmacro MUI_LANGUAGE Swedish -!insertmacro MUI_LANGUAGE SimpChinese -!insertmacro MUI_LANGUAGE Turkish - - - - ;Component-selection page - ;Titles - - LangString sec_main ${LANG_ENGLISH} "Program Files" - LangString sec_data ${LANG_ENGLISH} "Program Skins" - LangString sec_shortcuts ${LANG_ENGLISH} "Shortcuts" - LangString sec_link ${LANG_ENGLISH} "File Association" - LangString sec_autostart ${LANG_ENGLISH} "Auto Startup" - LangString DESC_sec_main ${LANG_ENGLISH} "Installs the RetroShare program files." - LangString DESC_sec_data ${LANG_ENGLISH} "Installs RetroShare Skins" - LangString DESC_sec_shortcuts ${LANG_ENGLISH} "Create RetroShare shortcut icons." - LangString DESC_sec_link ${LANG_ENGLISH} "Associate RetroShare with .rsc file extension" - LangString LANGUAGEID ${LANG_ENGLISH} "1033" - - - LangString sec_main ${LANG_FRENCH} "RetroShare" - LangString sec_data ${LANG_FRENCH} "Programme de Skins" - LangString sec_shortcuts ${LANG_FRENCH} "Raccourcis" - LangString sec_link ${LANG_FRENCH} "RetroShare fichiers Association" - LangString sec_startmenu ${LANG_FRENCH} "Raccourcis du menu Démarrer" - LangString sec_autostart ${LANG_FRENCH} "Démarrage automatique" - LangString DESC_sec_main ${LANG_FRENCH} "Installe les fichiers du programme." - LangString DESC_sec_data ${LANG_FRENCH} "Installe RetroShare Skins" - LangString DESC_sec_startmenu ${LANG_FRENCH} "Crée les raccourcis du menu Démarrer" - LangString DESC_sec_shortcuts ${LANG_FRENCH} "Crée une icône sur le bureau." - LangString DESC_sec_link ${LANG_FRENCH} "Associate RetroShare with .rsc file extension" - LangString LANGUAGEID ${LANG_FRENCH} "1036" - - - LangString sec_main ${LANG_GERMAN} "Programmdateien" - LangString sec_data ${LANG_GERMAN} "Skins fuer das Programm" - LangString sec_shortcuts ${LANG_GERMAN} "Shortcuts" - LangString sec_link ${LANG_GERMAN} "Dateiverknuepfungen" - LangString sec_autostart ${LANG_GERMAN} "Auto Startup" - LangString DESC_sec_main ${LANG_GERMAN} "Installiert die erforderlichen Programmdateien." - LangString DESC_sec_data ${LANG_GERMAN} "Installiert RetroShare Skins" - LangString DESC_sec_shortcuts ${LANG_GERMAN} "Erstellt eine RetroShare Verkn�pfung im Startmen�, Desktop oder im Schnellstarter." - LangString DESC_sec_link ${LANG_GERMAN} "RetroShare mit .rsc Dateien verkn�pfen" - LangString LANGUAGEID ${LANG_GERMAN} "1031" - - LangString sec_main ${LANG_TURKISH} "Program Dosyalar�" - LangString sec_data ${LANG_TURKISH} "Program Skinleri" - LangString sec_shortcuts ${LANG_TURKISH} "Shortcut'lar" - LangString sec_link ${LANG_TURKISH} ".rsc Dosya Kaydet" - LangString sec_autostart ${LANG_TURKISH} "Otomatik calistir ve baglan" - LangString DESC_sec_main ${LANG_TURKISH} "Program dosyalar�n� kurar." - LangString DESC_sec_data ${LANG_TURKISH} "RetroShare Skin'leri kurar" - LangString DESC_sec_shortcuts ${TURKISH} "Shortcut yap Start menu , Desktop veya Quicklaunchbar icin." - LangString DESC_sec_link ${LANG_TURKISH} "RetroShare .rsc almas� i�in kaydettirir" - LangString LANGUAGEID ${LANG_TURKISH} "1055" - - LangString sec_main ${LANG_SIMPCHINESE} "程序文件" - LangString sec_data ${LANG_SIMPCHINESE} "程序皮肤" - LangString sec_shortcuts ${LANG_SIMPCHINESE} "快捷方式" - LangString sec_link ${LANG_SIMPCHINESE} "RetroShare文件关联" - LangString sec_autostart ${LANG_SIMPCHINESE} "自动启动" - LangString DESC_sec_main ${LANG_SIMPCHINESE} "安装RetroShare程序" - LangString DESC_sec_data ${LANG_SIMPCHINESE} "安装RetroShare皮肤" - LangString DESC_sec_shortcuts ${LANG_SIMPCHINESE} "建RetroShare快捷方式" - LangString DESC_sec_link ${LANG_SIMPCHINESE} "关联.rsc扩" - LangString LANGUAGEID ${LANG_SIMPCHINESE} "2052" - - LangString sec_main ${LANG_POLISH} "Pliki programu" - LangString sec_data ${LANG_POLISH} "Skórki" - LangString sec_shortcuts ${LANG_POLISH} "Skróty" - LangString sec_link ${LANG_POLISH} "Skojarz pliki" - LangString sec_autostart ${LANG_POLISH} "Automatyczne uruchamianie" - LangString DESC_sec_main ${LANG_POLISH} "Instaluje pliki programu RetroShare" - LangString DESC_sec_data ${LANG_POLISH} "Instaluje skórki programu RetroShare" - LangString DESC_sec_shortcuts ${LANG_POLISH} "Utwórz ikony skrótów na pulpicie, w menu start oraz na pasku szybkiego uruchamiania." - LangString DESC_sec_link ${LANG_POLISH} "Skojarz pliki o rozszerzeniu .rsc z RetroShare" - LangString LANGUAGEID ${LANG_POLISH} "1045" - - LangString sec_main ${LANG_DANISH} "Program Files" - LangString sec_data ${LANG_DANISH} "Program Skins" - LangString sec_shortcuts ${LANG_DANISH} "Shortcuts" - LangString sec_link ${LANG_DANISH} "File Association" - LangString sec_autostart ${LANG_DANISH} "Auto Startup" - LangString DESC_sec_main ${LANG_DANISH} "Installs the RetroShare program files." - LangString DESC_sec_data ${LANG_DANISH} "Installs RetroShare Skins" - LangString DESC_sec_shortcuts ${LANG_DANISH} "Create RetroShare shortcut icons." - LangString DESC_sec_link ${LANG_DANISH} "Associate RetroShare with .rsc file extension" - LangString LANGUAGEID ${LANG_DANISH} "1030" - - LangString sec_main ${LANG_RUSSIAN} "Program Files" - LangString sec_data ${LANG_RUSSIAN} "Program Skins" - LangString sec_shortcuts ${LANG_RUSSIAN} "Shortcuts" - LangString sec_link ${LANG_RUSSIAN} "File Association" - LangString sec_autostart ${LANG_RUSSIAN} "Auto Startup" - LangString DESC_sec_main ${LANG_RUSSIAN} "Installs the RetroShare program files." - LangString DESC_sec_data ${LANG_RUSSIAN} "Installs RetroShare Skins" - LangString DESC_sec_shortcuts ${LANG_RUSSIAN} "Create RetroShare shortcut icons." - LangString DESC_sec_link ${LANG_RUSSIAN} "Associate RetroShare with .rsc file extension" - LangString LANGUAGEID ${LANG_RUSSIAN} "1049" - - LangString sec_main ${LANG_SWEDISH} "Program Files" - LangString sec_data ${LANG_SWEDISH} "Program Skins" - LangString sec_shortcuts ${LANG_SWEDISH} "Shortcuts" - LangString sec_link ${LANG_SWEDISH} "File Association" - LangString sec_autostart ${LANG_SWEDISH} "Auto Startup" - LangString DESC_sec_main ${LANG_SWEDISH} "Installs the RetroShare program files." - LangString DESC_sec_data ${LANG_SWEDISH} "Installs RetroShare Skins" - LangString DESC_sec_shortcuts ${LANG_SWEDISH} "Create RetroShare shortcut icons." - LangString DESC_sec_link ${LANG_SWEDISH} "Associate RetroShare with .rsc file extension" - LangString LANGUAGEID ${LANG_SWEDISH} "1053" - - LangString sec_main ${LANG_JAPANESE} "Program Files" - LangString sec_data ${LANG_JAPANESE} "Program Skins" - LangString sec_shortcuts ${LANG_JAPANESE} "Shortcuts" - LangString sec_link ${LANG_JAPANESE} "File Association" - LangString sec_autostart ${LANG_JAPANESE} "Auto Startup" - LangString DESC_sec_main ${LANG_JAPANESE} "Installs the RetroShare program files." - LangString DESC_sec_data ${LANG_JAPANESE} "Installs RetroShare Skins" - LangString DESC_sec_shortcuts ${LANG_JAPANESE} "Create RetroShare shortcut icons." - LangString DESC_sec_link ${LANG_JAPANESE} "Associate RetroShare with .rsc file extension" - LangString LANGUAGEID ${LANG_JAPANESE} "1041" - - LangString sec_main ${LANG_KOREAN} "Program Files" - LangString sec_data ${LANG_KOREAN} "Program Skins" - LangString sec_shortcuts ${LANG_KOREAN} "Shortcuts" - LangString sec_link ${LANG_KOREAN} "File Association" - LangString sec_autostart ${LANG_KOREAN} "Auto Startup" - LangString DESC_sec_main ${LANG_KOREAN} "Installs the RetroShare program files." - LangString DESC_sec_data ${LANG_KOREAN} "Installs RetroShare Skins" - LangString DESC_sec_shortcuts ${LANG_KOREAN} "Create RetroShare shortcut icons." - LangString DESC_sec_link ${LANG_KOREAN} "Associate RetroShare with .rsc file extension" - LangString LANGUAGEID ${LANG_KOREAN} "1042" - - -!insertmacro MUI_RESERVEFILE_INSTALLOPTIONS - -Section $(sec_main) sec_main - - ;Set Section required - SectionIn RO - - ; Set Section properties - SetOverwrite on - - ; Clears previous error logs - Delete "$INSTDIR\*.log" - - ; Set Section Files and Shortcuts - SetOutPath "$INSTDIR\" - File /r "release\RetroShare.exe" - File /r "..\..\retroshare-nogui\src\release\retroshare-nogui.exe" - File /r "D:\Qt\2010.01\mingw\bin\mingwm10.dll" - File /r "D:\Qt\2010.01\qt\bin\QtCore4.dll" - File /r "D:\Qt\2010.01\qt\bin\QtGui4.dll" - File /r "D:\Qt\2010.01\qt\bin\QtNetwork4.dll" - File /r "D:\Qt\2010.01\qt\bin\QtXml4.dll" - File /r "D:\Qt\2010.01\qt\bin\QtScript4.dll" - File /r "D:\Qt\2010.01\qt\bin\libgcc_s_dw2-1.dll" - File /r "D:\Qt\2010.01\qt\plugins\imageformats" - File /r "D:\Development\miniupnpc-1.3\miniupnpc.dll" - File /r ${QTBASE}\qt\qt_*.qm - File /r "release\pthreadGC2d.dll" - File /r "release\libgpg-error-0.dll" - File /r "release\libgpgme-11.dll" - File /r "changelog.txt" - File /r /x Data "release\bdboot.txt" - - -SectionEnd - -Section $(sec_data) sec_data - - ; Set Section properties - SetOverwrite on - - ; Set Section Files and Shortcuts - SetOutPath "$APPDATA\RetroShare\" - ;File /r "data\*" - - ; Set Section Plugins - SetOutPath "$APPDATA\RetroShare\plugins\" - ;File /r "plugins\" - - ; Set Section qss and exclude svn - SetOutPath "$INSTDIR\qss\" - File /r /x .svn qss\*.* - - ; Set Section sounds and exclude svn - SetOutPath "$INSTDIR\sounds\" - File /r /x .svn sounds\*.* - - ; Set Section skin - ; SetOutPath "$INSTDIR\skin\" - ; File /r release\skin\*.* - - ; Add emoticons - ;SetOutPath "$INSTDIR\emoticons\" - ;File /r emoticons\*.* - - ; Add Chat Style - ;SetOutPath "$INSTDIR\style\" - ;File /r style\*.* - -SectionEnd - -; These are the programs that are needed by RetroShare. -Section -Prerequisites - SetOutPath $INSTDIR\Prerequisites - MessageBox MB_YESNO "$(InstallGPG4WIN)" /SD IDYES IDNO leave - File "Prerequisites\gpg4win-1.1.4.exe" - ExecWait "$INSTDIR\Prerequisites\gpg4win-1.1.4.exe" - - leave: -SectionEnd - -Section $(sec_link) sec_link - ; Delete any existing keys - - - ; Write the file association - WriteRegStr HKCR .rsc "" retroshare - WriteRegStr HKCR retroshare "" "RSC File" - WriteRegBin HKCR retroshare EditFlags 00000100 - WriteRegStr HKCR "retroshare\shell" "" open - WriteRegStr HKCR "retroshare\shell\open\command" "" `"$INSTDIR\RetroShare.exe" "%1"` - -SectionEnd - -SectionGroup $(sec_shortcuts) sec_shortcuts -Section StartMenu SEC0001 - - SetOutPath "$INSTDIR" - CreateDirectory "$SMPROGRAMS\${APPNAME}" - CreateShortCut "$SMPROGRAMS\${APPNAME}\${APPNAME}.lnk" "$INSTDIR\RetroShare.exe" "" "$INSTDIR\RetroShare.exe" 0 - CreateShortCut "$SMPROGRAMS\${APPNAME}\$(^UninstallLink).lnk" "$INSTDIR\uninstall.exe" "" "$INSTDIR\uninstall.exe" 0 - -SectionEnd - -Section Desktop SEC0002 - - - CreateShortCut "$DESKTOP\${APPNAME}.lnk" "$INSTDIR\RetroShare.exe" "" "$INSTDIR\RetroShare.exe" 0 - -SectionEnd - -Section Quicklaunchbar SEC0003 - - - CreateShortCut "$QUICKLAUNCH\${APPNAME}.lnk" "$INSTDIR\RetroShare.exe" "" "$INSTDIR\RetroShare.exe" 0 - -SectionEnd -SectionGroupEnd - -;Section $(sec_autostart) sec_autostart - -; WriteRegStr HKCU "Software\Microsoft\Windows\CurrentVersion\Run" "RetroRun" "$INSTDIR\${APPNAME}.exe -a" - -;SectionEnd - -;Section $(sec_autostart) sec_autostart - -; CreateShortCut "$SMSTARTUP\${APPNAME}.lnk" "$INSTDIR\RetroShare.exe" "" "$INSTDIR\RetroShare.exe" 0 -;SectionEnd - - -Section -FinishSection - - WriteRegStr HKLM "Software\${APPNAME}" "" "$INSTDIR" - WriteRegStr HKLM "Software\${APPNAME}" "Version" "${VERSION}" - WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${APPNAME}" "DisplayName" "${APPNAME}" - WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${APPNAME}" "UninstallString" "$INSTDIR\uninstall.exe" - WriteUninstaller "$INSTDIR\uninstall.exe" - -SectionEnd - - - -;-------------------------------- -;Descriptions - -!insertmacro MUI_FUNCTION_DESCRIPTION_BEGIN - !insertmacro MUI_DESCRIPTION_TEXT ${sec_main} $(DESC_sec_main) - !insertmacro MUI_DESCRIPTION_TEXT ${sec_data} $(DESC_sec_data) - !insertmacro MUI_DESCRIPTION_TEXT ${sec_shortcuts} $(DESC_sec_shortcuts) - !insertmacro MUI_DESCRIPTION_TEXT ${sec_link} $(DESC_sec_link) - ;!insertmacro MUI_DESCRIPTION_TEXT ${sec_autostart} $(DESC_sec_autostart) -!insertmacro MUI_FUNCTION_DESCRIPTION_END - -;Uninstall section -Section "Uninstall" - - ; Remove file association registry keys - DeleteRegKey HKCR .rsc - DeleteRegKey HKCR retroshare - - ; Remove program/uninstall regsitry keys - DeleteRegKey HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${APPNAME}" - DeleteRegKey HKLM SOFTWARE\${APPNAME} - - DeleteRegValue HKCU "Software\Microsoft\Windows\CurrentVersion\Run" "RetroRun" - - ; Remove files and uninstaller - Delete $INSTDIR\RetroShare.exe - Delete $INSTDIR\*.dll - Delete $INSTDIR\*.dat - Delete $INSTDIR\*.txt - Delete $INSTDIR\*.ini - Delete $INSTDIR\*.log - - Delete $INSTDIR\uninstall.exe - - ; Remove the kadc.ini file. - ; Don't remove the directory, otherwise - ; we lose the XPGP keys. - ; Should make this an option though... - Delete "$APPDATA\${APPNAME}\kadc.ini" - Delete "$APPDATA\${APPNAME}\*.cfg" - Delete "$APPDATA\${APPNAME}\*.conf" - Delete "$APPDATA\${APPNAME}\*.log-save" - Delete "$APPDATA\${APPNAME}\*.log" - Delete "$APPDATA\${APPNAME}\*.failed" - - RMDir /r "$APPDATA\${APPNAME}\cache" - RMDir /r "$APPDATA\${APPNAME}\Partials" - - ; Remove shortcuts, if any - Delete "$SMPROGRAMS\${APPNAME}\*.*" - - ; Remove desktop shortcut - Delete "$DESKTOP\${APPNAME}.lnk" - - ; Remove Quicklaunch shortcut - Delete "$QUICKLAUNCH\${APPNAME}.lnk" - - ; Remove Autostart - ;Delete "$SMSTARTUP\${APPNAME}.lnk" - - ; Remove directories used - RMDir "$SMPROGRAMS\${APPNAME}" - RMDir /r "$INSTDIR" - RMDir /r "$INSTDIR\qss" - RMDir /r "$INSTDIR\emoticons" - RMDir /r "$INSTDIR\style" - RMDir /r "$INSTDIR\translations" - -SectionEnd - -Function .onInit - - InitPluginsDir - Push $R1 - File /oname=$PLUGINSDIR\spltmp.bmp "gui\images\splash.bmp" - advsplash::show 1200 1000 1000 -1 $PLUGINSDIR\spltmp - Pop $R1 - Pop $R1 - !insertmacro MUI_LANGDLL_DISPLAY - - - -FunctionEnd - - -# Installer Language Strings -# TODO Update the Language Strings with the appropriate translations. - -LangString InstallGPG4WIN ${LANG_ENGLISH} "Install Gpg4win ? Gpg4win is required for RetroShare!" -LangString InstallGPG4WIN ${LANG_GERMAN} "Installiere Gpg4win ? Gpg4win ist erforderlich fuer RetroShare!" -LangString InstallGPG4WIN ${LANG_TURKISH} "Gpg4win Yükle? Gpg4win RetroShare için gerekli!" -LangString InstallGPG4WIN ${LANG_FRENCH} "RetroShare a besoin de GPG4win pour fonctionner. Lancer l'installation de GPG4win?" -LangString InstallGPG4WIN ${LANG_SIMPCHINESE} "Install Gpg4win ? Gpg4win是需要Retroshare!" -LangString InstallGPG4WIN ${LANG_POLISH} "Install Gpg4win ? Gpg4win wymagane jest Retroshare!" -LangString InstallGPG4WIN ${LANG_DANISH} "Installer Gpg4win? Gpg4win er nødvendig for RetroShare!" -LangString InstallGPG4WIN ${LANG_JAPANESE} "Install Gpg4win ? Gpg4win is required for RetroShare!" -LangString InstallGPG4WIN ${LANG_KOREAN} "Install Gpg4win ? Gpg4win is required for RetroShare!" -LangString InstallGPG4WIN ${LANG_RUSSIAN} "Install Gpg4win ? Gpg4win is required for RetroShare!" -LangString InstallGPG4WIN ${LANG_SWEDISH} "Installera Gpg4win? Gpg4win krävs för RetroShare!" - -LangString FINISHPAGELINK ${LANG_ENGLISH} "Visit the RetroShare forums for the latest news and support" -LangString FINISHPAGELINK ${LANG_GERMAN} "Besuche RetroShare Support Forum " -LangString FINISHPAGELINK ${LANG_TURKISH} "Destek için Retroshare foruma ziyaret" -LangString FINISHPAGELINK ${LANG_FRENCH} "Consultez le forum RetroShare pour vous tenir au courant des dernieres modifications, et obtenir de l'aide." -LangString FINISHPAGELINK ${LANG_SIMPCHINESE} "帮助论坛" -LangString FINISHPAGELINK ${LANG_POLISH} "Odwiedź forum RetroShare do najświeższych informacji i wsparcia" -LangString FINISHPAGELINK ${LANG_DANISH} "Besøg RetroShare fora for de seneste nyheder og støtte" -LangString FINISHPAGELINK ${LANG_JAPANESE} "Visit the RetroShare forums for the latest news and support" -LangString FINISHPAGELINK ${LANG_KOREAN} "Visit the RetroShare forums for the latest news and support" -LangString FINISHPAGELINK ${LANG_RUSSIAN} "Visit the RetroShare forums for the latest news and support" -LangString FINISHPAGELINK ${LANG_SWEDISH} "Besök RetroShare forum för de senaste nyheterna och stöd" - -LangString ^UninstallLink ${LANG_ENGLISH} "Uninstall" -LangString ^UninstallLink ${LANG_GERMAN} "Deinstallieren" -LangString ^UninstallLink ${LANG_TURKISH} "Kald�r" -LangString ^UninstallLink ${LANG_FRENCH} "Désinstaller" -LangString ^UninstallLink ${LANG_SIMPCHINESE} "卸载" -LangString ^UninstallLink ${LANG_POLISH} "Odinstaluj" -LangString ^UninstallLink ${LANG_DANISH} "Afinstaller" -LangString ^UninstallLink ${LANG_JAPANESE} "Uninstall" -LangString ^UninstallLink ${LANG_KOREAN} "Uninstall" -LangString ^UninstallLink ${LANG_RUSSIAN} "Uninstall" -LangString ^UninstallLink ${LANG_SWEDISH} "Avinstallera" - - -; eof diff --git a/retroshare-gui/src/retroshare.in b/retroshare-gui/src/retroshare.in deleted file mode 100644 index 994d26d7c..000000000 --- a/retroshare-gui/src/retroshare.in +++ /dev/null @@ -1,594 +0,0 @@ -; Script generated with the Venis Install Wizard & modified by defnax - -; Define your application name -!define APPNAME "RetroShare" -!define VERSION "0.5.4e" -!define REVISION "$WCREV$" -!define APPNAMEANDVERSION "${APPNAME} ${VERSION} ${REVISION}" -!define QTBASE "d:\qt\2010.05" -!define RSBASE "d:\Development\retroshare\retroshare-gui\" - -; Main Install settings -Name "${APPNAMEANDVERSION}" -InstallDir "$PROGRAMFILES\RetroShare" -InstallDirRegKey HKLM "Software\${APPNAME}" "" -OutFile "RetroShare_${VERSION}_${REVISION}_setup.exe" -BrandingText "${APPNAMEANDVERSION}" -; Use compression -SetCompressor /SOLID LZMA - -; Modern interface settings -!include Sections.nsh -!include "MUI.nsh" - -;Interface Settings -!define MUI_ABORTWARNING -;!define MUI_HEADERIMAGE -;!define MUI_HEADERIMAGE_BITMAP "retroshare.bmp" ; optional - -# MUI defines -!define MUI_ICON "${NSISDIR}\Contrib\Graphics\Icons\orange-install.ico" -!define MUI_FINISHPAGE_NOAUTOCLOSE -!define MUI_LICENSEPAGE_RADIOBUTTONS -!define MUI_COMPONENTSPAGE_SMALLDESC -!define MUI_FINISHPAGE_LINK "$(FINISHPAGELINK)" -!define MUI_FINISHPAGE_LINK_LOCATION "http://retroshare.sourceforge.net/forum/" -!define MUI_FINISHPAGE_RUN "$INSTDIR\RetroShare.exe" -!define MUI_FINISHPAGE_SHOWREADME $INSTDIR\changelog.txt -!define MUI_FINISHPAGE_SHOWREADME_TEXT changelog.txt -!define MUI_FINISHPAGE_SHOWREADME_NOTCHECKED -!define MUI_UNICON "${NSISDIR}\Contrib\Graphics\Icons\orange-uninstall.ico" -!define MUI_UNFINISHPAGE_NOAUTOCLOSE -!define MUI_LANGDLL_REGISTRY_ROOT HKLM -!define MUI_LANGDLL_REGISTRY_KEY ${REGKEY} -!define MUI_LANGDLL_REGISTRY_VALUENAME InstallerLanguage - -;!define MUI_WELCOMEPAGE_TEXT "This wizard will guide you through the installation of RetroShare. \r\n\r\nIt is recommended that you close all other applications before starting Setup. This will make it possible to update relevant system files without havinf to reboot your computer. \r\n\r\nIMPORTANT: Ensure that RetroShare is NOT RUNNING before continuing (you can exit from the taskbar menu), otherwise the installer cannot update the executables, and the installation will fail. \r\n\r\nClick Next to continue. " - -;!define MUI_WELCOMEPAGE_TEXT "This wizard will guide you through the installation of RetroShare. \r\n\r\nIMPORTANT: Ensure that RetroShare is NOT RUNNING before continuing (you can exit from the taskbar menu), otherwise the installer cannot update the executables, and the installation will fail. \r\n\r\nClick Next to continue. " - - -; Defines the un-/installer logo of RetroShare -!insertmacro MUI_DEFAULT MUI_WELCOMEFINISHPAGE_BITMAP "${NSISDIR}\Contrib\Graphics\Wizard\orange.bmp" -!insertmacro MUI_DEFAULT MUI_UNWELCOMEFINISHPAGE_BITMAP "${NSISDIR}\Contrib\Graphics\Wizard\orange-uninstall.bmp" - -; Set languages (first is default language) -!insertmacro MUI_RESERVEFILE_LANGDLL -ReserveFile "${NSISDIR}\Plugins\AdvSplash.dll" - -;-------------------------------- -;Configuration - - - ;!insertmacro MUI_RESERVEFILE_SPECIALBITMAP - - LicenseLangString myLicenseData 1030 "license\license.txt" - LicenseLangString myLicenseData 1031 "license\license-GER.txt" - LicenseLangString myLicenseData 1032 "license\license-GR.txt" - LicenseLangString myLicenseData 1033 "license\license.txt" - LicenseLangString myLicenseData 1034 "license\license-SP.txt" - LicenseLangString myLicenseData 1036 "license\license-FR.txt" - LicenseLangString myLicenseData 1040 "license\license-IT.txt" - LicenseLangString myLicenseData 1041 "license\license.txt" - LicenseLangString myLicenseData 1042 "license\license.txt" - LicenseLangString myLicenseData 1045 "license\license.txt" - LicenseLangString myLicenseData 1046 "license\license-PT_BR.txt" - LicenseLangString myLicenseData 1049 "license\license.txt" - LicenseLangString myLicenseData 1053 "license\license.txt" - LicenseLangString myLicenseData 1055 "license\license-TR.txt" - LicenseLangString myLicenseData 2052 "license\license.txt" - - LicenseData $(myLicenseData) - -# Installer pages -!insertmacro MUI_PAGE_WELCOME -!insertmacro MUI_PAGE_LICENSE "$(myLicenseData)" -!insertmacro MUI_PAGE_COMPONENTS -!insertmacro MUI_PAGE_DIRECTORY -!insertmacro MUI_PAGE_INSTFILES -!insertmacro MUI_PAGE_FINISH -!insertmacro MUI_UNPAGE_CONFIRM -!insertmacro MUI_UNPAGE_INSTFILES - -# Installer languages -!define MUI_LANGDLL_ALLLANGUAGES - -!insertmacro MUI_LANGUAGE English -!insertmacro MUI_LANGUAGE Danish -!insertmacro MUI_LANGUAGE French -!insertmacro MUI_LANGUAGE German -!insertmacro MUI_LANGUAGE Greek -!insertmacro MUI_LANGUAGE Italian -!insertmacro MUI_LANGUAGE Japanese -!insertmacro MUI_LANGUAGE Korean -!insertmacro MUI_LANGUAGE Polish -!insertmacro MUI_LANGUAGE PortugueseBR -!insertmacro MUI_LANGUAGE Russian -!insertmacro MUI_LANGUAGE Swedish -!insertmacro MUI_LANGUAGE SimpChinese -!insertmacro MUI_LANGUAGE Spanish -!insertmacro MUI_LANGUAGE Turkish - - - ;Component-selection page - ;Titles - - LangString sec_main ${LANG_ENGLISH} "Program Files" - LangString sec_data ${LANG_ENGLISH} "Program Skins" - LangString sec_shortcuts ${LANG_ENGLISH} "Shortcuts" - LangString sec_plugins ${LANG_ENGLISH} "Plugins" - LangString sec_link ${LANG_ENGLISH} "File Association" - LangString sec_autostart ${LANG_ENGLISH} "Auto Startup" - LangString DESC_sec_main ${LANG_ENGLISH} "Installs the RetroShare program files." - LangString DESC_sec_plugins ${LANG_ENGLISH} "Installs the RetroShare plugins." - LangString DESC_sec_data ${LANG_ENGLISH} "Installs RetroShare Skins" - LangString DESC_sec_shortcuts ${LANG_ENGLISH} "Create RetroShare shortcut icons." - LangString DESC_sec_link ${LANG_ENGLISH} "Associate RetroShare with .rsc file extension" - LangString LANGUAGEID ${LANG_ENGLISH} "1033" - - LangString sec_main ${LANG_FRENCH} "RetroShare" - LangString sec_data ${LANG_FRENCH} "Programme de Skins" - LangString sec_plugins ${LANG_FRENCH} "Plugins" - LangString sec_shortcuts ${LANG_FRENCH} "Raccourcis" - LangString sec_link ${LANG_FRENCH} "Association de fichiers" - LangString sec_startmenu ${LANG_FRENCH} "Raccourcis du menu Démarrer" - LangString sec_autostart ${LANG_FRENCH} "Démarrage automatique" - LangString DESC_sec_main ${LANG_FRENCH} "Installation des fichiers du programme." - LangString DESC_sec_data ${LANG_FRENCH} "Installation des Skins de RetroShare" - LangString DESC_sec_plugins ${LANG_FRENCH} "Installation des extensions de RetroShare " - LangString DESC_sec_startmenu ${LANG_FRENCH} "Création des raccourcis du menu Démarrer" - LangString DESC_sec_shortcuts ${LANG_FRENCH} "Création de l'icône sur le bureau." - LangString DESC_sec_link ${LANG_FRENCH} "Associer RetroShare avec l'extension de fichier .rsc" - LangString LANGUAGEID ${LANG_FRENCH} "1036" - - LangString sec_main ${LANG_GERMAN} "Programme" - LangString sec_data ${LANG_GERMAN} "Programm Skins" - LangString sec_plugins ${LANG_GERMAN} "Plug-ins" - LangString sec_shortcuts ${LANG_GERMAN} "Verknüpfungen" - LangString sec_link ${LANG_GERMAN} "Dateiverknüpfungen" - LangString sec_autostart ${LANG_GERMAN} "Autostart" - LangString DESC_sec_main ${LANG_GERMAN} "Installiert die RetroShare Programmdateien." - LangString DESC_sec_data ${LANG_GERMAN} "Installiert RetroShare Skins" - LangString DESC_sec_plugins ${LANG_GERMAN} "Installiert die RetroShare Erweiterungen." - LangString DESC_sec_shortcuts ${LANG_GERMAN} "RetroShare Verknüpfung im Startmenüe, Desktop oder im Schnellstarter erstellen." - LangString DESC_sec_link ${LANG_GERMAN} "RetroShare mit .rsc Dateiendung verknüpfen" - LangString LANGUAGEID ${LANG_GERMAN} "1031" - - LangString sec_main ${LANG_TURKISH} "Program Dosyalar?" - LangString sec_data ${LANG_TURKISH} "Program Skinleri" - LangString sec_shortcuts ${LANG_TURKISH} "Shortcut'lar" - LangString sec_plugins ${LANG_TURKISH} "Eklentiler" - LangString sec_link ${LANG_TURKISH} ".rsc Dosya Kaydet" - LangString sec_autostart ${LANG_TURKISH} "Otomatik calistir ve baglan" - LangString DESC_sec_main ${LANG_TURKISH} "Program dosyalar?n? kurar." - LangString DESC_sec_data ${LANG_TURKISH} "RetroShare Skin'leri kurar" - LangString DESC_sec_plugins ${LANG_TURKISH} "Installs the RetroShare plugins." - LangString DESC_sec_shortcuts ${TURKISH} "Shortcut yap Start menu , Desktop veya Quicklaunchbar icin." - LangString DESC_sec_link ${LANG_TURKISH} "RetroShare .rsc almas? i?in kaydettirir" - LangString LANGUAGEID ${LANG_TURKISH} "1055" - - LangString sec_main ${LANG_SIMPCHINESE} "程序文件" - LangString sec_data ${LANG_SIMPCHINESE} "程序皮肤" - LangString sec_plugins ${LANG_SIMPCHINESE} "Plugins" - LangString sec_shortcuts ${LANG_SIMPCHINESE} "快捷方式" - LangString sec_link ${LANG_SIMPCHINESE} "RetroShare文件关联" - LangString sec_autostart ${LANG_SIMPCHINESE} "自动启动" - LangString DESC_sec_main ${LANG_SIMPCHINESE} "安装RetroShare程序" - LangString DESC_sec_data ${LANG_SIMPCHINESE} "安装RetroShare皮肤" - LangString DESC_sec_plugins ${LANG_SIMPCHINESE} "Installs the RetroShare plugins." - LangString DESC_sec_shortcuts ${LANG_SIMPCHINESE} "建RetroShare快捷方式" - LangString DESC_sec_link ${LANG_SIMPCHINESE} "关联.rsc扩展名" - LangString LANGUAGEID ${LANG_SIMPCHINESE} "2052" - - LangString sec_main ${LANG_POLISH} "Pliki programu" - LangString sec_data ${LANG_POLISH} "Skórki" - LangString sec_plugins ${LANG_POLISH} "Plugins" - LangString sec_shortcuts ${LANG_POLISH} "Skróty" - LangString sec_link ${LANG_POLISH} "Skojarz pliki" - LangString sec_autostart ${LANG_POLISH} "Automatyczne uruchamianie" - LangString DESC_sec_main ${LANG_POLISH} "Instaluje pliki programu RetroShare" - LangString DESC_sec_data ${LANG_POLISH} "Instaluje skórki programu RetroShare" - LangString DESC_sec_plugins ${LANG_POLISH} "Installs the RetroShare plugins." - LangString DESC_sec_shortcuts ${LANG_POLISH} "Utwórz ikony skrótów na pulpicie, w menu start oraz na pasku szybkiego uruchamiania." - LangString DESC_sec_link ${LANG_POLISH} "Skojarz pliki o rozszerzeniu .rsc z RetroShare" - LangString LANGUAGEID ${LANG_POLISH} "1045" - - LangString sec_main ${LANG_DANISH} "Program Files" - LangString sec_data ${LANG_DANISH} "Program Skins" - LangString sec_plugins ${LANG_DANISH} "Plugins" - LangString sec_shortcuts ${LANG_DANISH} "Shortcuts" - LangString sec_link ${LANG_DANISH} "File Association" - LangString sec_autostart ${LANG_DANISH} "Auto Startup" - LangString DESC_sec_main ${LANG_DANISH} "Installs the RetroShare program files." - LangString DESC_sec_data ${LANG_DANISH} "Installs RetroShare Skins" - LangString DESC_sec_plugins ${LANG_DANISH} "Installs the RetroShare plugins." - LangString DESC_sec_shortcuts ${LANG_DANISH} "Create RetroShare shortcut icons." - LangString DESC_sec_link ${LANG_DANISH} "Associate RetroShare with .rsc file extension" - LangString LANGUAGEID ${LANG_DANISH} "1030" - - LangString sec_main ${LANG_RUSSIAN} "Program Files" - LangString sec_data ${LANG_RUSSIAN} "Program Skins" - LangString sec_plugins ${LANG_RUSSIAN} "Plugins" - LangString sec_shortcuts ${LANG_RUSSIAN} "Shortcuts" - LangString sec_link ${LANG_RUSSIAN} "File Association" - LangString sec_autostart ${LANG_RUSSIAN} "Auto Startup" - LangString DESC_sec_main ${LANG_RUSSIAN} "Installs the RetroShare program files." - LangString DESC_sec_data ${LANG_RUSSIAN} "Installs RetroShare Skins" - LangString DESC_sec_plugins ${LANG_RUSSIAN} "Installs the RetroShare plugins." - LangString DESC_sec_shortcuts ${LANG_RUSSIAN} "Create RetroShare shortcut icons." - LangString DESC_sec_link ${LANG_RUSSIAN} "Associate RetroShare with .rsc file extension" - LangString LANGUAGEID ${LANG_RUSSIAN} "1049" - - LangString sec_main ${LANG_SWEDISH} "Program Files" - LangString sec_data ${LANG_SWEDISH} "Program Skins" - LangString sec_plugins ${LANG_SWEDISH} "Plugins" - LangString sec_shortcuts ${LANG_SWEDISH} "Shortcuts" - LangString sec_link ${LANG_SWEDISH} "File Association" - LangString sec_autostart ${LANG_SWEDISH} "Auto Startup" - LangString DESC_sec_main ${LANG_SWEDISH} "Installs the RetroShare program files." - LangString DESC_sec_data ${LANG_SWEDISH} "Installs RetroShare Skins" - LangString DESC_sec_plugins ${LANG_SWEDISH} "Installs the RetroShare plugins." - LangString DESC_sec_shortcuts ${LANG_SWEDISH} "Create RetroShare shortcut icons." - LangString DESC_sec_link ${LANG_SWEDISH} "Associate RetroShare with .rsc file extension" - LangString LANGUAGEID ${LANG_SWEDISH} "1053" - - LangString sec_main ${LANG_SPANISH} "Archivos de programa" - LangString sec_data ${LANG_SPANISH} "Estilos del programa" - LangString sec_plugins ${LANG_SPANISH} "Plugins" - LangString sec_shortcuts ${LANG_SPANISH} "Accesos directos" - LangString sec_link ${LANG_SPANISH} "Asociación de archivos" - LangString sec_autostart ${LANG_SPANISH} "Inicio automático" - LangString DESC_sec_main ${LANG_SPANISH} "Instala los archivos del programa RetroShare." - LangString DESC_sec_data ${LANG_SPANISH} "Instala los estilos para RetroShare" - LangString DESC_sec_plugins ${LANG_SPANISH} "Installs the RetroShare plugins." - LangString DESC_sec_shortcuts ${LANG_SPANISH} "Crear iconos de acceso directo de RetroShare." - LangString DESC_sec_link ${LANG_SPANISH} "Asociar RetroShare con la extensión de archivo .rsc" - LangString LANGUAGEID ${LANG_SPANISH} "1034" - - LangString sec_main ${LANG_ITALIAN} "Programmi" - LangString sec_data ${LANG_ITALIAN} "Temi del Programma" - LangString sec_plugins ${LANG_ITALIAN} "Plugins" - LangString sec_shortcuts ${LANG_ITALIAN} "Icone" - LangString sec_link ${LANG_ITALIAN} "Associazione dei File" - LangString sec_autostart ${LANG_ITALIAN} "Esecuzione Automatica" - LangString DESC_sec_main ${LANG_ITALIAN} "Installare i file programma di RetroShare." - LangString DESC_sec_data ${LANG_ITALIAN} "Installare i temi di RetroShare" - LangString DESC_sec_plugins ${LANG_ITALIAN} "Installs the RetroShare plugins." - LangString DESC_sec_shortcuts ${LANG_ITALIAN} "Creare le icone per avviare RetroShare." - LangString DESC_sec_link ${LANG_ITALIAN} "Associa a RetroShare i file con estensione .rsc" - LangString LANGUAGEID ${LANG_ITALIAN} "1040" - - LangString sec_main ${LANG_GREEK} "Program Files" - LangString sec_data ${LANG_GREEK} "Program Skins" - LangString sec_plugins ${LANG_GREEK} "Plugins" - LangString sec_shortcuts ${LANG_GREEK} "Shortcuts" - LangString sec_link ${LANG_GREEK} "File Association" - LangString sec_autostart ${LANG_GREEK} "Auto Startup" - LangString DESC_sec_main ${LANG_GREEK} "Installs the RetroShare program files." - LangString DESC_sec_data ${LANG_GREEK} "Installs RetroShare Skins" - LangString DESC_sec_plugins ${LANG_GREEK} "Installs the RetroShare plugins." - LangString DESC_sec_shortcuts ${LANG_GREEK} "Create RetroShare shortcut icons." - LangString DESC_sec_link ${LANG_GREEK} "Associate RetroShare with .rsc file extension" - LangString LANGUAGEID ${LANG_GREEK} "1032" - - LangString sec_main ${LANG_PORTUGUESEBR} "Program Files" - LangString sec_data ${LANG_PORTUGUESEBR} "Program Skins" - LangString sec_plugins ${LANG_PORTUGUESEBR} "Plugins" - LangString sec_shortcuts ${LANG_PORTUGUESEBR} "Shortcuts" - LangString sec_link ${LANG_PORTUGUESEBR} "File Association" - LangString sec_autostart ${LANG_PORTUGUESEBR} "Auto Startup" - LangString DESC_sec_main ${LANG_PORTUGUESEBR} "Installs the RetroShare program files." - LangString DESC_sec_data ${LANG_PORTUGUESEBR} "Installs RetroShare Skins" - LangString DESC_sec_plugins ${LANG_PORTUGUESEBR} "Installs the RetroShare plugins." - LangString DESC_sec_shortcuts ${LANG_PORTUGUESEBR} "Create RetroShare shortcut icons." - LangString DESC_sec_link ${LANG_PORTUGUESEBR} "Associate RetroShare with .rsc file extension" - LangString LANGUAGEID ${LANG_PORTUGUESEBR} "1046" - - LangString sec_main ${LANG_JAPANESE} "Program Files" - LangString sec_data ${LANG_JAPANESE} "Program Skins" - LangString sec_plugins ${LANG_JAPANESE} "Plugins" - LangString sec_shortcuts ${LANG_JAPANESE} "Shortcuts" - LangString sec_link ${LANG_JAPANESE} "File Association" - LangString sec_autostart ${LANG_JAPANESE} "Auto Startup" - LangString DESC_sec_main ${LANG_JAPANESE} "Installs the RetroShare program files." - LangString DESC_sec_data ${LANG_JAPANESE} "Installs RetroShare Skins" - LangString DESC_sec_plugins ${LANG_JAPANESE} "Installs the RetroShare plugins." - LangString DESC_sec_shortcuts ${LANG_JAPANESE} "Create RetroShare shortcut icons." - LangString DESC_sec_link ${LANG_JAPANESE} "Associate RetroShare with .rsc file extension" - LangString LANGUAGEID ${LANG_JAPANESE} "1041" - - LangString sec_main ${LANG_KOREAN} "Program Files" - LangString sec_data ${LANG_KOREAN} "Program Skins" - LangString sec_plugins ${LANG_KOREAN} "Plugins" - LangString sec_shortcuts ${LANG_KOREAN} "Shortcuts" - LangString sec_link ${LANG_KOREAN} "File Association" - LangString sec_autostart ${LANG_KOREAN} "Auto Startup" - LangString DESC_sec_main ${LANG_KOREAN} "Installs the RetroShare program files." - LangString DESC_sec_data ${LANG_KOREAN} "Installs RetroShare Skins" - LangString DESC_sec_plugins ${LANG_KOREAN} "Installs the RetroShare plugins." - LangString DESC_sec_shortcuts ${LANG_KOREAN} "Create RetroShare shortcut icons." - LangString DESC_sec_link ${LANG_KOREAN} "Associate RetroShare with .rsc file extension" - LangString LANGUAGEID ${LANG_KOREAN} "1042" - - -!insertmacro MUI_RESERVEFILE_INSTALLOPTIONS - -Section $(sec_main) sec_main - - ;Set Section required - SectionIn RO - - ; Set Section properties - SetOverwrite on - - ; Clears previous error logs - Delete "$INSTDIR\*.log" - - ; Set Section Files and Shortcuts - SetOutPath "$INSTDIR\" - File /r "release\RetroShare.exe" - File /r "..\..\retroshare-nogui\src\release\retroshare-nogui.exe" - File /r "${QTBASE}\mingw\bin\mingwm10.dll" - File /r "${QTBASE}\qt\bin\QtCore4.dll" - File /r "${QTBASE}\qt\bin\QtGui4.dll" - File /r "${QTBASE}\qt\bin\QtNetwork4.dll" - File /r "${QTBASE}\qt\bin\QtMultimedia4.dll" - File /r "${QTBASE}\qt\bin\QtXml4.dll" - File /r "${QTBASE}\qt\bin\QtScript4.dll" - File /r "${QTBASE}\qt\bin\QtSvg4.dll" - File /r "${QTBASE}\qt\bin\libgcc_s_dw2-1.dll" - File /r "${QTBASE}\qt\plugins\imageformats" - File /r ${QTBASE}\qt\qt_*.qm - File /r ${RSBASE}\src\qt_*.qm - File /r "release\pthreadGC2d.dll" - File /r "d:\Development\lib\libminiupnpc-1.3\miniupnpc.dll" - File /r "changelog.txt" - File /r /x Data "release\bdboot.txt" - - -SectionEnd - -Section $(sec_data) sec_data - - ; Set Section properties - SetOverwrite on - - ; Set Section Files and Shortcuts - SetOutPath "$APPDATA\RetroShare\" - ;File /r "data\*" - - ; Set Section qss and exclude svn - SetOutPath "$INSTDIR\qss\" - File /r /x .svn qss\*.* - - ; Set Section sounds and exclude svn - SetOutPath "$INSTDIR\sounds\" - File /r /x .svn sounds\*.* - - ; Set Section skin - ; SetOutPath "$INSTDIR\skin\" - ; File /r release\skin\*.* - - ; Add emoticons - ;SetOutPath "$INSTDIR\emoticons\" - ;File /r emoticons\*.* - - ; Add Chat Style - SetOutPath "$APPDATA\RetroShare\stylesheets\" - File /r gui\qss\chat\Bubble - File /r gui\qss\chat\Bubble_Compact - - -SectionEnd - -SectionGroup $(sec_plugins) sec_plugins -Section Voip SEC001 - - ; Set Section properties - SetOverwrite on - - ; Set Section Plugins - SetOutPath "$APPDATA\RetroShare\extensions\" - - File /r "..\..\plugins\VOIP\release\VOIP.dll" - -SectionEnd - -Section FeedReader SEC002 - - ; Set Section properties - SetOverwrite on - - ; Set Section Plugins - SetOutPath "$APPDATA\RetroShare\extensions\" - - File /r "..\..\plugins\FeedReader\release\FeedReader.dll" - -SectionEnd -SectionGroupEnd - -Section $(sec_link) sec_link - ; Delete any existing keys - - - ; Write the file association - WriteRegStr HKCR .rsc "" retroshare - WriteRegStr HKCR retroshare "" "RSC File" - WriteRegBin HKCR retroshare EditFlags 00000100 - WriteRegStr HKCR "retroshare\shell" "" open - WriteRegStr HKCR "retroshare\shell\open\command" "" `"$INSTDIR\RetroShare.exe" "%1"` - -SectionEnd - -SectionGroup $(sec_shortcuts) sec_shortcuts -Section StartMenu SEC0001 - - SetOutPath "$INSTDIR" - CreateDirectory "$SMPROGRAMS\${APPNAME}" - CreateShortCut "$SMPROGRAMS\${APPNAME}\${APPNAME}.lnk" "$INSTDIR\RetroShare.exe" "" "$INSTDIR\RetroShare.exe" 0 - CreateShortCut "$SMPROGRAMS\${APPNAME}\$(^UninstallLink).lnk" "$INSTDIR\uninstall.exe" "" "$INSTDIR\uninstall.exe" 0 - -SectionEnd - -Section Desktop SEC0002 - - - CreateShortCut "$DESKTOP\${APPNAME}.lnk" "$INSTDIR\RetroShare.exe" "" "$INSTDIR\RetroShare.exe" 0 - -SectionEnd - -Section Quicklaunchbar SEC0003 - - - CreateShortCut "$QUICKLAUNCH\${APPNAME}.lnk" "$INSTDIR\RetroShare.exe" "" "$INSTDIR\RetroShare.exe" 0 - -SectionEnd -SectionGroupEnd - -;Section $(sec_autostart) sec_autostart - -; WriteRegStr HKCU "Software\Microsoft\Windows\CurrentVersion\Run" "RetroRun" "$INSTDIR\${APPNAME}.exe -a" - -;SectionEnd - -;Section $(sec_autostart) sec_autostart - -; CreateShortCut "$SMSTARTUP\${APPNAME}.lnk" "$INSTDIR\RetroShare.exe" "" "$INSTDIR\RetroShare.exe" 0 -;SectionEnd - - -Section -FinishSection - - WriteRegStr HKLM "Software\${APPNAME}" "" "$INSTDIR" - WriteRegStr HKLM "Software\${APPNAME}" "Version" "${VERSION}" - WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${APPNAME}" "DisplayName" "${APPNAME}" - WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${APPNAME}" "UninstallString" "$INSTDIR\uninstall.exe" - WriteUninstaller "$INSTDIR\uninstall.exe" - -SectionEnd - - - -;-------------------------------- -;Descriptions - -!insertmacro MUI_FUNCTION_DESCRIPTION_BEGIN - !insertmacro MUI_DESCRIPTION_TEXT ${sec_main} $(DESC_sec_main) - !insertmacro MUI_DESCRIPTION_TEXT ${sec_data} $(DESC_sec_data) - !insertmacro MUI_DESCRIPTION_TEXT ${sec_plugins} $(DESC_sec_plugins) - !insertmacro MUI_DESCRIPTION_TEXT ${sec_shortcuts} $(DESC_sec_shortcuts) - !insertmacro MUI_DESCRIPTION_TEXT ${sec_link} $(DESC_sec_link) - ;!insertmacro MUI_DESCRIPTION_TEXT ${sec_autostart} $(DESC_sec_autostart) -!insertmacro MUI_FUNCTION_DESCRIPTION_END - -;Uninstall section -Section "Uninstall" - - ; Remove file association registry keys - DeleteRegKey HKCR .rsc - DeleteRegKey HKCR retroshare - - ; Remove program/uninstall regsitry keys - DeleteRegKey HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${APPNAME}" - DeleteRegKey HKLM SOFTWARE\${APPNAME} - - DeleteRegValue HKCU "Software\Microsoft\Windows\CurrentVersion\Run" "RetroRun" - - ; Remove files and uninstaller - Delete $INSTDIR\RetroShare.exe - Delete $INSTDIR\*.dll - Delete $INSTDIR\*.dat - Delete $INSTDIR\*.txt - Delete $INSTDIR\*.ini - Delete $INSTDIR\*.log - - Delete $INSTDIR\uninstall.exe - - ; Remove the kadc.ini file. - ; Don't remove the directory, otherwise - ; we lose the XPGP keys. - ; Should make this an option though... - Delete "$APPDATA\${APPNAME}\kadc.ini" - Delete "$APPDATA\${APPNAME}\*.cfg" - Delete "$APPDATA\${APPNAME}\*.conf" - Delete "$APPDATA\${APPNAME}\*.log-save" - Delete "$APPDATA\${APPNAME}\*.log" - Delete "$APPDATA\${APPNAME}\*.failed" - - RMDir /r "$APPDATA\${APPNAME}\cache" - RMDir /r "$APPDATA\${APPNAME}\Partials" - - ; Remove shortcuts, if any - Delete "$SMPROGRAMS\${APPNAME}\*.*" - - ; Remove desktop shortcut - Delete "$DESKTOP\${APPNAME}.lnk" - - ; Remove Quicklaunch shortcut - Delete "$QUICKLAUNCH\${APPNAME}.lnk" - - ; Remove Autostart - ;Delete "$SMSTARTUP\${APPNAME}.lnk" - - ; Remove directories used - RMDir "$SMPROGRAMS\${APPNAME}" - RMDir /r "$INSTDIR" - RMDir /r "$INSTDIR\qss" - RMDir /r "$INSTDIR\emoticons" - RMDir /r "$INSTDIR\style" - RMDir /r "$INSTDIR\translations" - -SectionEnd - -Function .onInit - - InitPluginsDir - Push $R1 - File /oname=$PLUGINSDIR\spltmp.bmp "gui\images\splash.bmp" - advsplash::show 1200 1000 1000 -1 $PLUGINSDIR\spltmp - Pop $R1 - Pop $R1 - !insertmacro MUI_LANGDLL_DISPLAY - - - -FunctionEnd - - -# Installer Language Strings -# TODO Update the Language Strings with the appropriate translations. - - -LangString FINISHPAGELINK ${LANG_ENGLISH} "Visit the RetroShare forums for the latest news and support" -LangString FINISHPAGELINK ${LANG_GERMAN} "Das RetroShare Support-Forum besuchen, um Neuigkeiten und Unterstützung zu erfahren" -LangString FINISHPAGELINK ${LANG_TURKISH} "Destek için Retroshare foruma ziyaret et" -LangString FINISHPAGELINK ${LANG_FRENCH} "Consultez le forum RetroShare pour vous tenir au courant des dernieres modifications, et obtenir de l'aide." -LangString FINISHPAGELINK ${LANG_SIMPCHINESE} "帮助论坛" -LangString FINISHPAGELINK ${LANG_POLISH} "Odwiedź forum RetroShare do najświeższych informacji i wsparcia" -LangString FINISHPAGELINK ${LANG_DANISH} "Besøg RetroShare fora for de seneste nyheder og støtte" -LangString FINISHPAGELINK ${LANG_JAPANESE} "Visit the RetroShare forums for the latest news and support" -LangString FINISHPAGELINK ${LANG_KOREAN} "Visit the RetroShare forums for the latest news and support" -LangString FINISHPAGELINK ${LANG_RUSSIAN} "Visit the RetroShare forums for the latest news and support" -LangString FINISHPAGELINK ${LANG_SWEDISH} "Besök RetroShare forum för de senaste nyheterna och stöd" -LangString FINISHPAGELINK ${LANG_SPANISH} "Visite los foros de RetroShare para las últimas noticias y soporte" -LangString FINISHPAGELINK ${LANG_ITALIAN} "Visita i forum di RetroShare per le ultime novità ed il supporto" -LangString FINISHPAGELINK ${LANG_GREEK} "Visit the RetroShare forums for the latest news and support" -LangString FINISHPAGELINK ${LANG_PORTUGUESEBR} "Visit the RetroShare forums for the latest news and support" - -LangString ^UninstallLink ${LANG_ENGLISH} "Uninstall" -LangString ^UninstallLink ${LANG_GERMAN} "Deinstallieren" -LangString ^UninstallLink ${LANG_TURKISH} "Kald�r" -LangString ^UninstallLink ${LANG_FRENCH} "Désinstaller" -LangString ^UninstallLink ${LANG_SIMPCHINESE} "卸载" -LangString ^UninstallLink ${LANG_POLISH} "Odinstaluj" -LangString ^UninstallLink ${LANG_DANISH} "Afinstaller" -LangString ^UninstallLink ${LANG_JAPANESE} "Uninstall" -LangString ^UninstallLink ${LANG_KOREAN} "Uninstall" -LangString ^UninstallLink ${LANG_RUSSIAN} "Uninstall" -LangString ^UninstallLink ${LANG_SWEDISH} "Avinstallera" -LangString ^UninstallLink ${LANG_SPANISH} "Desinstalar" -LangString ^UninstallLink ${LANG_ITALIAN} "Disinstallare" -LangString ^UninstallLink ${LANG_GREEK} "Απεγκατάσταση" -LangString ^UninstallLink ${LANG_PORTUGUESEBR} "Desinstalar" - -; eof diff --git a/retroshare-gui/src/retroshare.nsi b/retroshare-gui/src/retroshare.nsi deleted file mode 100644 index 9a604b44a..000000000 --- a/retroshare-gui/src/retroshare.nsi +++ /dev/null @@ -1,595 +0,0 @@ -; Script generated with the Venis Install Wizard & modified by defnax - -; Define your application name -!define APPNAME "RetroShare" -!define VERSION "0.5.5a" -!define REVISION "6725" -!define APPNAMEANDVERSION "${APPNAME} ${VERSION} ${REVISION}" -!define QTBASE "h:\qt\2010.05" -!define RSBASE "h:\Development\retroshare\retroshare-gui\" - -; Main Install settings -Name "${APPNAMEANDVERSION}" -InstallDir "$PROGRAMFILES\RetroShare" -InstallDirRegKey HKLM "Software\${APPNAME}" "" -OutFile "RetroShare_${VERSION}_${REVISION}_setup.exe" -BrandingText "${APPNAMEANDVERSION}" -; Use compression -SetCompressor /SOLID LZMA - -; Modern interface settings -!include Sections.nsh -!include "MUI.nsh" - -;Interface Settings -!define MUI_ABORTWARNING -;!define MUI_HEADERIMAGE -;!define MUI_HEADERIMAGE_BITMAP "retroshare.bmp" ; optional - -# MUI defines -!define MUI_ICON "${NSISDIR}\Contrib\Graphics\Icons\orange-install.ico" -!define MUI_FINISHPAGE_NOAUTOCLOSE -!define MUI_LICENSEPAGE_RADIOBUTTONS -!define MUI_COMPONENTSPAGE_SMALLDESC -!define MUI_FINISHPAGE_LINK "$(FINISHPAGELINK)" -!define MUI_FINISHPAGE_LINK_LOCATION "http://retroshare.sourceforge.net/forum/" -!define MUI_FINISHPAGE_RUN "$INSTDIR\RetroShare.exe" -!define MUI_FINISHPAGE_SHOWREADME $INSTDIR\changelog.txt -!define MUI_FINISHPAGE_SHOWREADME_TEXT changelog.txt -!define MUI_FINISHPAGE_SHOWREADME_NOTCHECKED -!define MUI_UNICON "${NSISDIR}\Contrib\Graphics\Icons\orange-uninstall.ico" -!define MUI_UNFINISHPAGE_NOAUTOCLOSE -!define MUI_LANGDLL_REGISTRY_ROOT HKLM -!define MUI_LANGDLL_REGISTRY_KEY ${REGKEY} -!define MUI_LANGDLL_REGISTRY_VALUENAME InstallerLanguage - -;!define MUI_WELCOMEPAGE_TEXT "This wizard will guide you through the installation of RetroShare. \r\n\r\nIt is recommended that you close all other applications before starting Setup. This will make it possible to update relevant system files without havinf to reboot your computer. \r\n\r\nIMPORTANT: Ensure that RetroShare is NOT RUNNING before continuing (you can exit from the taskbar menu), otherwise the installer cannot update the executables, and the installation will fail. \r\n\r\nClick Next to continue. " - -;!define MUI_WELCOMEPAGE_TEXT "This wizard will guide you through the installation of RetroShare. \r\n\r\nIMPORTANT: Ensure that RetroShare is NOT RUNNING before continuing (you can exit from the taskbar menu), otherwise the installer cannot update the executables, and the installation will fail. \r\n\r\nClick Next to continue. " - - -; Defines the un-/installer logo of RetroShare -!insertmacro MUI_DEFAULT MUI_WELCOMEFINISHPAGE_BITMAP "${NSISDIR}\Contrib\Graphics\Wizard\orange.bmp" -!insertmacro MUI_DEFAULT MUI_UNWELCOMEFINISHPAGE_BITMAP "${NSISDIR}\Contrib\Graphics\Wizard\orange-uninstall.bmp" - -; Set languages (first is default language) -!insertmacro MUI_RESERVEFILE_LANGDLL -ReserveFile "${NSISDIR}\Plugins\AdvSplash.dll" - -;-------------------------------- -;Configuration - - - ;!insertmacro MUI_RESERVEFILE_SPECIALBITMAP - - LicenseLangString myLicenseData 1030 "license\license.txt" - LicenseLangString myLicenseData 1031 "license\license-GER.txt" - LicenseLangString myLicenseData 1032 "license\license-GR.txt" - LicenseLangString myLicenseData 1033 "license\license.txt" - LicenseLangString myLicenseData 1034 "license\license-SP.txt" - LicenseLangString myLicenseData 1036 "license\license-FR.txt" - LicenseLangString myLicenseData 1040 "license\license-IT.txt" - LicenseLangString myLicenseData 1041 "license\license.txt" - LicenseLangString myLicenseData 1042 "license\license.txt" - LicenseLangString myLicenseData 1045 "license\license.txt" - LicenseLangString myLicenseData 1046 "license\license-PT_BR.txt" - LicenseLangString myLicenseData 1049 "license\license.txt" - LicenseLangString myLicenseData 1053 "license\license.txt" - LicenseLangString myLicenseData 1055 "license\license-TR.txt" - LicenseLangString myLicenseData 2052 "license\license.txt" - - LicenseData $(myLicenseData) - -# Installer pages -!insertmacro MUI_PAGE_WELCOME -!insertmacro MUI_PAGE_LICENSE "$(myLicenseData)" -!insertmacro MUI_PAGE_COMPONENTS -!insertmacro MUI_PAGE_DIRECTORY -!insertmacro MUI_PAGE_INSTFILES -!insertmacro MUI_PAGE_FINISH -!insertmacro MUI_UNPAGE_CONFIRM -!insertmacro MUI_UNPAGE_INSTFILES - -# Installer languages -!define MUI_LANGDLL_ALLLANGUAGES - -!insertmacro MUI_LANGUAGE English -!insertmacro MUI_LANGUAGE Danish -!insertmacro MUI_LANGUAGE French -!insertmacro MUI_LANGUAGE German -!insertmacro MUI_LANGUAGE Greek -!insertmacro MUI_LANGUAGE Italian -!insertmacro MUI_LANGUAGE Japanese -!insertmacro MUI_LANGUAGE Korean -!insertmacro MUI_LANGUAGE Polish -!insertmacro MUI_LANGUAGE PortugueseBR -!insertmacro MUI_LANGUAGE Russian -!insertmacro MUI_LANGUAGE Swedish -!insertmacro MUI_LANGUAGE SimpChinese -!insertmacro MUI_LANGUAGE Spanish -!insertmacro MUI_LANGUAGE Turkish - - - ;Component-selection page - ;Titles - - LangString sec_main ${LANG_ENGLISH} "Program Files" - LangString sec_data ${LANG_ENGLISH} "Program Skins" - LangString sec_shortcuts ${LANG_ENGLISH} "Shortcuts" - LangString sec_plugins ${LANG_ENGLISH} "Plugins" - LangString sec_link ${LANG_ENGLISH} "File Association" - LangString sec_autostart ${LANG_ENGLISH} "Auto Startup" - LangString DESC_sec_main ${LANG_ENGLISH} "Installs the RetroShare program files." - LangString DESC_sec_plugins ${LANG_ENGLISH} "Installs the RetroShare plugins." - LangString DESC_sec_data ${LANG_ENGLISH} "Installs RetroShare Skins" - LangString DESC_sec_shortcuts ${LANG_ENGLISH} "Create RetroShare shortcut icons." - LangString DESC_sec_link ${LANG_ENGLISH} "Associate RetroShare with .rsc file extension" - LangString LANGUAGEID ${LANG_ENGLISH} "1033" - - LangString sec_main ${LANG_FRENCH} "RetroShare" - LangString sec_data ${LANG_FRENCH} "Programme de Skins" - LangString sec_plugins ${LANG_FRENCH} "Plugins" - LangString sec_shortcuts ${LANG_FRENCH} "Raccourcis" - LangString sec_link ${LANG_FRENCH} "Association de fichiers" - LangString sec_startmenu ${LANG_FRENCH} "Raccourcis du menu Démarrer" - LangString sec_autostart ${LANG_FRENCH} "Démarrage automatique" - LangString DESC_sec_main ${LANG_FRENCH} "Installation des fichiers du programme." - LangString DESC_sec_data ${LANG_FRENCH} "Installation des Skins de RetroShare" - LangString DESC_sec_plugins ${LANG_FRENCH} "Installation des extensions de RetroShare " - LangString DESC_sec_startmenu ${LANG_FRENCH} "Création des raccourcis du menu Démarrer" - LangString DESC_sec_shortcuts ${LANG_FRENCH} "Création de l'icône sur le bureau." - LangString DESC_sec_link ${LANG_FRENCH} "Associer RetroShare avec l'extension de fichier .rsc" - LangString LANGUAGEID ${LANG_FRENCH} "1036" - - LangString sec_main ${LANG_GERMAN} "Programme" - LangString sec_data ${LANG_GERMAN} "Programm Skins" - LangString sec_plugins ${LANG_GERMAN} "Plug-ins" - LangString sec_shortcuts ${LANG_GERMAN} "Verknüpfungen" - LangString sec_link ${LANG_GERMAN} "Dateiverknüpfungen" - LangString sec_autostart ${LANG_GERMAN} "Autostart" - LangString DESC_sec_main ${LANG_GERMAN} "Installiert die RetroShare Programmdateien." - LangString DESC_sec_data ${LANG_GERMAN} "Installiert RetroShare Skins" - LangString DESC_sec_plugins ${LANG_GERMAN} "Installiert die RetroShare Erweiterungen." - LangString DESC_sec_shortcuts ${LANG_GERMAN} "RetroShare Verknüpfung im Startmenüe, Desktop oder im Schnellstarter erstellen." - LangString DESC_sec_link ${LANG_GERMAN} "RetroShare mit .rsc Dateiendung verknüpfen" - LangString LANGUAGEID ${LANG_GERMAN} "1031" - - LangString sec_main ${LANG_TURKISH} "Program Dosyalar?" - LangString sec_data ${LANG_TURKISH} "Program Skinleri" - LangString sec_shortcuts ${LANG_TURKISH} "Shortcut'lar" - LangString sec_plugins ${LANG_TURKISH} "Eklentiler" - LangString sec_link ${LANG_TURKISH} ".rsc Dosya Kaydet" - LangString sec_autostart ${LANG_TURKISH} "Otomatik calistir ve baglan" - LangString DESC_sec_main ${LANG_TURKISH} "Program dosyalar?n? kurar." - LangString DESC_sec_data ${LANG_TURKISH} "RetroShare Skin'leri kurar" - LangString DESC_sec_plugins ${LANG_TURKISH} "Installs the RetroShare plugins." - LangString DESC_sec_shortcuts ${TURKISH} "Shortcut yap Start menu , Desktop veya Quicklaunchbar icin." - LangString DESC_sec_link ${LANG_TURKISH} "RetroShare .rsc almas? i?in kaydettirir" - LangString LANGUAGEID ${LANG_TURKISH} "1055" - - LangString sec_main ${LANG_SIMPCHINESE} "程序文件" - LangString sec_data ${LANG_SIMPCHINESE} "程序皮肤" - LangString sec_plugins ${LANG_SIMPCHINESE} "Plugins" - LangString sec_shortcuts ${LANG_SIMPCHINESE} "快捷方式" - LangString sec_link ${LANG_SIMPCHINESE} "RetroShare文件关联" - LangString sec_autostart ${LANG_SIMPCHINESE} "自动启动" - LangString DESC_sec_main ${LANG_SIMPCHINESE} "安装RetroShare程序" - LangString DESC_sec_data ${LANG_SIMPCHINESE} "安装RetroShare皮肤" - LangString DESC_sec_plugins ${LANG_SIMPCHINESE} "Installs the RetroShare plugins." - LangString DESC_sec_shortcuts ${LANG_SIMPCHINESE} "建RetroShare快捷方式" - LangString DESC_sec_link ${LANG_SIMPCHINESE} "关联.rsc扩展名" - LangString LANGUAGEID ${LANG_SIMPCHINESE} "2052" - - LangString sec_main ${LANG_POLISH} "Pliki programu" - LangString sec_data ${LANG_POLISH} "Skórki" - LangString sec_plugins ${LANG_POLISH} "Plugins" - LangString sec_shortcuts ${LANG_POLISH} "Skróty" - LangString sec_link ${LANG_POLISH} "Skojarz pliki" - LangString sec_autostart ${LANG_POLISH} "Automatyczne uruchamianie" - LangString DESC_sec_main ${LANG_POLISH} "Instaluje pliki programu RetroShare" - LangString DESC_sec_data ${LANG_POLISH} "Instaluje skórki programu RetroShare" - LangString DESC_sec_plugins ${LANG_POLISH} "Installs the RetroShare plugins." - LangString DESC_sec_shortcuts ${LANG_POLISH} "Utwórz ikony skrótów na pulpicie, w menu start oraz na pasku szybkiego uruchamiania." - LangString DESC_sec_link ${LANG_POLISH} "Skojarz pliki o rozszerzeniu .rsc z RetroShare" - LangString LANGUAGEID ${LANG_POLISH} "1045" - - LangString sec_main ${LANG_DANISH} "Program Files" - LangString sec_data ${LANG_DANISH} "Program Skins" - LangString sec_plugins ${LANG_DANISH} "Plugins" - LangString sec_shortcuts ${LANG_DANISH} "Shortcuts" - LangString sec_link ${LANG_DANISH} "File Association" - LangString sec_autostart ${LANG_DANISH} "Auto Startup" - LangString DESC_sec_main ${LANG_DANISH} "Installs the RetroShare program files." - LangString DESC_sec_data ${LANG_DANISH} "Installs RetroShare Skins" - LangString DESC_sec_plugins ${LANG_DANISH} "Installs the RetroShare plugins." - LangString DESC_sec_shortcuts ${LANG_DANISH} "Create RetroShare shortcut icons." - LangString DESC_sec_link ${LANG_DANISH} "Associate RetroShare with .rsc file extension" - LangString LANGUAGEID ${LANG_DANISH} "1030" - - LangString sec_main ${LANG_RUSSIAN} "Program Files" - LangString sec_data ${LANG_RUSSIAN} "Program Skins" - LangString sec_plugins ${LANG_RUSSIAN} "Plugins" - LangString sec_shortcuts ${LANG_RUSSIAN} "Shortcuts" - LangString sec_link ${LANG_RUSSIAN} "File Association" - LangString sec_autostart ${LANG_RUSSIAN} "Auto Startup" - LangString DESC_sec_main ${LANG_RUSSIAN} "Installs the RetroShare program files." - LangString DESC_sec_data ${LANG_RUSSIAN} "Installs RetroShare Skins" - LangString DESC_sec_plugins ${LANG_RUSSIAN} "Installs the RetroShare plugins." - LangString DESC_sec_shortcuts ${LANG_RUSSIAN} "Create RetroShare shortcut icons." - LangString DESC_sec_link ${LANG_RUSSIAN} "Associate RetroShare with .rsc file extension" - LangString LANGUAGEID ${LANG_RUSSIAN} "1049" - - LangString sec_main ${LANG_SWEDISH} "Program Files" - LangString sec_data ${LANG_SWEDISH} "Program Skins" - LangString sec_plugins ${LANG_SWEDISH} "Plugins" - LangString sec_shortcuts ${LANG_SWEDISH} "Shortcuts" - LangString sec_link ${LANG_SWEDISH} "File Association" - LangString sec_autostart ${LANG_SWEDISH} "Auto Startup" - LangString DESC_sec_main ${LANG_SWEDISH} "Installs the RetroShare program files." - LangString DESC_sec_data ${LANG_SWEDISH} "Installs RetroShare Skins" - LangString DESC_sec_plugins ${LANG_SWEDISH} "Installs the RetroShare plugins." - LangString DESC_sec_shortcuts ${LANG_SWEDISH} "Create RetroShare shortcut icons." - LangString DESC_sec_link ${LANG_SWEDISH} "Associate RetroShare with .rsc file extension" - LangString LANGUAGEID ${LANG_SWEDISH} "1053" - - LangString sec_main ${LANG_SPANISH} "Archivos de programa" - LangString sec_data ${LANG_SPANISH} "Estilos del programa" - LangString sec_plugins ${LANG_SPANISH} "Plugins" - LangString sec_shortcuts ${LANG_SPANISH} "Accesos directos" - LangString sec_link ${LANG_SPANISH} "Asociación de archivos" - LangString sec_autostart ${LANG_SPANISH} "Inicio automático" - LangString DESC_sec_main ${LANG_SPANISH} "Instala los archivos del programa RetroShare." - LangString DESC_sec_data ${LANG_SPANISH} "Instala los estilos para RetroShare" - LangString DESC_sec_plugins ${LANG_SPANISH} "Installs the RetroShare plugins." - LangString DESC_sec_shortcuts ${LANG_SPANISH} "Crear iconos de acceso directo de RetroShare." - LangString DESC_sec_link ${LANG_SPANISH} "Asociar RetroShare con la extensión de archivo .rsc" - LangString LANGUAGEID ${LANG_SPANISH} "1034" - - LangString sec_main ${LANG_ITALIAN} "Programmi" - LangString sec_data ${LANG_ITALIAN} "Temi del Programma" - LangString sec_plugins ${LANG_ITALIAN} "Plugins" - LangString sec_shortcuts ${LANG_ITALIAN} "Icone" - LangString sec_link ${LANG_ITALIAN} "Associazione dei File" - LangString sec_autostart ${LANG_ITALIAN} "Esecuzione Automatica" - LangString DESC_sec_main ${LANG_ITALIAN} "Installare i file programma di RetroShare." - LangString DESC_sec_data ${LANG_ITALIAN} "Installare i temi di RetroShare" - LangString DESC_sec_plugins ${LANG_ITALIAN} "Installs the RetroShare plugins." - LangString DESC_sec_shortcuts ${LANG_ITALIAN} "Creare le icone per avviare RetroShare." - LangString DESC_sec_link ${LANG_ITALIAN} "Associa a RetroShare i file con estensione .rsc" - LangString LANGUAGEID ${LANG_ITALIAN} "1040" - - LangString sec_main ${LANG_GREEK} "Program Files" - LangString sec_data ${LANG_GREEK} "Program Skins" - LangString sec_plugins ${LANG_GREEK} "Plugins" - LangString sec_shortcuts ${LANG_GREEK} "Shortcuts" - LangString sec_link ${LANG_GREEK} "File Association" - LangString sec_autostart ${LANG_GREEK} "Auto Startup" - LangString DESC_sec_main ${LANG_GREEK} "Installs the RetroShare program files." - LangString DESC_sec_data ${LANG_GREEK} "Installs RetroShare Skins" - LangString DESC_sec_plugins ${LANG_GREEK} "Installs the RetroShare plugins." - LangString DESC_sec_shortcuts ${LANG_GREEK} "Create RetroShare shortcut icons." - LangString DESC_sec_link ${LANG_GREEK} "Associate RetroShare with .rsc file extension" - LangString LANGUAGEID ${LANG_GREEK} "1032" - - LangString sec_main ${LANG_PORTUGUESEBR} "Program Files" - LangString sec_data ${LANG_PORTUGUESEBR} "Program Skins" - LangString sec_plugins ${LANG_PORTUGUESEBR} "Plugins" - LangString sec_shortcuts ${LANG_PORTUGUESEBR} "Shortcuts" - LangString sec_link ${LANG_PORTUGUESEBR} "File Association" - LangString sec_autostart ${LANG_PORTUGUESEBR} "Auto Startup" - LangString DESC_sec_main ${LANG_PORTUGUESEBR} "Installs the RetroShare program files." - LangString DESC_sec_data ${LANG_PORTUGUESEBR} "Installs RetroShare Skins" - LangString DESC_sec_plugins ${LANG_PORTUGUESEBR} "Installs the RetroShare plugins." - LangString DESC_sec_shortcuts ${LANG_PORTUGUESEBR} "Create RetroShare shortcut icons." - LangString DESC_sec_link ${LANG_PORTUGUESEBR} "Associate RetroShare with .rsc file extension" - LangString LANGUAGEID ${LANG_PORTUGUESEBR} "1046" - - LangString sec_main ${LANG_JAPANESE} "Program Files" - LangString sec_data ${LANG_JAPANESE} "Program Skins" - LangString sec_plugins ${LANG_JAPANESE} "Plugins" - LangString sec_shortcuts ${LANG_JAPANESE} "Shortcuts" - LangString sec_link ${LANG_JAPANESE} "File Association" - LangString sec_autostart ${LANG_JAPANESE} "Auto Startup" - LangString DESC_sec_main ${LANG_JAPANESE} "Installs the RetroShare program files." - LangString DESC_sec_data ${LANG_JAPANESE} "Installs RetroShare Skins" - LangString DESC_sec_plugins ${LANG_JAPANESE} "Installs the RetroShare plugins." - LangString DESC_sec_shortcuts ${LANG_JAPANESE} "Create RetroShare shortcut icons." - LangString DESC_sec_link ${LANG_JAPANESE} "Associate RetroShare with .rsc file extension" - LangString LANGUAGEID ${LANG_JAPANESE} "1041" - - LangString sec_main ${LANG_KOREAN} "Program Files" - LangString sec_data ${LANG_KOREAN} "Program Skins" - LangString sec_plugins ${LANG_KOREAN} "Plugins" - LangString sec_shortcuts ${LANG_KOREAN} "Shortcuts" - LangString sec_link ${LANG_KOREAN} "File Association" - LangString sec_autostart ${LANG_KOREAN} "Auto Startup" - LangString DESC_sec_main ${LANG_KOREAN} "Installs the RetroShare program files." - LangString DESC_sec_data ${LANG_KOREAN} "Installs RetroShare Skins" - LangString DESC_sec_plugins ${LANG_KOREAN} "Installs the RetroShare plugins." - LangString DESC_sec_shortcuts ${LANG_KOREAN} "Create RetroShare shortcut icons." - LangString DESC_sec_link ${LANG_KOREAN} "Associate RetroShare with .rsc file extension" - LangString LANGUAGEID ${LANG_KOREAN} "1042" - - -!insertmacro MUI_RESERVEFILE_INSTALLOPTIONS - -Section $(sec_main) sec_main - - ;Set Section required - SectionIn RO - - ; Set Section properties - SetOverwrite on - - ; Clears previous error logs - Delete "$INSTDIR\*.log" - - ; Set Section Files and Shortcuts - SetOutPath "$INSTDIR\" - File /r "release\RetroShare.exe" - File /r "..\..\retroshare-nogui\src\release\retroshare-nogui.exe" - File /r "${QTBASE}\mingw\bin\mingwm10.dll" - File /r "${QTBASE}\qt\bin\QtCore4.dll" - File /r "${QTBASE}\qt\bin\QtGui4.dll" - File /r "${QTBASE}\qt\bin\QtNetwork4.dll" - File /r "${QTBASE}\qt\bin\QtMultimedia4.dll" - File /r "${QTBASE}\qt\bin\QtXml4.dll" - File /r "${QTBASE}\qt\bin\QtScript4.dll" - File /r "${QTBASE}\qt\bin\QtSvg4.dll" - File /r "${QTBASE}\qt\bin\libgcc_s_dw2-1.dll" - File /r "${QTBASE}\qt\plugins\imageformats" - File /r ${QTBASE}\qt\qt_*.qm - File /r ${RSBASE}\src\qt_*.qm - File /r "release\pthreadGC2d.dll" - File /r "h:\Development\lib\libminiupnpc-1.3\miniupnpc.dll" - File /r "changelog.txt" - File /r /x Data "release\bdboot.txt" - - -SectionEnd - -Section $(sec_data) sec_data - - ; Set Section properties - SetOverwrite on - - ; Set Section Files and Shortcuts - SetOutPath "$APPDATA\RetroShare\" - ;File /r "data\*" - - ; Set Section qss and exclude svn - SetOutPath "$INSTDIR\qss\" - File /r /x .svn qss\*.* - - ; Set Section sounds and exclude svn - SetOutPath "$INSTDIR\sounds\" - File /r /x .svn sounds\*.* - - ; Set Section skin - ; SetOutPath "$INSTDIR\skin\" - ; File /r release\skin\*.* - - ; Add emoticons - ;SetOutPath "$INSTDIR\emoticons\" - ;File /r emoticons\*.* - - ; Add Chat Style - SetOutPath "$APPDATA\RetroShare\stylesheets\" - File /r gui\qss\chat\Bubble - File /r gui\qss\chat\Bubble_Compact - - -SectionEnd - -SectionGroup $(sec_plugins) sec_plugins -Section Voip SEC001 - - ; Set Section properties - SetOverwrite on - - ; Set Section Plugins - SetOutPath "$APPDATA\RetroShare\extensions\" - - File /r "..\..\plugins\VOIP\release\VOIP.dll" - -SectionEnd - -Section FeedReader SEC002 - - ; Set Section properties - SetOverwrite on - - ; Set Section Plugins - SetOutPath "$APPDATA\RetroShare\extensions\" - - File /r "..\..\plugins\FeedReader\release\FeedReader.dll" - -SectionEnd - -SectionGroupEnd - -Section $(sec_link) sec_link - ; Delete any existing keys - - - ; Write the file association - WriteRegStr HKCR .rsc "" retroshare - WriteRegStr HKCR retroshare "" "RSC File" - WriteRegBin HKCR retroshare EditFlags 00000100 - WriteRegStr HKCR "retroshare\shell" "" open - WriteRegStr HKCR "retroshare\shell\open\command" "" `"$INSTDIR\RetroShare.exe" "%1"` - -SectionEnd - -SectionGroup $(sec_shortcuts) sec_shortcuts -Section StartMenu SEC0001 - - SetOutPath "$INSTDIR" - CreateDirectory "$SMPROGRAMS\${APPNAME}" - CreateShortCut "$SMPROGRAMS\${APPNAME}\${APPNAME}.lnk" "$INSTDIR\RetroShare.exe" "" "$INSTDIR\RetroShare.exe" 0 - CreateShortCut "$SMPROGRAMS\${APPNAME}\$(^UninstallLink).lnk" "$INSTDIR\uninstall.exe" "" "$INSTDIR\uninstall.exe" 0 - -SectionEnd - -Section Desktop SEC0002 - - - CreateShortCut "$DESKTOP\${APPNAME}.lnk" "$INSTDIR\RetroShare.exe" "" "$INSTDIR\RetroShare.exe" 0 - -SectionEnd - -Section Quicklaunchbar SEC0003 - - - CreateShortCut "$QUICKLAUNCH\${APPNAME}.lnk" "$INSTDIR\RetroShare.exe" "" "$INSTDIR\RetroShare.exe" 0 - -SectionEnd -SectionGroupEnd - -;Section $(sec_autostart) sec_autostart - -; WriteRegStr HKCU "Software\Microsoft\Windows\CurrentVersion\Run" "RetroRun" "$INSTDIR\${APPNAME}.exe -a" - -;SectionEnd - -;Section $(sec_autostart) sec_autostart - -; CreateShortCut "$SMSTARTUP\${APPNAME}.lnk" "$INSTDIR\RetroShare.exe" "" "$INSTDIR\RetroShare.exe" 0 -;SectionEnd - - -Section -FinishSection - - WriteRegStr HKLM "Software\${APPNAME}" "" "$INSTDIR" - WriteRegStr HKLM "Software\${APPNAME}" "Version" "${VERSION}" - WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${APPNAME}" "DisplayName" "${APPNAME}" - WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${APPNAME}" "UninstallString" "$INSTDIR\uninstall.exe" - WriteUninstaller "$INSTDIR\uninstall.exe" - -SectionEnd - - - -;-------------------------------- -;Descriptions - -!insertmacro MUI_FUNCTION_DESCRIPTION_BEGIN - !insertmacro MUI_DESCRIPTION_TEXT ${sec_main} $(DESC_sec_main) - !insertmacro MUI_DESCRIPTION_TEXT ${sec_data} $(DESC_sec_data) - !insertmacro MUI_DESCRIPTION_TEXT ${sec_plugins} $(DESC_sec_plugins) - !insertmacro MUI_DESCRIPTION_TEXT ${sec_shortcuts} $(DESC_sec_shortcuts) - !insertmacro MUI_DESCRIPTION_TEXT ${sec_link} $(DESC_sec_link) - ;!insertmacro MUI_DESCRIPTION_TEXT ${sec_autostart} $(DESC_sec_autostart) -!insertmacro MUI_FUNCTION_DESCRIPTION_END - -;Uninstall section -Section "Uninstall" - - ; Remove file association registry keys - DeleteRegKey HKCR .rsc - DeleteRegKey HKCR retroshare - - ; Remove program/uninstall regsitry keys - DeleteRegKey HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${APPNAME}" - DeleteRegKey HKLM SOFTWARE\${APPNAME} - - DeleteRegValue HKCU "Software\Microsoft\Windows\CurrentVersion\Run" "RetroRun" - - ; Remove files and uninstaller - Delete $INSTDIR\RetroShare.exe - Delete $INSTDIR\*.dll - Delete $INSTDIR\*.dat - Delete $INSTDIR\*.txt - Delete $INSTDIR\*.ini - Delete $INSTDIR\*.log - - Delete $INSTDIR\uninstall.exe - - ; Remove the kadc.ini file. - ; Don't remove the directory, otherwise - ; we lose the XPGP keys. - ; Should make this an option though... - Delete "$APPDATA\${APPNAME}\kadc.ini" - Delete "$APPDATA\${APPNAME}\*.cfg" - Delete "$APPDATA\${APPNAME}\*.conf" - Delete "$APPDATA\${APPNAME}\*.log-save" - Delete "$APPDATA\${APPNAME}\*.log" - Delete "$APPDATA\${APPNAME}\*.failed" - - RMDir /r "$APPDATA\${APPNAME}\cache" - RMDir /r "$APPDATA\${APPNAME}\Partials" - - ; Remove shortcuts, if any - Delete "$SMPROGRAMS\${APPNAME}\*.*" - - ; Remove desktop shortcut - Delete "$DESKTOP\${APPNAME}.lnk" - - ; Remove Quicklaunch shortcut - Delete "$QUICKLAUNCH\${APPNAME}.lnk" - - ; Remove Autostart - ;Delete "$SMSTARTUP\${APPNAME}.lnk" - - ; Remove directories used - RMDir "$SMPROGRAMS\${APPNAME}" - RMDir /r "$INSTDIR" - RMDir /r "$INSTDIR\qss" - RMDir /r "$INSTDIR\emoticons" - RMDir /r "$INSTDIR\style" - RMDir /r "$INSTDIR\translations" - -SectionEnd - -Function .onInit - - InitPluginsDir - Push $R1 - File /oname=$PLUGINSDIR\spltmp.bmp "gui\images\splash.bmp" - advsplash::show 1200 1000 1000 -1 $PLUGINSDIR\spltmp - Pop $R1 - Pop $R1 - !insertmacro MUI_LANGDLL_DISPLAY - - - -FunctionEnd - - -# Installer Language Strings -# TODO Update the Language Strings with the appropriate translations. - - -LangString FINISHPAGELINK ${LANG_ENGLISH} "Visit the RetroShare forums for the latest news and support" -LangString FINISHPAGELINK ${LANG_GERMAN} "Das RetroShare Support-Forum besuchen, um Neuigkeiten und Unterstützung zu erfahren" -LangString FINISHPAGELINK ${LANG_TURKISH} "Destek için Retroshare foruma ziyaret et" -LangString FINISHPAGELINK ${LANG_FRENCH} "Consultez le forum RetroShare pour vous tenir au courant des dernieres modifications, et obtenir de l'aide." -LangString FINISHPAGELINK ${LANG_SIMPCHINESE} "帮助论坛" -LangString FINISHPAGELINK ${LANG_POLISH} "Odwiedź forum RetroShare do najświeższych informacji i wsparcia" -LangString FINISHPAGELINK ${LANG_DANISH} "Besøg RetroShare fora for de seneste nyheder og støtte" -LangString FINISHPAGELINK ${LANG_JAPANESE} "Visit the RetroShare forums for the latest news and support" -LangString FINISHPAGELINK ${LANG_KOREAN} "Visit the RetroShare forums for the latest news and support" -LangString FINISHPAGELINK ${LANG_RUSSIAN} "Visit the RetroShare forums for the latest news and support" -LangString FINISHPAGELINK ${LANG_SWEDISH} "Besök RetroShare forum för de senaste nyheterna och stöd" -LangString FINISHPAGELINK ${LANG_SPANISH} "Visite los foros de RetroShare para las últimas noticias y soporte" -LangString FINISHPAGELINK ${LANG_ITALIAN} "Visita i forum di RetroShare per le ultime novità ed il supporto" -LangString FINISHPAGELINK ${LANG_GREEK} "Visit the RetroShare forums for the latest news and support" -LangString FINISHPAGELINK ${LANG_PORTUGUESEBR} "Visit the RetroShare forums for the latest news and support" - -LangString ^UninstallLink ${LANG_ENGLISH} "Uninstall" -LangString ^UninstallLink ${LANG_GERMAN} "Deinstallieren" -LangString ^UninstallLink ${LANG_TURKISH} "Kald�r" -LangString ^UninstallLink ${LANG_FRENCH} "Désinstaller" -LangString ^UninstallLink ${LANG_SIMPCHINESE} "卸载" -LangString ^UninstallLink ${LANG_POLISH} "Odinstaluj" -LangString ^UninstallLink ${LANG_DANISH} "Afinstaller" -LangString ^UninstallLink ${LANG_JAPANESE} "Uninstall" -LangString ^UninstallLink ${LANG_KOREAN} "Uninstall" -LangString ^UninstallLink ${LANG_RUSSIAN} "Uninstall" -LangString ^UninstallLink ${LANG_SWEDISH} "Avinstallera" -LangString ^UninstallLink ${LANG_SPANISH} "Desinstalar" -LangString ^UninstallLink ${LANG_ITALIAN} "Disinstallare" -LangString ^UninstallLink ${LANG_GREEK} "Απεγκατάσταση" -LangString ^UninstallLink ${LANG_PORTUGUESEBR} "Desinstalar" - -; eof From 6a4cdcc471d671df3875ea102c3ba58d5d73f5c2 Mon Sep 17 00:00:00 2001 From: csoler Date: Mon, 29 Nov 2021 22:59:46 +0100 Subject: [PATCH 039/113] 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 856ce2ffb165bb7358af2d81d954f8c8e5f001b7 Mon Sep 17 00:00:00 2001 From: Gioacchino Mazzurco Date: Tue, 30 Nov 2021 11:03:22 +0100 Subject: [PATCH 040/113] Do not depend on Qt at all on Android Do the necessary modifications to not depend on Qt to run on Android both in libretroshare and in retroshare-service --- .gitmodules | 3 + .../Android/prepare-toolchain-clang.sh | 13 ++ libretroshare/src/jsonapi/jsonapi.cpp | 5 +- libretroshare/src/libretroshare.pro | 21 ++- libretroshare/src/pqi/p3peermgr.cc | 4 +- libretroshare/src/pqi/pqinetwork.cc | 88 ++++------ libretroshare/src/pqi/pqinetwork.h | 16 +- .../LocalArray.h | 0 .../README-ifaddrs-android.adoc} | 10 +- .../ScopedFd.h | 0 .../androidcoutcerrcatcher.hpp} | 26 +-- .../src/rs_android/errorconditionwrap.cpp | 42 +++++ .../ifaddrs-android.h | 0 .../org/retroshare/service/AssetHelper.java | 98 +++++++++++ .../service/ErrorConditionWrap.java | 48 ++++++ .../service/RetroShareServiceAndroid.java | 138 +++++++++++++++ .../rs_android/retroshareserviceandroid.cpp | 103 ++++++++++++ .../rs_android/retroshareserviceandroid.hpp | 84 ++++++++++ libretroshare/src/rs_android/rsjni.cpp | 70 ++++++++ libretroshare/src/rs_android/rsjni.hpp | 90 ++++++++++ libretroshare/src/rsserver/rsaccounts.cc | 80 ++++++--- libretroshare/src/rsserver/rsinit.cc | 57 +++---- .../src/services/broadcastdiscoveryservice.cc | 158 +++++++++++------- .../src/services/broadcastdiscoveryservice.h | 34 ++-- libretroshare/src/use_libretroshare.pri | 9 +- .../src/android/AndroidManifest.xml | 80 +++++---- .../service/AppUpdatedReceiver.java | 2 + .../org/retroshare/service/AssetHelper.java | 1 + .../service/BootCompletedReceiver.java | 2 + .../service/ErrorConditionWrap.java | 1 + .../service/RetroShareServiceAndroid.java | 51 +----- .../RetroShareServiceControlActivity.java | 8 +- .../src/retroshare-service-android.cc | 29 ++++ retroshare-service/src/retroshare-service.cc | 64 ++----- retroshare-service/src/retroshare-service.pro | 10 +- supportlibs/jni.hpp | 1 + 36 files changed, 1094 insertions(+), 352 deletions(-) rename libretroshare/src/{android_ifaddrs => rs_android}/LocalArray.h (100%) rename libretroshare/src/{android_ifaddrs/README.adoc => rs_android/README-ifaddrs-android.adoc} (75%) rename libretroshare/src/{android_ifaddrs => rs_android}/ScopedFd.h (100%) rename libretroshare/src/{util/androiddebug.h => rs_android/androidcoutcerrcatcher.hpp} (83%) create mode 100644 libretroshare/src/rs_android/errorconditionwrap.cpp rename libretroshare/src/{android_ifaddrs => rs_android}/ifaddrs-android.h (100%) create mode 100644 libretroshare/src/rs_android/org/retroshare/service/AssetHelper.java create mode 100644 libretroshare/src/rs_android/org/retroshare/service/ErrorConditionWrap.java create mode 100644 libretroshare/src/rs_android/org/retroshare/service/RetroShareServiceAndroid.java create mode 100644 libretroshare/src/rs_android/retroshareserviceandroid.cpp create mode 100644 libretroshare/src/rs_android/retroshareserviceandroid.hpp create mode 100644 libretroshare/src/rs_android/rsjni.cpp create mode 100644 libretroshare/src/rs_android/rsjni.hpp create mode 120000 retroshare-service/src/android/src/org/retroshare/service/AssetHelper.java create mode 120000 retroshare-service/src/android/src/org/retroshare/service/ErrorConditionWrap.java mode change 100644 => 120000 retroshare-service/src/android/src/org/retroshare/service/RetroShareServiceAndroid.java create mode 100644 retroshare-service/src/retroshare-service-android.cc create mode 160000 supportlibs/jni.hpp diff --git a/.gitmodules b/.gitmodules index 2f69bb7b2..5199bdb4d 100644 --- a/.gitmodules +++ b/.gitmodules @@ -17,3 +17,6 @@ [submodule "supportlibs/libsam3"] path = supportlibs/libsam3 url = https://github.com/i2p/libsam3.git +[submodule "supportlibs/jni.hpp"] + path = supportlibs/jni.hpp + url = https://github.com/RetroShare/jni.hpp.git diff --git a/build_scripts/Android/prepare-toolchain-clang.sh b/build_scripts/Android/prepare-toolchain-clang.sh index 25fefccba..510b04855 100755 --- a/build_scripts/Android/prepare-toolchain-clang.sh +++ b/build_scripts/Android/prepare-toolchain-clang.sh @@ -112,6 +112,9 @@ define_default_value MVPTREE_SOURCE_VERSION origin/master define_default_value REPORT_DIR "$(pwd)/$(basename ${NATIVE_LIBS_TOOLCHAIN_PATH})_build_report/" +define_default_value RS_SRC_DIR "$(realpath $(dirname $BASH_SOURCE)/../../)" + + cArch="" eABI="" cmakeABI="" @@ -829,6 +832,15 @@ build_phash() popd } +task_register fetch_jni_hpp +fetch_jni_hpp() +{ + local rDir="supportlibs/jni.hpp/" + + [ "$(ls "${RS_SRC_DIR}/${rDir}" | wc -l)" -gt "4" ] || + git -C ${RS_SRC_DIR} submodule update --init ${rDir} +} + task_register build_mvptree build_mvptree() { @@ -862,6 +874,7 @@ build_default_toolchain() task_run build_xapian || return $? task_run build_miniupnpc || return $? task_run build_phash || return $? + task_run fetch_jni_hpp || return $? task_run deduplicate_includes || return $? task_run get_native_libs_toolchain_path || return $? } diff --git a/libretroshare/src/jsonapi/jsonapi.cpp b/libretroshare/src/jsonapi/jsonapi.cpp index 4b003f225..2f2ded30c 100644 --- a/libretroshare/src/jsonapi/jsonapi.cpp +++ b/libretroshare/src/jsonapi/jsonapi.cpp @@ -796,8 +796,9 @@ void JsonApiServer::run() } catch(std::exception& e) { - RsErr() << __PRETTY_FUNCTION__ << " Failure starting JSON API server: " - << e.what() << std::endl; + /* TODO: find a way to report back programmatically if failed listening + * port */ + RS_ERR("Failure starting JSON API server: ", e.what()); print_stacktrace(); return; } diff --git a/libretroshare/src/libretroshare.pro b/libretroshare/src/libretroshare.pro index 36103f856..2bad4682f 100644 --- a/libretroshare/src/libretroshare.pro +++ b/libretroshare/src/libretroshare.pro @@ -1101,13 +1101,11 @@ android-* { DEFINES *= "fseeko64=fseeko" DEFINES *= "ftello64=ftello" - ## @See: android_ifaddrs/README.adoc - !contains(DEFINES, LIBRETROSHARE_ANDROID_IFADDRS_QT) { - HEADERS += \ - android_ifaddrs/ifaddrs-android.h \ - android_ifaddrs/LocalArray.h \ - android_ifaddrs/ScopedFd.h - } +## @See: rs_android/README-ifaddrs-android.adoc + HEADERS += \ + rs_android/ifaddrs-android.h \ + rs_android/LocalArray.h \ + rs_android/ScopedFd.h } ## Static library are very susceptible to order in command line @@ -1116,6 +1114,13 @@ android-* { LIBS += $$linkStaticLibs(sLibs) PRE_TARGETDEPS += $$pretargetStaticLibs(sLibs) - HEADERS += util/androiddebug.h + HEADERS += \ + rs_android/androidcoutcerrcatcher.hpp \ + rs_android/retroshareserviceandroid.hpp \ + rs_android/rsjni.hpp + + SOURCES += rs_android/rsjni.cpp \ + rs_android/retroshareserviceandroid.cpp \ + rs_android/errorconditionwrap.cpp } diff --git a/libretroshare/src/pqi/p3peermgr.cc b/libretroshare/src/pqi/p3peermgr.cc index 83c4d9366..f1d604ea5 100644 --- a/libretroshare/src/pqi/p3peermgr.cc +++ b/libretroshare/src/pqi/p3peermgr.cc @@ -1398,11 +1398,11 @@ bool p3PeerMgrIMPL::UpdateOwnAddress( const sockaddr_storage& pLocalAddr, sockaddr_storage_copy(pExtAddr, extAddr); sockaddr_storage_ipv6_to_ipv4(extAddr); -//#ifdef PEER_DEBUG +#ifdef PEER_DEBUG std::cerr << "p3PeerMgrIMPL::UpdateOwnAddress(" << sockaddr_storage_tostring(localAddr) << ", " << sockaddr_storage_tostring(extAddr) << ")" << std::endl; -//#endif +#endif if( rsBanList && !rsBanList->isAddressAccepted(localAddr, diff --git a/libretroshare/src/pqi/pqinetwork.cc b/libretroshare/src/pqi/pqinetwork.cc index b6c52fc27..2b786f488 100644 --- a/libretroshare/src/pqi/pqinetwork.cc +++ b/libretroshare/src/pqi/pqinetwork.cc @@ -21,16 +21,6 @@ * along with this program. If not, see . * * * *******************************************************************************/ -#ifdef WINDOWS_SYS -# include "util/rswin.h" -# include "util/rsmemory.h" -# include -#endif // WINDOWS_SYS - -/// @See: android_ifaddrs/README.adoc -#ifdef __ANDROID__ -# include -#endif // def __ANDROID__ #include #include @@ -44,6 +34,28 @@ #include "util/rsnet.h" #include "util/stacktrace.h" +#ifdef WINDOWS_SYS +# include "util/rswin.h" +# include "util/rsmemory.h" +# include +#endif // WINDOWS_SYS + +/// @See: android_ifaddrs/README.adoc +#ifdef __ANDROID__ +# include +#endif // def __ANDROID__ + +#ifdef WINDOWS_SYS /* Windows - define errno */ +int errno; +#else /* Windows - define errno */ +#include +#endif + +#ifdef __HAIKU__ +# include +# define IFF_RUNNING 0x0001 +#endif + static struct RsLog::logInfo pqinetzoneInfo = {RsLog::Default, "pqinet"}; #define pqinetzone &pqinetzoneInfo @@ -51,21 +63,6 @@ static struct RsLog::logInfo pqinetzoneInfo = {RsLog::Default, "pqinet"}; * #define NET_DEBUG 1 ****/ -#ifdef WINDOWS_SYS /* Windows - define errno */ - -int errno; - -#else /* Windows - define errno */ - -#include - -#endif - -#ifdef __HAIKU__ - #include - #define IFF_RUNNING 0x0001 -#endif - /********************************** WINDOWS/UNIX SPECIFIC PART ******************/ #ifndef WINDOWS_SYS @@ -271,24 +268,16 @@ int inet_aton(const char *name, struct in_addr *addr) #endif /********************************** WINDOWS/UNIX SPECIFIC PART ******************/ - +#include "util/cxx17retrocompat.h" #include #ifdef WINDOWS_SYS # include # include # pragma comment(lib, "IPHLPAPI.lib") -#elif defined(__ANDROID__) && __ANDROID_API__ < 24 && \ - defined(LIBRETROSHARE_ANDROID_IFADDRS_QT) +#elif defined(__ANDROID__) && __ANDROID_API__ < 24 /// @See: android_ifaddrs/README.adoc -# include -# include -# include -# include -#elif defined(__ANDROID__) && __ANDROID_API__ < 24 && \ - !defined(LIBRETROSHARE_ANDROID_IFADDRS_QT) -/// @See: android_ifaddrs/README.adoc -# include "android_ifaddrs/ifaddrs-android.h" -#else // not __ANDROID__ nor WINDOWS => Linux and other unixes +# include "rs_android/ifaddrs-android.h" +#else // not WINDOWS => Linux and other unixes # include # include #endif // WINDOWS_SYS @@ -331,17 +320,7 @@ bool getLocalAddresses(std::vector& addrs) } } free(adapter_addresses); -#elif defined(__ANDROID__) && __ANDROID_API__ < 24 && \ - defined(LIBRETROSHARE_ANDROID_IFADDRS_QT) -/// @See: android_ifaddrs/README.adoc - for(auto& qAddr: QNetworkInterface::allAddresses()) - { - sockaddr_storage tmpAddr; - sockaddr_storage_clear(tmpAddr); - if(sockaddr_storage_ipv4_aton(tmpAddr, qAddr.toString().toStdString().c_str())) - addrs.push_back(tmpAddr); - } -#else // not WINDOWS_SYS not ANDROID => Linux and other unixes +#else // not WINDOWS_SYS => Linux and other unixes struct ifaddrs *ifsaddrs, *ifa; if(getifaddrs(&ifsaddrs) != 0) { @@ -355,18 +334,19 @@ bool getLocalAddresses(std::vector& addrs) { sockaddr_storage tmp; sockaddr_storage_clear(tmp); - if (sockaddr_storage_copyip(tmp, *reinterpret_cast(ifa->ifa_addr))) + if(sockaddr_storage_copyip( + tmp, + *reinterpret_cast(ifa->ifa_addr) )) addrs.push_back(tmp); } freeifaddrs(ifsaddrs); #endif // WINDOWS_SYS #ifdef NET_DEBUG - std::list::iterator it; - std::cout << "getLocalAddresses(...) returning: <" ; - for(it = addrs.begin(); it != addrs.end(); ++it) - std::cout << sockaddr_storage_iptostring(*it) << ", "; - std::cout << ">" << std::endl; + auto&& dbg = RS_DBG("returning: ["); + for(auto& addr: std::as_const(addrs)) + dbg << sockaddr_storage_iptostring(addr) << ", "; + dbg << "]" << std::endl; #endif return !addrs.empty(); diff --git a/libretroshare/src/pqi/pqinetwork.h b/libretroshare/src/pqi/pqinetwork.h index e4238ee5e..9519bf197 100644 --- a/libretroshare/src/pqi/pqinetwork.h +++ b/libretroshare/src/pqi/pqinetwork.h @@ -4,7 +4,8 @@ * libretroshare: retroshare core library * * * * Copyright (C) 2004-2006 Robert Fernie * - * Copyright (C) 2015-2018 Gioacchino Mazzurco * + * Copyright (C) 2015-2021 Gioacchino Mazzurco * + * Copyright (C) 2021 Asociación Civil Altermundi * * * * This program is free software: you can redistribute it and/or modify * * it under the terms of the GNU Lesser General Public License as * @@ -20,8 +21,7 @@ * along with this program. If not, see . * * * *******************************************************************************/ -#ifndef MRK_PQI_NETWORKING_HEADER -#define MRK_PQI_NETWORKING_HEADER +#pragma once #include @@ -86,9 +86,13 @@ extern int errno; /* Define extern errno, to duplicate unix behaviour */ #include #include +#include "util/rsdeprecate.h" + // Same def - different functions... +RS_DEPRECATED_FOR("use std::error_condition instead") void showSocketError(std::string &out); +RS_DEPRECATED_FOR("use std::error_condition instead") std::string socket_errorType(int err); bool getLocalAddresses(std::vector & addrs); @@ -103,10 +107,6 @@ int unix_getsockopt_error(int sockfd, int *err); #ifdef WINDOWS_SYS // WINDOWS /******************* WINDOWS SPECIFIC PART ******************/ +RS_DEPRECATED_FOR("use std::error_condition instead") int WinToUnixError(int error); #endif - - - -#endif - diff --git a/libretroshare/src/android_ifaddrs/LocalArray.h b/libretroshare/src/rs_android/LocalArray.h similarity index 100% rename from libretroshare/src/android_ifaddrs/LocalArray.h rename to libretroshare/src/rs_android/LocalArray.h diff --git a/libretroshare/src/android_ifaddrs/README.adoc b/libretroshare/src/rs_android/README-ifaddrs-android.adoc similarity index 75% rename from libretroshare/src/android_ifaddrs/README.adoc rename to libretroshare/src/rs_android/README-ifaddrs-android.adoc index ba0355df7..0c0065f92 100644 --- a/libretroshare/src/android_ifaddrs/README.adoc +++ b/libretroshare/src/rs_android/README-ifaddrs-android.adoc @@ -24,9 +24,8 @@ plus depending on Qt networking module just for this is frustrating. Update: the warning flood seems have been fixed in later Qt versions https://bugreports.qt.io/browse/QTBUG-86394 -This solution is the first working we implemented in our code it is disabled by -default but can be enabled passing `DEFINES+=LIBRETROSHARE_ANDROID_IFADDRS_QT` -when running `qmake` command. +This solution was the first working we implemented in our code it has been +removed to avoid dependency on Qt, as lighter alternatives are possible. == Code copied from Android Gingerbread release @@ -43,3 +42,8 @@ https://android.googlesource.com/platform/libcore/+/refs/heads/gingerbread-relea is particularly easy to include in our code base and compile. This solution seems the best fitting and doesn't introduce dependency on Qt. +Newer Android releases (expecially 11) have introduced multiple restrictions +on network information access so we suggest you to prepare different APK for +different API level in order to use the `getifaddrs` provided by Android NDK +which deal gracefully with those restrictions as soon as available. + diff --git a/libretroshare/src/android_ifaddrs/ScopedFd.h b/libretroshare/src/rs_android/ScopedFd.h similarity index 100% rename from libretroshare/src/android_ifaddrs/ScopedFd.h rename to libretroshare/src/rs_android/ScopedFd.h diff --git a/libretroshare/src/util/androiddebug.h b/libretroshare/src/rs_android/androidcoutcerrcatcher.hpp similarity index 83% rename from libretroshare/src/util/androiddebug.h rename to libretroshare/src/rs_android/androidcoutcerrcatcher.hpp index c358be553..43cf16dd7 100644 --- a/libretroshare/src/util/androiddebug.h +++ b/libretroshare/src/rs_android/androidcoutcerrcatcher.hpp @@ -1,9 +1,9 @@ /******************************************************************************* - * libretroshare/src/util: androiddebug.h * * * * libretroshare: retroshare core library * * * - * Copyright (C) 2016 Gioacchino Mazzurco * + * Copyright (C) 2016-2021 Gioacchino Mazzurco * + * Copyright (C) 2021 Asociación Civil Altermundi * * * * This program is free software: you can redistribute it and/or modify * * it under the terms of the GNU Lesser General Public License as * @@ -36,10 +36,10 @@ * class at the beginning of the main of your program to get them (stdout and * stderr) on logcat output. */ -class AndroidStdIOCatcher +class AndroidCoutCerrCatcher { public: - AndroidStdIOCatcher(const std::string& dTag = "RetroShare", + AndroidCoutCerrCatcher(const std::string& dTag = "RetroShare", android_LogPriority stdout_pri = ANDROID_LOG_INFO, android_LogPriority stderr_pri = ANDROID_LOG_ERROR) : tag(dTag), cout_pri(stdout_pri), cerr_pri(stderr_pri), should_stop(false) @@ -63,10 +63,10 @@ public: pthread_detach(thr); } - ~AndroidStdIOCatcher() + ~AndroidCoutCerrCatcher() { should_stop = true; - pthread_join(thr, NULL); + pthread_join(thr, nullptr); } private: @@ -79,11 +79,13 @@ private: pthread_t thr; std::atomic should_stop; - static void *thread_func(void* instance) + static void* thread_func(void* instance) { - __android_log_write(ANDROID_LOG_INFO, "RetroShare", "Android debugging start"); + __android_log_write( + ANDROID_LOG_INFO, "RetroShare", + "Android standard I/O catcher start" ); - AndroidStdIOCatcher &i = *static_cast(instance); + AndroidCoutCerrCatcher &i = *static_cast(instance); std::string out_buf; std::string err_buf; @@ -113,9 +115,11 @@ private: usleep(10000); } - __android_log_write(ANDROID_LOG_INFO, "RetroShare", "Android debugging stop"); + __android_log_write( + ANDROID_LOG_INFO, "RetroShare", + "Android standard I/O catcher stop" ); - return NULL; + return nullptr; } }; diff --git a/libretroshare/src/rs_android/errorconditionwrap.cpp b/libretroshare/src/rs_android/errorconditionwrap.cpp new file mode 100644 index 000000000..e27495878 --- /dev/null +++ b/libretroshare/src/rs_android/errorconditionwrap.cpp @@ -0,0 +1,42 @@ +/******************************************************************************* + * * + * libretroshare: retroshare core library * + * * + * Copyright (C) 2021 Gioacchino Mazzurco * + * Copyright (C) 2021 Asociación Civil Altermundi * + * * + * 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 "rs_android/rsjni.hpp" + +namespace jni +{ +Local> MakeAnything( + ThingToMake, JNIEnv& env, + const std::error_condition& ec ) +{ + auto& clazz = jni::Class::Singleton(env); + + static auto method = + clazz.GetConstructor(env); + + jni::jint value = ec.value(); + auto message = jni::Make(env, ec.message()); + auto category = jni::Make(env, ec.category().name()); + + return clazz.New(env, method, value, message, category); +} +} diff --git a/libretroshare/src/android_ifaddrs/ifaddrs-android.h b/libretroshare/src/rs_android/ifaddrs-android.h similarity index 100% rename from libretroshare/src/android_ifaddrs/ifaddrs-android.h rename to libretroshare/src/rs_android/ifaddrs-android.h diff --git a/libretroshare/src/rs_android/org/retroshare/service/AssetHelper.java b/libretroshare/src/rs_android/org/retroshare/service/AssetHelper.java new file mode 100644 index 000000000..c32aa5b5d --- /dev/null +++ b/libretroshare/src/rs_android/org/retroshare/service/AssetHelper.java @@ -0,0 +1,98 @@ +/* + * RetroShare + * Copyright (C) 2021 Gioacchino Mazzurco + * Copyright (C) 2021 Asociación Civil Altermundi + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero 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 Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + * + * SPDX-FileCopyrightText: Retroshare Team + * SPDX-License-Identifier: AGPL-3.0-or-later + */ + +package org.retroshare.service; + +import android.util.Log; +import android.content.Context; +import java.io.OutputStream; +import java.io.FileOutputStream; +import java.io.InputStream; +import java.io.IOException; + + +public class AssetHelper +{ + public static boolean copyAsset( + Context ctx, String assetPath, String destinationFilePath ) + { + Log.d(TAG, "copyAsset " + assetPath + " -> " + destinationFilePath); + + InputStream in; + OutputStream out; + + try { in = ctx.getAssets().open(assetPath); } + catch(Exception e) + { + Log.e( + TAG, + "Failure opening asset: " + assetPath + " " + e.getMessage() ); + return false; + } + + try { out = new FileOutputStream(destinationFilePath); } + catch(Exception e) + { + Log.e( + TAG, + "Failure opening destination: " + destinationFilePath + " " + + e.getMessage() ); + return false; + } + + try + { + byte[] buf = new byte[1024]; + int len; + while ((len = in.read(buf)) > 0) out.write(buf, 0, len); + } + catch(IOException e) + { + Log.e( + TAG, + "Failure coping: " + assetPath + " -> " + destinationFilePath + + " " + e.getMessage() ); + return false; + } + + try { in.close(); } + catch(IOException e) + { + Log.e(TAG, "Failure closing: " + assetPath + " " + e.getMessage() ); + return false; + } + + try { out.close(); } + catch(IOException e) + { + Log.e( + TAG, + "Failure closing: " + destinationFilePath + " " + + e.getMessage() ); + return false; + } + + return true; + } + + private static final String TAG = "RetroShare AssetHelper.java"; +} diff --git a/libretroshare/src/rs_android/org/retroshare/service/ErrorConditionWrap.java b/libretroshare/src/rs_android/org/retroshare/service/ErrorConditionWrap.java new file mode 100644 index 000000000..c0830f5d2 --- /dev/null +++ b/libretroshare/src/rs_android/org/retroshare/service/ErrorConditionWrap.java @@ -0,0 +1,48 @@ +/* + * RetroShare + * Copyright (C) 2021 Gioacchino Mazzurco + * Copyright (C) 2021 Asociación Civil Altermundi + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero 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 Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + * + * SPDX-FileCopyrightText: Retroshare Team + * SPDX-License-Identifier: AGPL-3.0-or-later + */ + +package org.retroshare.service; + +public class ErrorConditionWrap +{ + public ErrorConditionWrap( + int value, String message, String categoryName ) + { + mValue = value; + mMessage = message; + mCategoryName = categoryName; + } + + public int value() { return mValue; } + public String message() { return mMessage; } + public String categoryName() { return mCategoryName; } + + public boolean toBool() { return mValue != 0; } + + @Override + public String toString() + { return String.format("%d", mValue)+" "+mMessage+" [" + mCategoryName+ "]"; } + + private int mValue = 0; + private String mMessage; + private String mCategoryName; +} diff --git a/libretroshare/src/rs_android/org/retroshare/service/RetroShareServiceAndroid.java b/libretroshare/src/rs_android/org/retroshare/service/RetroShareServiceAndroid.java new file mode 100644 index 000000000..72fb57c32 --- /dev/null +++ b/libretroshare/src/rs_android/org/retroshare/service/RetroShareServiceAndroid.java @@ -0,0 +1,138 @@ +/* + * RetroShare + * Copyright (C) 2016-2021 Gioacchino Mazzurco + * Copyright (C) 2021 Asociación Civil Altermundi + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero 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 Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + * + * SPDX-FileCopyrightText: Retroshare Team + * SPDX-License-Identifier: AGPL-3.0-or-later + */ + +package org.retroshare.service; + +import android.app.Service; +import android.os.IBinder; +import android.os.Bundle; +import android.content.Context; +import android.content.Intent; +import android.util.Log; +import android.app.ActivityManager; +import java.util.Objects; + +public class RetroShareServiceAndroid extends Service +{ + public static final int DEFAULT_JSON_API_PORT = 9092; + public static final String DEFAULT_JSON_API_BINDING_ADDRESS = "127.0.0.1"; + + static { System.loadLibrary("retroshare-service"); } + + public static void start( + Context ctx, int jsonApiPort, String jsonApiBindAddress ) + { + Log.d(TAG, "start"); + Intent intent = new Intent(ctx, RetroShareServiceAndroid.class); + intent.putExtra(JSON_API_PORT_KEY, jsonApiPort); + intent.putExtra(JSON_API_BIND_ADDRESS_KEY, jsonApiBindAddress); + ctx.startService(intent); + } + + public static void stop(Context ctx) + { + Log.d(TAG, "stop"); + ctx.stopService(new Intent(ctx, RetroShareServiceAndroid.class)); + } + + public static boolean isRunning(Context ctx) + { + Log.d(TAG, "isRunning"); + ActivityManager manager = + (ActivityManager) ctx.getSystemService(Context.ACTIVITY_SERVICE); + for( ActivityManager.RunningServiceInfo service : + manager.getRunningServices(Integer.MAX_VALUE) ) + if( RetroShareServiceAndroid.class.getName() + .equals(service.service.getClassName()) ) + return true; + return false; + } + + public static Context getServiceContext() + { + if(sServiceContext == null) + Log.e(TAG, "getServiceContext() called before onCreate"); + return Objects.requireNonNull(sServiceContext); + } + + @Override + public int onStartCommand( + Intent intent, int flags, int startId ) + { + if(intent == null) + { + Log.i(TAG, "onStartCommand called without intent"); + return Service.START_REDELIVER_INTENT; + } + + int jsonApiPort = DEFAULT_JSON_API_PORT; + String jsonApiBindAddress = DEFAULT_JSON_API_BINDING_ADDRESS; + + Bundle args = intent.getExtras(); + if(args.containsKey(JSON_API_PORT_KEY)) + jsonApiPort = args.getInt(JSON_API_PORT_KEY); + if(args.containsKey(JSON_API_BIND_ADDRESS_KEY)) + jsonApiBindAddress = + args.getString(JSON_API_BIND_ADDRESS_KEY); + + ErrorConditionWrap ec = nativeStart(jsonApiPort, jsonApiBindAddress); + if(ec.toBool()) Log.e(TAG, "onStartCommand(...) " + ec.toString()); + + return super.onStartCommand(intent, flags, startId); + } + + @Override + public void onCreate () + { + super.onCreate(); + sServiceContext = this; + } + + @Override + public void onDestroy() + { + ErrorConditionWrap ec = nativeStop(); + if(ec.toBool()) Log.e(TAG, "onDestroy() " + ec.toString()); + sServiceContext = null; + super.onDestroy(); + } + + @Override + public IBinder onBind(Intent arg0) { return null; } + + private static final String JSON_API_PORT_KEY = + RetroShareServiceAndroid.class.getCanonicalName() + + "/JSON_API_PORT_KEY"; + + private static final String JSON_API_BIND_ADDRESS_KEY = + RetroShareServiceAndroid.class.getCanonicalName() + + "/JSON_API_BIND_ADDRESS_KEY" ; + + private static final String TAG = "RetroShareServiceAndroid.java"; + + private static Context sServiceContext; + + protected static native ErrorConditionWrap nativeStart( + int jsonApiPort, String jsonApiBindAddress ); + + protected static native ErrorConditionWrap nativeStop(); +} diff --git a/libretroshare/src/rs_android/retroshareserviceandroid.cpp b/libretroshare/src/rs_android/retroshareserviceandroid.cpp new file mode 100644 index 000000000..6e156edca --- /dev/null +++ b/libretroshare/src/rs_android/retroshareserviceandroid.cpp @@ -0,0 +1,103 @@ +/* + * RetroShare Service Android + * Copyright (C) 2016-2021 Gioacchino Mazzurco + * Copyright (C) 2021 Asociación Civil Altermundi + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero 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 Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + * + * SPDX-FileCopyrightText: Retroshare Team + * SPDX-License-Identifier: AGPL-3.0-or-later + */ + +#include +#include + +#include "util/stacktrace.h" +#include "retroshare/rsinit.h" +#include "retroshare/rsiface.h" +#include "util/rsdebug.h" + +#include "rs_android/retroshareserviceandroid.hpp" +#include "rs_android/rsjni.hpp" + + +/*static*/ std::unique_ptr +RetroShareServiceAndroid::sAndroidCoutCerrCatcher = nullptr; + +using ErrorConditionWrap = RsJni::ErrorConditionWrap; + +/*static*/ jni::Local> +RetroShareServiceAndroid::start( + JNIEnv& env, jni::Class&, + jni::jint jsonApiPort, const jni::String& jsonApiBindAddress ) +{ + if(jsonApiPort < 0 || jsonApiPort > std::numeric_limits::max()) + { + RS_ERR("Got invalid JSON API port: ", jsonApiPort); + return jni::Make(env, std::errc::invalid_argument); + } + + RsInfo() << "\n" << + "+================================================================+\n" + "| o---o o |\n" + "| \\ / - Retroshare Service Android - / \\ |\n" + "| o o---o |\n" + "+================================================================+" + << std::endl << std::endl; + + sAndroidCoutCerrCatcher = std::make_unique(); + + RsInit::InitRsConfig(); + RsControl::earlyInitNotificationSystem(); + + RsConfigOptions conf; + conf.jsonApiPort = static_cast(jsonApiPort); + conf.jsonApiBindAddress = jni::Make(env, jsonApiBindAddress); + + // Dirty workaround plugins not supported on Android ATM + conf.main_executable_path = " "; + + int initResult = RsInit::InitRetroShare(conf); + if(initResult != RS_INIT_OK) + { + RS_ERR("Retroshare core initalization failed with: ", initResult); + return jni::Make(env, std::errc::no_child_process); + } + + return jni::Make(env, std::error_condition()); +} + +jni::Local> RetroShareServiceAndroid::stop( + JNIEnv& env, jni::Class& ) +{ + if(RsControl::instance()->isReady()) + { + RsControl::instance()->rsGlobalShutDown(); + return jni::Make(env, std::error_condition()); + } + + sAndroidCoutCerrCatcher.reset(); + + return jni::Make(env, std::errc::no_such_process); +} + +jni::Local > +RetroShareServiceAndroid::getAndroidContext(JNIEnv& env) +{ + auto& clazz = jni::Class::Singleton(env); + static auto method = + clazz.GetStaticMethod()>( + env, "getServiceContext" ); + return clazz.Call(env, method); +} diff --git a/libretroshare/src/rs_android/retroshareserviceandroid.hpp b/libretroshare/src/rs_android/retroshareserviceandroid.hpp new file mode 100644 index 000000000..bd8f88f31 --- /dev/null +++ b/libretroshare/src/rs_android/retroshareserviceandroid.hpp @@ -0,0 +1,84 @@ +/* + * RetroShare Service Android + * Copyright (C) 2016-2021 Gioacchino Mazzurco + * Copyright (C) 2021 Asociación Civil Altermundi + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero 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 Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + * + * SPDX-FileCopyrightText: Retroshare Team + * SPDX-License-Identifier: AGPL-3.0-or-later + */ +#pragma once + +#include +#include + +#include + +#include "rs_android/rsjni.hpp" +#include "rs_android/androidcoutcerrcatcher.hpp" + +#include "util/stacktrace.h" + +/** Provide native methods that are registered into corresponding Java class + * to start/stop RetroShare with reasonable comfort on Android platform */ +struct RetroShareServiceAndroid +{ + static constexpr auto Name() + { return "org/retroshare/service/RetroShareServiceAndroid"; } + + using ErrorConditionWrap = RsJni::ErrorConditionWrap; + + /** + * Called from RetroShareServiceAndroid Java to init libretroshare + * @param[in] env the usual JNI parafernalia + * @param[in] jclass the usual JNI parafernalia + * @param[in] jsonApiPort port on which JSON API server will listen + * @param[in] jsonApiBindAddress binding address of the JSON API server + * @note Yeah you read it well we use a full 32 bit signed integer for JSON + * API port. This is because Java lack even the minimum decency to implement + * unsigned integral types so we need to wrap the port (16 bit unsigned + * integer everywhere reasonable) into a full integer and then check at + * runtime the value. + */ + static jni::Local> start( + JNIEnv& env, jni::Class& jclass, + jni::jint jsonApiPort, const jni::String& jsonApiBindAddress ); + + /** + * Called from RetroShareServiceAndroid Java to shutdown libretroshare + * @param[in] env the usual JNI parafernalia + * @param[in] jclass the usual JNI parafernalia + */ + static jni::Local> stop( + JNIEnv& env, jni::Class& ); + + struct Context + { + /// JNI parafernalia + static constexpr auto Name() { return "android/content/Context"; } + }; + + /// Return RetroShare Service Android Context + static jni::Local> getAndroidContext(JNIEnv& env); + +private: + /** Doesn't involve complex liftime handling stuff better let the runtime + * handle costruction (ASAP)/destruction for us */ + static CrashStackTrace CrashStackTrace; + + /** Involve threads, file descriptors etc. better handle lifetime + * explicitely */ + static std::unique_ptr sAndroidCoutCerrCatcher; +}; diff --git a/libretroshare/src/rs_android/rsjni.cpp b/libretroshare/src/rs_android/rsjni.cpp new file mode 100644 index 000000000..c9fc2c8ed --- /dev/null +++ b/libretroshare/src/rs_android/rsjni.cpp @@ -0,0 +1,70 @@ +/******************************************************************************* + * RetroShare JNI utilities * + * * + * libretroshare: retroshare core library * + * * + * Copyright (C) 2021 Gioacchino Mazzurco * + * Copyright (C) 2021 Asociación Civil Altermundi * + * * + * 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 "rs_android/rsjni.hpp" +#include "rs_android/retroshareserviceandroid.hpp" + +rs_view_ptr RsJni::mJvm = nullptr; + + +extern "C" JNIEXPORT jint JNICALL JNI_OnLoad_retroshare(JavaVM* vm, void*) +{ + RS_DBG(vm); + + RsJni::mJvm = vm; + + jni::JNIEnv& env { jni::GetEnv(*vm) }; + + /** Ensure singleton refereces to our own Java classes are inizialized here + * because default Java class loader which is the one accessible by native + * threads which is not main even if attached, is not capable to find them. + * https://stackoverflow.com/questions/20752352/classnotfoundexception-when-finding-a-class-in-jni-background-thread + * https://groups.google.com/g/android-ndk/c/2gkr1mXKn_E */ + jni::Class::Singleton(env); + jni::Class::Singleton(env); + + jni::RegisterNatives( + env, *jni::Class::Singleton(env), + jni::MakeNativeMethod< + decltype(&RetroShareServiceAndroid::start), + &RetroShareServiceAndroid::start >("nativeStart"), + jni::MakeNativeMethod< + decltype(&RetroShareServiceAndroid::stop), + &RetroShareServiceAndroid::stop >("nativeStop") + ); + + return jni::Unwrap(jni::jni_version_1_2); +} + +#ifdef RS_LIBRETROSHARE_EXPORT_JNI_ONLOAD +/** If libretroshare is linked statically to other components which already + * export JNI_OnLoad then a symbol clash may happen + * if RS_LIBRETROSHARE_EXPORT_JNI_ONLOAD is defined. + * @see JNI_OnLoad_retroshare should instead be called from the exported + * JNI_OnLoad */ +extern "C" JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM* vm, void* _reserved) +{ + RS_DBG(vm); + return JNI_OnLoad_retroshare(vm, _reserved); +} +#endif // def RS_LIBRETROSHARE_EXPORT_JNI_ONLOAD diff --git a/libretroshare/src/rs_android/rsjni.hpp b/libretroshare/src/rs_android/rsjni.hpp new file mode 100644 index 000000000..339dfd5c7 --- /dev/null +++ b/libretroshare/src/rs_android/rsjni.hpp @@ -0,0 +1,90 @@ +/******************************************************************************* + * RetroShare JNI utilities * + * * + * libretroshare: retroshare core library * + * * + * Copyright (C) 2021 Gioacchino Mazzurco * + * Copyright (C) 2021 Asociación Civil Altermundi * + * * + * 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 + +#include +#include + +#include + +#include "util/rsmemory.h" +#include "util/cxx23retrocompat.h" + + +/** Store JVM pointer safely and register native methods */ +extern "C" JNIEXPORT jint JNICALL JNI_OnLoad_retroshare(JavaVM* vm, void*); + + +/** Provide library wide JVM access with some safe measures + * The JVM pointer is set properly by @see JNI_OnLoad_retroshare + */ +class RsJni +{ +public: + static inline JavaVM& getVM() + { + if(!mJvm) // [[unlikely]] + { + RS_FATAL( "Attempt to access JVM before JNI_OnLoad_retroshare ", + std::errc::bad_address ); + print_stacktrace(); + std::exit(std::to_underlying(std::errc::bad_address)); + } + + return *mJvm; + } + + friend jint JNI_OnLoad_retroshare(JavaVM* vm, void*); + + /** Provide a comfortable way to access Android package assets like + * bdboot.txt from C++ */ + struct AssetHelper + { + static constexpr auto Name() + { return "org/retroshare/service/AssetHelper"; } + }; + + /** Provide a comfortable way to propagate C++ error_conditions to Java + * callers */ + struct ErrorConditionWrap + { + static constexpr auto Name() + { return "org/retroshare/service/ErrorConditionWrap"; } + }; + +private: + static rs_view_ptr mJvm; +}; + + +namespace jni +{ +/** Provides idiomatic way of creating instances via +@code{.cpp} + jni::Make(env, std::error_condition()); +@endcode */ +jni::Local> +MakeAnything( + jni::ThingToMake, JNIEnv& env, + const std::error_condition& ec ); +} diff --git a/libretroshare/src/rsserver/rsaccounts.cc b/libretroshare/src/rsserver/rsaccounts.cc index 8be56073c..1fa3802d1 100644 --- a/libretroshare/src/rsserver/rsaccounts.cc +++ b/libretroshare/src/rsserver/rsaccounts.cc @@ -32,12 +32,12 @@ #include #include - +#include #include #include "retroshare/rsinit.h" #include "rsaccounts.h" - +#include "util/rsdebug.h" #include "util/rsdir.h" #include "util/rsstring.h" #include "util/folderiterator.h" @@ -48,6 +48,11 @@ #include +#ifdef __ANDROID__ +# include "rs_android/rsjni.hpp" +# include "rs_android/retroshareserviceandroid.hpp" +#endif + // Global singleton declaration of data. RsAccountsDetail* RsAccounts::rsAccountsDetails = nullptr; @@ -328,22 +333,7 @@ bool RsAccountsDetail::defaultBaseDirectory() { std::string basedir; -/******************************** WINDOWS/UNIX SPECIFIC PART ******************/ -#ifndef WINDOWS_SYS - - // unix: homedir + /.retroshare - char *h = getenv("HOME"); - if (h == NULL) - { - std::cerr << "defaultBaseDirectory() Error: cannot determine $HOME dir" - << std::endl; - return false ; - } - - basedir = h; - basedir += "/.retroshare"; - -#else +#ifdef WINDOWS_SYS if (RsInit::isPortable()) { // use directory "Data" in portable version @@ -375,13 +365,53 @@ bool RsAccountsDetail::defaultBaseDirectory() } basedir += "\\RetroShare"; } -#endif -/******************************** WINDOWS/UNIX SPECIFIC PART ******************/ +#elif defined (__ANDROID__) // def WINDOWS_SYS + + struct ApplicationInfo + { + static constexpr auto Name() + { return "android/content/pm/ApplicationInfo"; } + }; + + auto uenv = jni::GetAttachedEnv(RsJni::getVM()); + JNIEnv& env = *uenv; + auto androidContext = RetroShareServiceAndroid::getAndroidContext(env); + auto& contextClass = + jni::Class::Singleton(env); + + auto& applicationInfoClass = jni::Class::Singleton(env); + + auto getApplicationInfo = + contextClass.GetMethod ()>( + env, "getApplicationInfo" ); + + auto applicationInfo = androidContext.Call(env, getApplicationInfo); + + auto dataDirField = jni::Field( + env, applicationInfoClass, "dataDir" ); + + jni::Local dataDir = applicationInfo.Get( + env, dataDirField ); + + basedir = jni::Make(env, dataDir) + "/.retroshare/"; + +#else // def WINDOWS_SYS, if defined (__ANDROID__) + // unix: homedir + /.retroshare + char* h = getenv("HOME"); + if(h == nullptr) + { + RS_ERR("cannot determine $HOME dir"); + return false ; + } + + basedir = h; + basedir += "/.retroshare"; +#endif // def WINDOWS_SYS /* store to class variable */ mBaseDirectory = basedir; - std::cerr << "defaultBaseDirectory() = " << mBaseDirectory; - std::cerr << std::endl; + + RS_INFO(mBaseDirectory); return true; } @@ -941,6 +971,11 @@ bool RsAccountsDetail::exportIdentityToString( bool RsAccountsDetail::copyGnuPGKeyrings() { +#ifdef __ANDROID__ + RS_ERR(std::errc::not_supported); + print_stacktrace(); + return false; +#else std::string pgp_dir = PathPGPDirectory() ; if(!RsDirUtil::checkCreateDirectory(pgp_dir)) @@ -992,6 +1027,7 @@ bool RsAccountsDetail::copyGnuPGKeyrings() } return true ; +#endif // def __ANDROID__ } diff --git a/libretroshare/src/rsserver/rsinit.cc b/libretroshare/src/rsserver/rsinit.cc index 7433ab151..67452d8b7 100644 --- a/libretroshare/src/rsserver/rsinit.cc +++ b/libretroshare/src/rsserver/rsinit.cc @@ -32,8 +32,9 @@ #endif #ifdef __ANDROID__ -# include // To install bdboot.txt -# include // for QString::fromStdString(...) +# include +# include "rs_android/rsjni.hpp" +# include "rs_android/retroshareserviceandroid.hpp" #endif #include "util/argstream.h" @@ -194,7 +195,7 @@ static const int SSLPWD_LEN = 64; void RsInit::InitRsConfig() { - RsInfo() << " libretroshare version: " << RS_HUMAN_READABLE_VERSION + RsInfo() << "libretroshare version: " << RS_HUMAN_READABLE_VERSION << std::endl; rsInitConfig = new RsInitConfig; @@ -1011,32 +1012,32 @@ int RsServer::StartupRetroShare() uint64_t tmp_size ; if (!RsDirUtil::checkFile(bootstrapfile,tmp_size,true)) { - std::cerr << "DHT bootstrap file not in ConfigDir: " << bootstrapfile - << std::endl; -#ifdef __ANDROID__ - QFile bdbootRF("assets:/values/bdboot.txt"); - if(!bdbootRF.open(QIODevice::ReadOnly | QIODevice::Text)) - std::cerr << __PRETTY_FUNCTION__ - << " bdbootRF(assets:/values/bdboot.txt).open(...) fail: " - << bdbootRF.errorString().toStdString() << std::endl; - else - { - QFile bdbootCF(QString::fromStdString(bootstrapfile)); - if(!bdbootCF.open(QIODevice::WriteOnly | QIODevice::Text)) - std::cerr << __PRETTY_FUNCTION__ << " bdbootCF(" - << bootstrapfile << ").open(...) fail: " - << bdbootRF.errorString().toStdString() << std::endl; - else - { - bdbootCF.write(bdbootRF.readAll()); - bdbootCF.close(); - std::cerr << "Installed DHT bootstrap file not in ConfigDir: " - << bootstrapfile << std::endl; - } + RS_INFO("DHT bootstrap file not in ConfigDir: ", bootstrapfile); - bdbootRF.close(); - } -#else +#ifdef __ANDROID__ + auto uenv = jni::GetAttachedEnv(RsJni::getVM()); + JNIEnv& env = *uenv; + + using AContext = RetroShareServiceAndroid::Context; + + auto& assetHelperClass = jni::Class::Singleton(env); + + static auto copyAsset = + assetHelperClass.GetStaticMethod< + jni::jboolean(jni::Object, jni::String, jni::String)>( + env, "copyAsset" ); + + auto androidContext = RetroShareServiceAndroid::getAndroidContext(env); + + jni::jboolean result = assetHelperClass.Call( + env, copyAsset, + androidContext, + jni::Make(env, "values/bdboot.txt"), + jni::Make(env, bootstrapfile) ); + + if(!result) RS_ERR("Failure installing ", bootstrapfile); + +#else // def __ANDROID__ std::cerr << "Checking for Installation DHT bootstrap file " << installfile << std::endl; if ((installfile != "") && (RsDirUtil::checkFile(installfile,tmp_size))) { diff --git a/libretroshare/src/services/broadcastdiscoveryservice.cc b/libretroshare/src/services/broadcastdiscoveryservice.cc index 076244b44..98b67cdcd 100644 --- a/libretroshare/src/services/broadcastdiscoveryservice.cc +++ b/libretroshare/src/services/broadcastdiscoveryservice.cc @@ -1,7 +1,8 @@ /******************************************************************************* * RetroShare Broadcast Domain Discovery * * * - * Copyright (C) 2019 Gioacchino Mazzurco * + * Copyright (C) 2019-2021 Gioacchino Mazzurco * + * Copyright (C) 2019-2021 Asociación Civil Altermundi * * * * This program is free software: you can redistribute it and/or modify * * it under the terms of the GNU Lesser General Public License as * @@ -25,16 +26,17 @@ #include #include -#ifdef __ANDROID__ -# include -#endif // def __ANDROID__ - #include "services/broadcastdiscoveryservice.h" #include "retroshare/rspeers.h" #include "serialiser/rsserializable.h" #include "serialiser/rsserializer.h" #include "retroshare/rsevents.h" +#ifdef __ANDROID__ +# include "rs_android/retroshareserviceandroid.hpp" +#endif // def __ANDROID__ + + /*extern*/ RsBroadcastDiscovery* rsBroadcastDiscovery = nullptr; struct BroadcastDiscoveryPack : RsSerializable @@ -99,7 +101,7 @@ BroadcastDiscoveryService::BroadcastDiscoveryService( if(mRsPeers.isHiddenNode(mRsPeers.getOwnId())) return; #ifdef __ANDROID__ - createMulticastLock(); + createAndroidMulticastLock(); #endif // def __ANDROID__ enableMulticastListening(); @@ -228,19 +230,47 @@ RsBroadcastDiscoveryResult BroadcastDiscoveryService::createResult( bool BroadcastDiscoveryService::isMulticastListeningEnabled() { #ifdef __ANDROID__ - return assertMulticastLockIsvalid() && - mWifiMulticastLock.callMethod("isHeld"); -#endif // def __ANDROID__ + if(!mAndroidWifiMulticastLock) + { + RS_ERR("Android multicast lock not initialized!"); + return false; + } + auto uenv = jni::GetAttachedEnv(RsJni::getVM()); + JNIEnv& env = *uenv; + auto& multicastLockClass = jni::Class::Singleton(env); + + auto isHeld = + multicastLockClass.GetMethod( + env, "isHeld" ); + + return mAndroidWifiMulticastLock.Call(env, isHeld); +#else if // def __ANDROID__ return true; +#endif // def __ANDROID__ } bool BroadcastDiscoveryService::enableMulticastListening() { #ifdef __ANDROID__ - if(assertMulticastLockIsvalid() && !isMulticastListeningEnabled()) + if(!mAndroidWifiMulticastLock) { - mWifiMulticastLock.callMethod("acquire"); + RS_ERR("Android multicast lock not initialized!"); + return false; + } + + if(!isMulticastListeningEnabled()) + { + auto uenv = jni::GetAttachedEnv(RsJni::getVM()); + JNIEnv& env = *uenv; + auto& multicastLockClass = jni::Class::Singleton(env); + + auto acquire = + multicastLockClass.GetMethod( + env, "acquire" ); + + mAndroidWifiMulticastLock.Call(env, acquire); + return true; } #endif // def __ANDROID__ @@ -251,9 +281,24 @@ bool BroadcastDiscoveryService::enableMulticastListening() bool BroadcastDiscoveryService::disableMulticastListening() { #ifdef __ANDROID__ - if(assertMulticastLockIsvalid() && isMulticastListeningEnabled()) + if(!mAndroidWifiMulticastLock) { - mWifiMulticastLock.callMethod("release"); + RS_ERR("Android multicast lock not initialized!"); + return false; + } + + if(isMulticastListeningEnabled()) + { + auto uenv = jni::GetAttachedEnv(RsJni::getVM()); + JNIEnv& env = *uenv; + auto& multicastLockClass = jni::Class::Singleton(env); + + auto release = + multicastLockClass.GetMethod( + env, "release" ); + + mAndroidWifiMulticastLock.Call(env, release); + return true; } #endif // def __ANDROID__ @@ -262,56 +307,57 @@ bool BroadcastDiscoveryService::disableMulticastListening() } #ifdef __ANDROID__ -bool BroadcastDiscoveryService::createMulticastLock() + +bool BroadcastDiscoveryService::createAndroidMulticastLock() { - Dbg2() << __PRETTY_FUNCTION__ << std::endl; - - constexpr auto fname = __PRETTY_FUNCTION__; - const auto failure = [&](const std::string& err) + if(mAndroidWifiMulticastLock) { - RsErr() << fname << " " << err << std::endl; - return false; - }; - - if(mWifiMulticastLock.isValid()) - return failure("mWifiMulticastLock is already initialized"); - - QAndroidJniObject context = QtAndroid::androidContext(); - if(!context.isValid()) - return failure("Cannot retrieve Android context"); - - QAndroidJniObject WIFI_SERVICE = QAndroidJniObject::getStaticObjectField( - "android.content.Context", "WIFI_SERVICE", "Ljava/lang/String;"); - if(!WIFI_SERVICE.isValid()) - return failure("Cannot retrieve Context.WIFI_SERVICE value"); - - QAndroidJniObject wifiManager = context.callObjectMethod( - "getSystemService", "(Ljava/lang/String;)Ljava/lang/Object;", - WIFI_SERVICE.object() ); - if(!wifiManager.isValid()) - return failure("Cannot retrieve Android Wifi Manager"); - - mWifiMulticastLock = wifiManager.callObjectMethod( - "createMulticastLock", - "(Ljava/lang/String;)Landroid/net/wifi/WifiManager$MulticastLock;", - QAndroidJniObject::fromString(fname).object() ); - if(!mWifiMulticastLock.isValid()) - return failure("Cannot create WifiManager.MulticastLock"); - - return true; -} - -bool BroadcastDiscoveryService::assertMulticastLockIsvalid() -{ - if(!mWifiMulticastLock.isValid()) - { - RsErr() << __PRETTY_FUNCTION__ << " mWifiMulticastLock is invalid!" - << std::endl; + RS_ERR("Android multicast lock is already initialized"); print_stacktrace(); return false; } + + auto uenv = jni::GetAttachedEnv(RsJni::getVM()); + JNIEnv& env = *uenv; + + using AContextTag = RetroShareServiceAndroid::Context; + using AContext = jni::Class; + static auto& contextClass = AContext::Singleton(env); + + auto wifiServiceField = jni::StaticField( + env, contextClass, "WIFI_SERVICE"); + + jni::Local WIFI_SERVICE = contextClass.Get( + env, wifiServiceField ); + + auto androidContext = RetroShareServiceAndroid::getAndroidContext(env); + + auto getSystemService = + contextClass.GetMethod (jni::String)>( + env, "getSystemService" ); + + struct WifiManager + { static constexpr auto Name() { return "android/net/wifi/WifiManager"; } }; + + auto& wifiManagerClass = jni::Class::Singleton(env); + + auto wifiManager = jni::Cast( + env, wifiManagerClass, + androidContext.Call(env, getSystemService, WIFI_SERVICE) ); + + auto createMulticastLock = + wifiManagerClass.GetMethod(jni::String)>( + env, "createMulticastLock" ); + + mAndroidWifiMulticastLock = jni::NewGlobal( + env, wifiManager.Call( + env, createMulticastLock, + jni::Make( + env, "RetroShare BroadcastDiscoveryService" ) ) ); + return true; } + #endif // def __ANDROID__ RsBroadcastDiscovery::~RsBroadcastDiscovery() = default; diff --git a/libretroshare/src/services/broadcastdiscoveryservice.h b/libretroshare/src/services/broadcastdiscoveryservice.h index ebbec04c1..f4204c324 100644 --- a/libretroshare/src/services/broadcastdiscoveryservice.h +++ b/libretroshare/src/services/broadcastdiscoveryservice.h @@ -1,7 +1,8 @@ /******************************************************************************* * RetroShare Broadcast Domain Discovery * * * - * Copyright (C) 2019 Gioacchino Mazzurco * + * Copyright (C) 2019-2021 Gioacchino Mazzurco * + * Copyright (C) 2019-2021 Asociación Civil Altermundi * * * * This program is free software: you can redistribute it and/or modify * * it under the terms of the GNU Lesser General Public License as * @@ -27,14 +28,16 @@ #include -#ifdef __ANDROID__ -# include -#endif // def __ANDROID__ - #include "retroshare/rsbroadcastdiscovery.h" #include "util/rsthreads.h" #include "util/rsdebug.h" +#ifdef __ANDROID__ +# include +# include "rs_android/rsjni.hpp" +#endif // def __ANDROID__ + + namespace UDC = udpdiscovery; class RsPeers; @@ -42,7 +45,7 @@ class BroadcastDiscoveryService : public RsBroadcastDiscovery, public RsTickingThread { public: - BroadcastDiscoveryService(RsPeers& pRsPeers); + explicit BroadcastDiscoveryService(RsPeers& pRsPeers); ~BroadcastDiscoveryService() override; /// @see RsBroadcastDiscovery @@ -71,26 +74,27 @@ protected: std::map mDiscoveredData; RsMutex mDiscoveredDataMutex; - RsPeers& mRsPeers; // TODO: std::shared_ptr mRsPeers; + RsPeers& mRsPeers; RsBroadcastDiscoveryResult createResult( const UDC::IpPort& ipp, const std::string& uData ); #ifdef __ANDROID__ - /** Android WifiManager.MulticastLock */ - QAndroidJniObject mWifiMulticastLock; + struct AndroidMulticastLock + { + static constexpr auto Name() + { return "android/net/wifi/WifiManager$MulticastLock"; } + }; + + jni::Global> mAndroidWifiMulticastLock; /** Initialize the wifi multicast lock without acquiring it * Needed to enable multicast listening in Android, for RetroShare broadcast * discovery inspired by: * https://github.com/flutter/flutter/issues/16335#issuecomment-420547860 */ - bool createMulticastLock(); - - /** Return false if mWifiMulticastLock is invalid and print error messages */ - bool assertMulticastLockIsvalid(); - -#endif // def __ANDROID__ + bool createAndroidMulticastLock(); +#endif RS_SET_CONTEXT_DEBUG_LEVEL(3) }; diff --git a/libretroshare/src/use_libretroshare.pri b/libretroshare/src/use_libretroshare.pri index a34951772..7ceda74ba 100644 --- a/libretroshare/src/use_libretroshare.pri +++ b/libretroshare/src/use_libretroshare.pri @@ -111,14 +111,7 @@ PRE_TARGETDEPS += $$pretargetStaticLibs(sLibs) LIBS += $$linkDynamicLibs(dLibs) android-* { - CONFIG *= qt - - lessThan(ANDROID_API_VERSION, 24) { - ## @See: android_ifaddrs/README.adoc - contains(DEFINES, LIBRETROSHARE_ANDROID_IFADDRS_QT) { - QT *= network - } - } + INCLUDEPATH *= $$clean_path($${RS_SRC_PATH}/supportlibs/jni.hpp/include/) } ################################### Pkg-Config Stuff ############################# diff --git a/retroshare-service/src/android/AndroidManifest.xml b/retroshare-service/src/android/AndroidManifest.xml index d41a72995..ecf8ba78a 100644 --- a/retroshare-service/src/android/AndroidManifest.xml +++ b/retroshare-service/src/android/AndroidManifest.xml @@ -2,9 +2,9 @@ - + @@ -14,59 +14,81 @@ - - - - - - - - - - - - - + + + + + - + + + + - - - - +]]> + + + + + + + + + + + + + + + +]]> + + + + + + + + + + + + + @@ -76,17 +98,11 @@ ++ features based on the dependencies of the application. ++ Remove the comment if you do not require these default features. --> +]]> - + - - - - - - - - - + --> +]]> diff --git a/retroshare-service/src/android/src/org/retroshare/service/AppUpdatedReceiver.java b/retroshare-service/src/android/src/org/retroshare/service/AppUpdatedReceiver.java index 283fd10cc..3f2e3f375 100644 --- a/retroshare-service/src/android/src/org/retroshare/service/AppUpdatedReceiver.java +++ b/retroshare-service/src/android/src/org/retroshare/service/AppUpdatedReceiver.java @@ -19,6 +19,7 @@ * SPDX-License-Identifier: AGPL-3.0-or-later */ +/* package org.retroshare.service; import android.content.BroadcastReceiver; @@ -36,3 +37,4 @@ public class AppUpdatedReceiver extends BroadcastReceiver RetroShareServiceAndroid.start(context); } } +*/ \ No newline at end of file diff --git a/retroshare-service/src/android/src/org/retroshare/service/AssetHelper.java b/retroshare-service/src/android/src/org/retroshare/service/AssetHelper.java new file mode 120000 index 000000000..60da18398 --- /dev/null +++ b/retroshare-service/src/android/src/org/retroshare/service/AssetHelper.java @@ -0,0 +1 @@ +../../../../../../../libretroshare/src/rs_android/org/retroshare/service/AssetHelper.java \ No newline at end of file diff --git a/retroshare-service/src/android/src/org/retroshare/service/BootCompletedReceiver.java b/retroshare-service/src/android/src/org/retroshare/service/BootCompletedReceiver.java index 89c09c241..75bfbc063 100644 --- a/retroshare-service/src/android/src/org/retroshare/service/BootCompletedReceiver.java +++ b/retroshare-service/src/android/src/org/retroshare/service/BootCompletedReceiver.java @@ -19,6 +19,7 @@ * SPDX-License-Identifier: AGPL-3.0-or-later */ +/* package org.retroshare.service; import android.content.BroadcastReceiver; @@ -35,3 +36,4 @@ public class BootCompletedReceiver extends BroadcastReceiver RetroShareServiceAndroid.start(context); } } +*/ \ No newline at end of file diff --git a/retroshare-service/src/android/src/org/retroshare/service/ErrorConditionWrap.java b/retroshare-service/src/android/src/org/retroshare/service/ErrorConditionWrap.java new file mode 120000 index 000000000..1f90a62c6 --- /dev/null +++ b/retroshare-service/src/android/src/org/retroshare/service/ErrorConditionWrap.java @@ -0,0 +1 @@ +../../../../../../../libretroshare/src/rs_android/org/retroshare/service/ErrorConditionWrap.java \ No newline at end of file diff --git a/retroshare-service/src/android/src/org/retroshare/service/RetroShareServiceAndroid.java b/retroshare-service/src/android/src/org/retroshare/service/RetroShareServiceAndroid.java deleted file mode 100644 index 3cea999bf..000000000 --- a/retroshare-service/src/android/src/org/retroshare/service/RetroShareServiceAndroid.java +++ /dev/null @@ -1,50 +0,0 @@ -/* - * RetroShare - * Copyright (C) 2016-2018 Gioacchino Mazzurco - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero 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 Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see . - * - * SPDX-FileCopyrightText: Retroshare Team - * SPDX-License-Identifier: AGPL-3.0-or-later - */ - -package org.retroshare.service; - -import android.app.ActivityManager; -import android.content.Context; -import android.content.Intent; - -import org.qtproject.qt5.android.bindings.QtService; - -public class RetroShareServiceAndroid extends QtService -{ - public static void start(Context ctx) - { - ctx.startService(new Intent(ctx, RetroShareServiceAndroid.class)); - } - - public static void stop(Context ctx) - { - ctx.stopService(new Intent(ctx, RetroShareServiceAndroid.class)); - } - - public static boolean isRunning(Context ctx) - { - ActivityManager manager = (ActivityManager) ctx.getSystemService(Context.ACTIVITY_SERVICE); - for (ActivityManager.RunningServiceInfo service : manager.getRunningServices(Integer.MAX_VALUE)) - if (RetroShareServiceAndroid.class.getName().equals(service.service.getClassName())) - return true; - return false; - } -} diff --git a/retroshare-service/src/android/src/org/retroshare/service/RetroShareServiceAndroid.java b/retroshare-service/src/android/src/org/retroshare/service/RetroShareServiceAndroid.java new file mode 120000 index 000000000..480e21ac4 --- /dev/null +++ b/retroshare-service/src/android/src/org/retroshare/service/RetroShareServiceAndroid.java @@ -0,0 +1 @@ +../../../../../../../libretroshare/src/rs_android/org/retroshare/service/RetroShareServiceAndroid.java \ No newline at end of file diff --git a/retroshare-service/src/android/src/org/retroshare/service/RetroShareServiceControlActivity.java b/retroshare-service/src/android/src/org/retroshare/service/RetroShareServiceControlActivity.java index d1e1f78b7..dafe10301 100644 --- a/retroshare-service/src/android/src/org/retroshare/service/RetroShareServiceControlActivity.java +++ b/retroshare-service/src/android/src/org/retroshare/service/RetroShareServiceControlActivity.java @@ -1,6 +1,6 @@ /* * RetroShare - * Copyright (C) 2016-2018 Gioacchino Mazzurco + * Copyright (C) 2016-2021 Gioacchino Mazzurco * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as @@ -50,7 +50,11 @@ public class RetroShareServiceControlActivity extends Activity else { button.setText("Starting..."); - RetroShareServiceAndroid.start(RetroShareServiceControlActivity.this); + RetroShareServiceAndroid.start( + RetroShareServiceControlActivity.this, + RetroShareServiceAndroid.DEFAULT_JSON_API_PORT, + RetroShareServiceAndroid.DEFAULT_JSON_API_BINDING_ADDRESS + ); serviceStarting = true; serviceStopping = false; } diff --git a/retroshare-service/src/retroshare-service-android.cc b/retroshare-service/src/retroshare-service-android.cc new file mode 100644 index 000000000..30204c8fd --- /dev/null +++ b/retroshare-service/src/retroshare-service-android.cc @@ -0,0 +1,29 @@ +/* + * RetroShare Service Android + * Copyright (C) 2021 Gioacchino Mazzurco + * Copyright (C) 2021 Asociación Civil Altermundi + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero 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 Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + * + * SPDX-FileCopyrightText: Retroshare Team + * SPDX-License-Identifier: AGPL-3.0-or-later + */ + +#include "rs_android/rsjni.hpp" + +extern "C" JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM* vm, void* _reserved) +{ + RS_DBG(vm); + return JNI_OnLoad_retroshare(vm, _reserved); +} diff --git a/retroshare-service/src/retroshare-service.cc b/retroshare-service/src/retroshare-service.cc index e80d468e1..3aad20a8c 100644 --- a/retroshare-service/src/retroshare-service.cc +++ b/retroshare-service/src/retroshare-service.cc @@ -1,6 +1,7 @@ /* * RetroShare Service - * Copyright (C) 2016-2019 Gioacchino Mazzurco + * Copyright (C) 2016-2021 Gioacchino Mazzurco + * Copyright (C) 2021 Asociación Civil Altermundi * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as @@ -19,39 +20,31 @@ * SPDX-License-Identifier: AGPL-3.0-or-later */ -#include "util/stacktrace.h" -#include "util/argstream.h" -#include "util/rskbdinput.h" -#include "retroshare/rsinit.h" - -#ifdef RS_JSONAPI -#include "retroshare/rsjsonapi.h" - -#ifdef RS_WEBUI -#include "retroshare/rswebui.h" -#endif -#endif - -static CrashStackTrace gCrashStackTrace; #include #include #include #include -#ifdef __ANDROID__ -# include -# include -# include -# include - -# include "util/androiddebug.h" -#endif // def __ANDROID__ - +#include "util/stacktrace.h" +#include "util/argstream.h" +#include "util/rskbdinput.h" +#include "retroshare/rsinit.h" #include "retroshare/rsinit.h" #include "retroshare/rsiface.h" #include "util/rsdebug.h" +#ifdef RS_JSONAPI +# include "retroshare/rsjsonapi.h" + +# ifdef RS_WEBUI +# include "retroshare/rswebui.h" +# endif // def RS_WEBUI +#endif // def RS_JSONAPI + +static CrashStackTrace gCrashStackTrace; + + #ifdef RS_SERVICE_TERMINAL_LOGIN class RsServiceNotify: public NotifyClient { @@ -74,9 +67,6 @@ public: }; #endif // def RS_SERVICE_TERMINAL_LOGIN -#ifdef __ANDROID__ -void signalHandler(int /*signal*/) { QCoreApplication::exit(0); } -#else static std::atomic keepRunning(true); static int receivedSignal = 0; @@ -87,16 +77,10 @@ void signalHandler(int signal) receivedSignal = signal; keepRunning = false; } -#endif // def __ANDROID__ int main(int argc, char* argv[]) { -#ifdef __ANDROID__ - AndroidStdIOCatcher dbg; (void) dbg; - QAndroidService app(argc, argv); -#endif // def __ANDROID__ - signal(SIGINT, signalHandler); signal(SIGTERM, signalHandler); #ifdef SIGBREAK @@ -128,7 +112,7 @@ int main(int argc, char* argv[]) RsConfigOptions conf; #ifdef RS_JSONAPI - conf.jsonApiPort = RsJsonApi::DEFAULT_PORT; // enable JSonAPI by default + conf.jsonApiPort = RsJsonApi::DEFAULT_PORT; // enable JSON API by default #ifdef RS_WEBUI std::string webui_base_directory = RsWebUi::DEFAULT_BASE_DIRECTORY; #endif @@ -323,22 +307,10 @@ int main(int argc, char* argv[]) } #endif -#ifdef __ANDROID__ - rsControl->setShutdownCallback(QCoreApplication::exit); - - QObject::connect( - &app, &QCoreApplication::aboutToQuit, - [](){ - if(RsControl::instance()->isReady()) - RsControl::instance()->rsGlobalShutDown(); } ); - - return app.exec(); -#else // def __ANDROID__ rsControl->setShutdownCallback([&](int){keepRunning = false;}); while(keepRunning) std::this_thread::sleep_for(std::chrono::milliseconds(500)); return 0; -#endif } diff --git a/retroshare-service/src/retroshare-service.pro b/retroshare-service/src/retroshare-service.pro index cbd1b9d13..64d373e76 100644 --- a/retroshare-service/src/retroshare-service.pro +++ b/retroshare-service/src/retroshare-service.pro @@ -1,6 +1,6 @@ # RetroShare service qmake build script # -# Copyright (C) 2018-2019, Gioacchino Mazzurco +# Copyright (C) 2018-2021, Gioacchino Mazzurco # # This program is free software: you can redistribute it and/or modify it under # the terms of the GNU Affero General Public License as published by the @@ -22,8 +22,7 @@ TARGET = retroshare-service -QT += core -QT -= gui +CONFIG -= qt !include("../../libretroshare/src/use_libretroshare.pri"):error("Including") @@ -32,8 +31,6 @@ SOURCES += retroshare-service.cc ################################# Linux ########################################## android-* { - QT += androidextras - ANDROID_PACKAGE_SOURCE_DIR = $$PWD/android DISTFILES += android/AndroidManifest.xml \ @@ -45,6 +42,9 @@ android-* { android/build.gradle \ android/gradle/wrapper/gradle-wrapper.properties \ android/gradlew.bat + + SOURCES -= retroshare-service.cc + SOURCES += retroshare-service-android.cc } diff --git a/supportlibs/jni.hpp b/supportlibs/jni.hpp new file mode 160000 index 000000000..66f73a6aa --- /dev/null +++ b/supportlibs/jni.hpp @@ -0,0 +1 @@ +Subproject commit 66f73a6aa82367d6ba23e7e842f95dfb33c451d6 From 2095dae95d16347965d8fb5af4db81761133935a Mon Sep 17 00:00:00 2001 From: Gioacchino Mazzurco Date: Tue, 30 Nov 2021 17:00:02 +0100 Subject: [PATCH 041/113] Fix build with older Java < 7 --- .../org/retroshare/service/RetroShareServiceAndroid.java | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/libretroshare/src/rs_android/org/retroshare/service/RetroShareServiceAndroid.java b/libretroshare/src/rs_android/org/retroshare/service/RetroShareServiceAndroid.java index 72fb57c32..818f06348 100644 --- a/libretroshare/src/rs_android/org/retroshare/service/RetroShareServiceAndroid.java +++ b/libretroshare/src/rs_android/org/retroshare/service/RetroShareServiceAndroid.java @@ -29,7 +29,7 @@ import android.content.Context; import android.content.Intent; import android.util.Log; import android.app.ActivityManager; -import java.util.Objects; + public class RetroShareServiceAndroid extends Service { @@ -70,8 +70,11 @@ public class RetroShareServiceAndroid extends Service public static Context getServiceContext() { if(sServiceContext == null) + { Log.e(TAG, "getServiceContext() called before onCreate"); - return Objects.requireNonNull(sServiceContext); + throw new NullPointerException(); + } + return sServiceContext; } @Override From 7231d94ea4a876cc9e420917526d22ea6aedd72f Mon Sep 17 00:00:00 2001 From: Gioacchino Mazzurco Date: Tue, 30 Nov 2021 17:00:33 +0100 Subject: [PATCH 042/113] Fix variable name in Android Dockerfile documentation --- build_scripts/Android/Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build_scripts/Android/Dockerfile b/build_scripts/Android/Dockerfile index 2e4b8c762..081d9126e 100644 --- a/build_scripts/Android/Dockerfile +++ b/build_scripts/Android/Dockerfile @@ -2,7 +2,7 @@ ## image name must match gitlab repository name, you can play just with the tag ## the part after : # export CI_IMAGE_NAME="registry.gitlab.com/retroshare/retroshare:android_arm_base" -# docker build --squash -t "${CI_REGISTRY_IMAGE}" \ +# docker build --squash --tag "${CI_IMAGE_NAME}" \ # --build-arg QT_INSTALLER_JWT_TOKEN="your qt JWT token goes here" . # # To build Android ARMv8 (64 bit) package pass also From 3217cd4df067e89a8f6132ab2468b6def8e76966 Mon Sep 17 00:00:00 2001 From: Phenom Date: Mon, 29 Nov 2021 15:25:25 +0100 Subject: [PATCH 043/113] Fix BoardPostDisplayWidget when editor redraw. --- .../src/gui/Posted/BoardPostDisplayWidget.cpp | 51 ++----- .../src/gui/Posted/BoardPostDisplayWidget.h | 6 +- .../gui/Posted/BoardPostDisplayWidget_card.ui | 44 +++++- .../Posted/BoardPostDisplayWidget_compact.ui | 46 +++++- .../src/gui/Posted/PostedCardView.ui | 41 ++--- retroshare-gui/src/gui/Posted/PostedItem.ui | 56 +++---- .../gui/Posted/PostedListWidgetWithModel.cpp | 143 ++++++++++-------- retroshare-gui/src/gui/common/RSTreeView.cpp | 69 ++++++--- retroshare-gui/src/gui/common/RSTreeView.h | 24 ++- .../src/gui/qss/stylesheet/Standard_Dark.qss | 2 +- .../src/gui/qss/stylesheet/Standard_Light.qss | 2 +- 11 files changed, 281 insertions(+), 203 deletions(-) diff --git a/retroshare-gui/src/gui/Posted/BoardPostDisplayWidget.cpp b/retroshare-gui/src/gui/Posted/BoardPostDisplayWidget.cpp index 241c713d1..6d2cbb4a4 100644 --- a/retroshare-gui/src/gui/Posted/BoardPostDisplayWidget.cpp +++ b/retroshare-gui/src/gui/Posted/BoardPostDisplayWidget.cpp @@ -122,14 +122,14 @@ void BoardPostDisplayWidgetBase::setReadStatus(bool isNew, bool isUnread) void BoardPostDisplayWidget_compact::doExpand(bool e) { #ifdef DEBUG_BOARDPOSTDISPLAYWIDGET - std::cerr << "Expanding" << std::endl; + std::cerr << "Expanding" << std::endl; #endif - if(e) - ui->frame_notes->show(); - else - ui->frame_notes->hide(); + if(e) + ui->frame_notes->show(); + else + ui->frame_notes->hide(); - emit expand(mPost.mMeta.mMsgId,e); + emit expand(mPost.mMeta.mMsgId,e); } void BoardPostDisplayWidgetBase::loadComments(bool e) @@ -144,7 +144,7 @@ void BoardPostDisplayWidgetBase::readToggled() emit changeReadStatusRequested(mPost.mMeta.mMsgId,s); } -void BoardPostDisplayWidgetBase::setup() +void BoardPostDisplayWidgetBase::baseSetup() { // show/hide things based on the view type @@ -166,8 +166,6 @@ void BoardPostDisplayWidgetBase::setup() QAction *CopyLinkAction = new QAction(QIcon(""),tr("Copy RetroShare Link"), this); connect(CopyLinkAction, SIGNAL(triggered()), this, SLOT(handleCopyLinkClicked())); - int S = QFontMetricsF(font()).height() ; - readButton()->setChecked(false); QMenu *menu = new QMenu(); @@ -196,8 +194,6 @@ void BoardPostDisplayWidgetBase::setup() } else { - QPixmap sqpixmap2 = FilesDefs::getPixmapFromQtResourcePath(":/images/thumb-default.png"); - QDateTime qtime; qtime.setTime_t(mPost.mMeta.mPublishTs); QString timestamp = qtime.toString("hh:mm dd-MMM-yyyy"); @@ -295,16 +291,7 @@ BoardPostDisplayWidget_compact::BoardPostDisplayWidget_compact(const RsPostedPos : BoardPostDisplayWidgetBase(post,display_flags,parent), ui(new Ui::BoardPostDisplayWidget_compact()) { ui->setupUi(this); - setup(); - - ui->right_VL->addStretch(); - ui->right_VL->setAlignment(Qt::AlignTop); - ui->topLayout->setAlignment(Qt::AlignTop); - ui->arrowsLayout->addStretch(); - ui->arrowsLayout->setAlignment(Qt::AlignTop); - ui->feedFrame_VL->addStretch(); - - adjustSize(); + BoardPostDisplayWidget_compact::setup(); } BoardPostDisplayWidget_compact::~BoardPostDisplayWidget_compact() @@ -314,7 +301,7 @@ BoardPostDisplayWidget_compact::~BoardPostDisplayWidget_compact() void BoardPostDisplayWidget_compact::setup() { - BoardPostDisplayWidgetBase::setup(); + baseSetup(); // show/hide things based on the view type @@ -356,7 +343,7 @@ void BoardPostDisplayWidget_compact::setup() QObject::connect(ui->expandButton, SIGNAL(toggled(bool)), this, SLOT(doExpand(bool))); QTextDocument doc; - doc.setHtml(notes()->text()); + doc.setHtml(BoardPostDisplayWidget_compact::notes()->text()); if(mDisplayFlags & SHOW_NOTES) { @@ -427,16 +414,7 @@ BoardPostDisplayWidget_card::BoardPostDisplayWidget_card(const RsPostedPost& pos : BoardPostDisplayWidgetBase(post,display_flags,parent), ui(new Ui::BoardPostDisplayWidget_card()) { ui->setupUi(this); - setup(); - - ui->right_VL->addStretch(); - ui->right_VL->setAlignment(Qt::AlignTop); - ui->topLayout->setAlignment(Qt::AlignTop); - ui->arrowsLayout->addStretch(); - ui->arrowsLayout->setAlignment(Qt::AlignTop); - ui->feedFrame_VL->addStretch(); - - adjustSize(); + BoardPostDisplayWidget_card::setup(); } BoardPostDisplayWidget_card::~BoardPostDisplayWidget_card() @@ -446,7 +424,7 @@ BoardPostDisplayWidget_card::~BoardPostDisplayWidget_card() void BoardPostDisplayWidget_card::setup() { - BoardPostDisplayWidgetBase::setup(); + baseSetup(); RsReputationLevel overall_reputation = rsReputations->overallReputationLevel(mPost.mMeta.mAuthorId); bool redacted = (overall_reputation == RsReputationLevel::LOCALLY_NEGATIVE); @@ -463,7 +441,6 @@ void BoardPostDisplayWidget_card::setup() GxsIdDetails::loadPixmapFromData(mPost.mImage.mData, mPost.mImage.mSize, pixmap,GxsIdDetails::ORIGINAL); // Wiping data - as its been passed to thumbnail. - QPixmap scaledpixmap; if(pixmap.width() > 800){ QPixmap scaledpixmap = pixmap.scaledToWidth(800, Qt::SmoothTransformation); ui->pictureLabel->setPixmap(scaledpixmap); @@ -478,10 +455,10 @@ void BoardPostDisplayWidget_card::setup() } QTextDocument doc; - doc.setHtml(notes()->text()); + doc.setHtml(BoardPostDisplayWidget_card::notes()->text()); if(doc.toPlainText().trimmed().isEmpty()) - notes()->hide(); + BoardPostDisplayWidget_card::notes()->hide(); } QToolButton *BoardPostDisplayWidget_card::voteUpButton() { return ui->voteUpButton; } diff --git a/retroshare-gui/src/gui/Posted/BoardPostDisplayWidget.h b/retroshare-gui/src/gui/Posted/BoardPostDisplayWidget.h index a6d4a04d6..189f83ae5 100644 --- a/retroshare-gui/src/gui/Posted/BoardPostDisplayWidget.h +++ b/retroshare-gui/src/gui/Posted/BoardPostDisplayWidget.h @@ -62,10 +62,11 @@ public: static const char *DEFAULT_BOARD_IMAGE; -protected slots: +protected: /* GxsGroupFeedItem */ - virtual void setup(); // to be overloaded by the different views + void baseSetup(); + virtual void setup() =0; // to be overloaded by the different views virtual QToolButton *voteUpButton() =0; virtual QToolButton *commentButton() =0; @@ -81,6 +82,7 @@ protected slots: virtual QToolButton *shareButton() =0; virtual QFrame *feedFrame() =0; +protected slots: void loadComments(bool e); void readToggled(); void setReadStatus(bool isNew, bool isUnread) ; diff --git a/retroshare-gui/src/gui/Posted/BoardPostDisplayWidget_card.ui b/retroshare-gui/src/gui/Posted/BoardPostDisplayWidget_card.ui index 28ce4fd1d..85eb14906 100644 --- a/retroshare-gui/src/gui/Posted/BoardPostDisplayWidget_card.ui +++ b/retroshare-gui/src/gui/Posted/BoardPostDisplayWidget_card.ui @@ -90,7 +90,10 @@ - + + + 0 + 0 @@ -173,6 +176,13 @@ + + + + Qt::Vertical + + + @@ -277,7 +287,7 @@ - + Qt::Horizontal @@ -340,7 +350,7 @@ - + Qt::Horizontal @@ -401,16 +411,16 @@ :/images/share.png:/images/share.png - - true - Qt::ToolButtonTextBesideIcon + + true + - + Qt::Horizontal @@ -424,10 +434,30 @@ + + + + Qt::Vertical + + + + 0 + 0 + + + + + + + + Qt::Vertical + + + diff --git a/retroshare-gui/src/gui/Posted/BoardPostDisplayWidget_compact.ui b/retroshare-gui/src/gui/Posted/BoardPostDisplayWidget_compact.ui index f27524f08..8c6e89748 100644 --- a/retroshare-gui/src/gui/Posted/BoardPostDisplayWidget_compact.ui +++ b/retroshare-gui/src/gui/Posted/BoardPostDisplayWidget_compact.ui @@ -7,7 +7,7 @@ 0 0 542 - 150 + 151 @@ -90,7 +90,22 @@ - + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + @@ -161,6 +176,13 @@ + + + + Qt::Vertical + + + @@ -287,7 +309,7 @@ - + Qt::Horizontal @@ -305,7 +327,7 @@ - + @@ -400,7 +422,7 @@ - + Qt::Horizontal @@ -414,6 +436,13 @@ + + + + Qt::Vertical + + + @@ -473,6 +502,13 @@ + + + + Qt::Vertical + + + diff --git a/retroshare-gui/src/gui/Posted/PostedCardView.ui b/retroshare-gui/src/gui/Posted/PostedCardView.ui index a55acad24..dba517263 100644 --- a/retroshare-gui/src/gui/Posted/PostedCardView.ui +++ b/retroshare-gui/src/gui/Posted/PostedCardView.ui @@ -7,7 +7,7 @@ 0 0 614 - 182 + 198 @@ -16,7 +16,7 @@ - + 0 @@ -118,7 +118,7 @@ - + 5 @@ -216,7 +216,7 @@ - + Qt::Horizontal @@ -241,30 +241,27 @@ 0 - - - QFrame::NoFrame QFrame::Plain - + 0 - 3 + 0 - 3 + 0 - 3 + 0 - 3 + 0 @@ -337,26 +334,20 @@ - + Qt::Vertical QSizePolicy::Expanding - - - 20 - 5 - - - + @@ -389,7 +380,7 @@ - + Qt::Horizontal @@ -461,7 +452,7 @@ - + 0 @@ -485,7 +476,7 @@ - + Qt::Horizontal @@ -513,9 +504,9 @@ - - + + diff --git a/retroshare-gui/src/gui/Posted/PostedItem.ui b/retroshare-gui/src/gui/Posted/PostedItem.ui index fc316a632..6c6b290f8 100644 --- a/retroshare-gui/src/gui/Posted/PostedItem.ui +++ b/retroshare-gui/src/gui/Posted/PostedItem.ui @@ -16,7 +16,7 @@ - + 1 @@ -82,21 +82,21 @@ QFrame::Plain - + 0 - 3 + 0 - 3 + 0 - 3 + 0 - 3 + 0 @@ -169,26 +169,20 @@ - + Qt::Vertical QSizePolicy::Expanding - - - 20 - 5 - - - + 9 @@ -233,7 +227,7 @@ - + Qt::Vertical @@ -248,7 +242,7 @@ - + 6 @@ -286,7 +280,7 @@ - + 0 @@ -312,7 +306,7 @@ - + 0 @@ -320,7 +314,7 @@ QLayout::SetDefaultConstraint - + 5 @@ -416,7 +410,7 @@ - + Qt::Horizontal @@ -434,7 +428,7 @@ - + 6 @@ -567,7 +561,7 @@ - + Qt::Horizontal @@ -631,9 +625,9 @@ QFrame::Raised - + - + Qt::Horizontal @@ -659,7 +653,7 @@ - + Qt::Horizontal @@ -685,7 +679,7 @@ QFrame::Sunken - + 3 @@ -726,17 +720,17 @@ + + GxsIdLabel + QLabel +

gui/gxs/GxsIdLabel.h
+ ElidedLabel QLabel
gui/common/ElidedLabel.h
1
- - GxsIdLabel - QLabel -
gui/gxs/GxsIdLabel.h
-
ClickableLabel QLabel diff --git a/retroshare-gui/src/gui/Posted/PostedListWidgetWithModel.cpp b/retroshare-gui/src/gui/Posted/PostedListWidgetWithModel.cpp index 087eebe3c..7dcc767b8 100644 --- a/retroshare-gui/src/gui/Posted/PostedListWidgetWithModel.cpp +++ b/retroshare-gui/src/gui/Posted/PostedListWidgetWithModel.cpp @@ -58,9 +58,7 @@ // number of posts to show at once. #define POSTS_CHUNK_SIZE 25 -/**** - * #define DEBUG_POSTED - ***/ +//#define DEBUG_POSTED static const int POSTED_TABS_POSTS = 1; @@ -87,8 +85,12 @@ std::ostream& operator<<(std::ostream& o,const QSize& s) { return o << s.width() void PostedPostDelegate::paint(QPainter * painter, const QStyleOptionViewItem & option, const QModelIndex & index) const { +#ifdef DEBUG_POSTED + if(option.state & QStyle::State_Selected) RS_DBG("Selected"); +#endif + if((option.state & QStyle::State_Selected)) // Avoids double display. The selected widget is never exactly the size of the rendered one, - return; // so when selected, we only draw the selected one. + return; // so when selected, we only draw the selected one. // prepare painter->save(); @@ -98,7 +100,7 @@ void PostedPostDelegate::paint(QPainter * painter, const QStyleOptionViewItem & painter->save(); - painter->fillRect( option.rect, option.palette.background()); + painter->fillRect( option.rect, option.palette.window()); painter->restore(); QPixmap pixmap(option.rect.size()); @@ -109,9 +111,9 @@ void PostedPostDelegate::paint(QPainter * painter, const QStyleOptionViewItem & BoardPostDisplayWidget_compact w(post,displayFlags(post.mMeta.mMsgId),nullptr); w.setFixedSize(option.rect.size()); - w.updateGeometry(); w.adjustSize(); + w.render(&pixmap,QPoint(0,0),QRegion(),QWidget::DrawChildren );// draw the widgets, not the background } else @@ -121,6 +123,7 @@ void PostedPostDelegate::paint(QPainter * painter, const QStyleOptionViewItem & w.setFixedSize(option.rect.size()); w.updateGeometry(); w.adjustSize(); + w.render(&pixmap,QPoint(0,0),QRegion(),QWidget::DrawChildren );// draw the widgets, not the background } @@ -145,6 +148,10 @@ void PostedPostDelegate::paint(QPainter * painter, const QStyleOptionViewItem & painter->save(); painter->drawPixmap(option.rect.topLeft(), pixmap /*,.scaled(option.rect.width(),option.rect.width()*w.height()/(float)w.width(),Qt::KeepAspectRatio,Qt::SmoothTransformation)*/); +#ifdef DEBUG_POSTED + painter->drawText(option.rect.bottomLeft(),QString::number(time(nullptr))); + RS_DBG("DisplayMode=", mDisplayMode == BoardPostDisplayWidget_compact::DISPLAY_MODE_COMPACT? "Compact":"Card", " Title:", post.mMeta.mMsgName.c_str()); +#endif painter->restore(); } @@ -193,40 +200,46 @@ uint8_t PostedPostDelegate::displayFlags(const RsGxsMessageId &id) const QWidget *PostedPostDelegate::createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex& index) const { - RsPostedPost post = index.data(Qt::UserRole).value() ; - if(index.column() == RsPostedPostsModel::COLUMN_POSTS) - { - QWidget *w ; + if (!index.isValid()) + return nullptr; - if(mDisplayMode==BoardPostDisplayWidget_compact::DISPLAY_MODE_COMPACT) - w = new BoardPostDisplayWidget_compact(post,displayFlags(post.mMeta.mMsgId),parent); - else - w = new BoardPostDisplayWidget_card(post,displayFlags(post.mMeta.mMsgId),parent); + if(index.column() != RsPostedPostsModel::COLUMN_POSTS) + return nullptr; - QObject::connect(w,SIGNAL(vote(RsGxsGrpMsgIdPair,bool)),mPostListWidget,SLOT(voteMsg(RsGxsGrpMsgIdPair,bool))); - QObject::connect(w,SIGNAL(expand(RsGxsMessageId,bool)),this,SLOT(expandItem(RsGxsMessageId,bool))); - QObject::connect(w,SIGNAL(commentsRequested(const RsGxsMessageId&,bool)),mPostListWidget,SLOT(openComments(const RsGxsMessageId&))); - QObject::connect(w,SIGNAL(changeReadStatusRequested(const RsGxsMessageId&,bool)),mPostListWidget,SLOT(changeReadStatus(const RsGxsMessageId&,bool))); + QWidget *w ; + RsPostedPost post = index.data(Qt::UserRole).value() ; - // All other interactions with the widget should cause the msg to be set as read. - QObject::connect(w,SIGNAL(thumbnailOpenned()),mPostListWidget,SLOT(markCurrentPostAsRead())); - QObject::connect(w,SIGNAL(vote(RsGxsGrpMsgIdPair,bool)),mPostListWidget,SLOT(markCurrentPostAsRead())); - QObject::connect(w,SIGNAL(expand(RsGxsMessageId,bool)),this,SLOT(markCurrentPostAsRead())); - QObject::connect(w,SIGNAL(commentsRequested(const RsGxsMessageId&,bool)),mPostListWidget,SLOT(markCurrentPostAsRead())); - QObject::connect(w,SIGNAL(shareButtonClicked()),mPostListWidget,SLOT(markCurrentPostAsRead())); - QObject::connect(w,SIGNAL(copylinkClicked()),mPostListWidget,SLOT(copyMessageLink())); +#ifdef DEBUG_POSTED + RS_DBG("Title:", post.mMeta.mMsgName.c_str()); +#endif - w->setFixedSize(option.rect.size()); - w->adjustSize(); - w->updateGeometry(); - w->adjustSize(); + if(mDisplayMode==BoardPostDisplayWidget_compact::DISPLAY_MODE_COMPACT) + w = new BoardPostDisplayWidget_compact(post,displayFlags(post.mMeta.mMsgId),parent); + else + w = new BoardPostDisplayWidget_card(post,displayFlags(post.mMeta.mMsgId),parent); - return w; - } - else - return NULL; + QObject::connect(w,SIGNAL(vote(RsGxsGrpMsgIdPair,bool)),mPostListWidget,SLOT(voteMsg(RsGxsGrpMsgIdPair,bool))); + QObject::connect(w,SIGNAL(expand(RsGxsMessageId,bool)),this,SLOT(expandItem(RsGxsMessageId,bool))); + QObject::connect(w,SIGNAL(commentsRequested(RsGxsMessageId,bool)),mPostListWidget,SLOT(openComments(RsGxsMessageId))); + QObject::connect(w,SIGNAL(changeReadStatusRequested(RsGxsMessageId,bool)),mPostListWidget,SLOT(changeReadStatus(RsGxsMessageId,bool))); + + // All other interactions with the widget should cause the msg to be set as read. + QObject::connect(w,SIGNAL(thumbnailOpenned()),mPostListWidget,SLOT(markCurrentPostAsRead())); + QObject::connect(w,SIGNAL(vote(RsGxsGrpMsgIdPair,bool)),mPostListWidget,SLOT(markCurrentPostAsRead())); + QObject::connect(w,SIGNAL(expand(RsGxsMessageId,bool)),this,SLOT(markCurrentPostAsRead())); + QObject::connect(w,SIGNAL(commentsRequested(RsGxsMessageId,bool)),mPostListWidget,SLOT(markCurrentPostAsRead())); + QObject::connect(w,SIGNAL(shareButtonClicked()),mPostListWidget,SLOT(markCurrentPostAsRead())); + QObject::connect(w,SIGNAL(copylinkClicked()),mPostListWidget,SLOT(copyMessageLink())); + + w->setGeometry(option.rect); + w->adjustSize(); + w->updateGeometry(); + w->adjustSize(); + + return w; } + void PostedPostDelegate::updateEditorGeometry(QWidget *editor, const QStyleOptionViewItem &option, const QModelIndex &/* index */) const { editor->setGeometry(option.rect); @@ -264,13 +277,11 @@ PostedListWidgetWithModel::PostedListWidgetWithModel(const RsGxsGroupId& postedI connect(ui->nextButton,SIGNAL(clicked()),this,SLOT(nextPosts())); connect(ui->prevButton,SIGNAL(clicked()),this,SLOT(prevPosts())); - connect(ui->postsTree,SIGNAL(customContextMenuRequested(const QPoint&)),this,SLOT(postContextMenu(const QPoint&))); + connect(ui->postsTree,SIGNAL(customContextMenuRequested(QPoint)),this,SLOT(postContextMenu(QPoint))); connect(ui->viewModeButton,SIGNAL(clicked()),this,SLOT(switchDisplayMode())); connect(mPostedPostsModel,SIGNAL(boardPostsLoaded()),this,SLOT(postPostLoad())); - QFontMetricsF fm(font()); - /* Setup UI helper */ /* Connect signals */ @@ -374,23 +385,20 @@ void PostedListWidgetWithModel::filterItems(QString text) void PostedListWidgetWithModel::nextPosts() { - ui->postsTree->selectionModel()->clear(); - if(mPostedPostsModel->displayedStartPostIndex() + POSTS_CHUNK_SIZE < mPostedPostsModel->filteredPostsCount()) - { - mPostedPostsModel->setPostsInterval(POSTS_CHUNK_SIZE+mPostedPostsModel->displayedStartPostIndex(),POSTS_CHUNK_SIZE); + if(mPostedPostsModel->displayedStartPostIndex() + POSTS_CHUNK_SIZE < mPostedPostsModel->filteredPostsCount()) + { + mPostedPostsModel->setPostsInterval(POSTS_CHUNK_SIZE+mPostedPostsModel->displayedStartPostIndex(),POSTS_CHUNK_SIZE); updateShowLabel(); - } + } } void PostedListWidgetWithModel::prevPosts() { - ui->postsTree->selectionModel()->clear(); - - if((int)mPostedPostsModel->displayedStartPostIndex() > 0) - { - mPostedPostsModel->setPostsInterval((int)mPostedPostsModel->displayedStartPostIndex()-POSTS_CHUNK_SIZE,POSTS_CHUNK_SIZE); - updateShowLabel(); - } + if((int)mPostedPostsModel->displayedStartPostIndex() > 0) + { + mPostedPostsModel->setPostsInterval((int)mPostedPostsModel->displayedStartPostIndex()-POSTS_CHUNK_SIZE,POSTS_CHUNK_SIZE); + updateShowLabel(); + } } void PostedListWidgetWithModel::showAuthorInPeople() @@ -490,29 +498,30 @@ void PostedListWidgetWithModel::handleEvent_main_thread(std::shared_ptrmPostedEventCode) { - case RsPostedEventCode::NEW_COMMENT: // [[fallthrough]]; - case RsPostedEventCode::NEW_VOTE: // [[fallthrough]]; - { - // special treatment here because the message might be a comment, so we need to refresh the comment tab if openned + case RsPostedEventCode::NEW_COMMENT: [[fallthrough]]; + case RsPostedEventCode::NEW_VOTE: + { + // special treatment here because the message might be a comment, so we need to refresh the comment tab if openned - for(int i=2;itabWidget->count();++i) - { - auto *t = dynamic_cast(ui->tabWidget->widget(i)); + for(int i=2;itabWidget->count();++i) + { + auto *t = dynamic_cast(ui->tabWidget->widget(i)); - if(t->groupId() == e->mPostedGroupId) - t->refresh(); - } - } - case RsPostedEventCode::NEW_MESSAGE: // [[fallthrough]]; - case RsPostedEventCode::NEW_POSTED_GROUP: // [[fallthrough]]; - case RsPostedEventCode::UPDATED_POSTED_GROUP: // [[fallthrough]]; - case RsPostedEventCode::UPDATED_MESSAGE: - case RsPostedEventCode::BOARD_DELETED: - case RsPostedEventCode::SYNC_PARAMETERS_UPDATED: - { + if(t->groupId() == e->mPostedGroupId) + t->refresh(); + } + } + [[clang::fallthrough]]; + case RsPostedEventCode::NEW_MESSAGE: [[fallthrough]]; + case RsPostedEventCode::NEW_POSTED_GROUP: [[fallthrough]]; + case RsPostedEventCode::UPDATED_POSTED_GROUP: [[fallthrough]]; + case RsPostedEventCode::UPDATED_MESSAGE: [[fallthrough]]; + case RsPostedEventCode::BOARD_DELETED: [[fallthrough]]; + case RsPostedEventCode::SYNC_PARAMETERS_UPDATED: + { if(e->mPostedGroupId == groupId()) updateDisplay(true); - } + } default: break; diff --git a/retroshare-gui/src/gui/common/RSTreeView.cpp b/retroshare-gui/src/gui/common/RSTreeView.cpp index 624021f2f..454ab250e 100644 --- a/retroshare-gui/src/gui/common/RSTreeView.cpp +++ b/retroshare-gui/src/gui/common/RSTreeView.cpp @@ -18,42 +18,73 @@ * * *******************************************************************************/ -#include -#include #include "RSTreeView.h" -RSTreeView::RSTreeView(QWidget *parent) : QTreeView(parent) +#include "util/rsdebug.h" + +#include +#include + +//#define DEBUG_RSTREEVIEW + +RSTreeView::RSTreeView(QWidget *parent) + : QTreeView(parent), autoSelect(false) { - setMouseTracking(false); // normally the default, but who knows if it's not goign to change in the future. + setMouseTracking(false); // normally the default, but who knows if it's not going to change in the future. } void RSTreeView::wheelEvent(QWheelEvent *e) { - if(e->modifiers() == Qt::ControlModifier) - { - emit zoomRequested(e->delta() > 0); - return; - } - else - QTreeView::wheelEvent(e); + if(e->modifiers() == Qt::ControlModifier) + { + emit zoomRequested(e->angleDelta().y() > 0); + return; + } + else + QTreeView::wheelEvent(e); } void RSTreeView::mouseMoveEvent(QMouseEvent *e) { - QModelIndex idx = indexAt(e->pos()); +#ifdef DEBUG_RSTREEVIEW + RS_DBG(e->localPos().x(), ":", e->localPos().y()); +#endif + if (autoSelect) + { + QModelIndex idx = indexAt(e->pos()); - if(idx.isValid() && idx != selectionModel()->currentIndex()) - selectionModel()->setCurrentIndex(idx,QItemSelectionModel::ClearAndSelect); + if(idx.isValid() && idx != selectionModel()->currentIndex()) + { +#ifdef DEBUG_RSTREEVIEW + RS_DBG("Selection changed"); +#endif + selectionModel()->setCurrentIndex(idx,QItemSelectionModel::ClearAndSelect); + } + } - QTreeView::mouseMoveEvent(e); + QTreeView::mouseMoveEvent(e); +} + +void RSTreeView::leaveEvent(QEvent *e) +{ +#ifdef DEBUG_RSTREEVIEW + RS_DBG(""); +#endif + if (autoSelect) + { + auto fp = focusPolicy(); + setFocusPolicy(Qt::NoFocus); // To not select first index when resetting current index. + selectionModel()->setCurrentIndex(QModelIndex(),QItemSelectionModel::Clear); // Close editor + setFocusPolicy(fp); + } + + QTreeView::leaveEvent(e); } void RSTreeView::setAutoSelect(bool b) { - if(b) - setMouseTracking(true); - else - setMouseTracking(false); + autoSelect = b; // Keep this because setMouseTracking can be called outside. + setMouseTracking(b); } void RSTreeView::resizeEvent(QResizeEvent *e) diff --git a/retroshare-gui/src/gui/common/RSTreeView.h b/retroshare-gui/src/gui/common/RSTreeView.h index 116ccac31..0ccd34134 100644 --- a/retroshare-gui/src/gui/common/RSTreeView.h +++ b/retroshare-gui/src/gui/common/RSTreeView.h @@ -29,26 +29,34 @@ class RSTreeView : public QTreeView Q_OBJECT public: - RSTreeView(QWidget *parent = 0); + RSTreeView(QWidget *parent = nullptr); + /** + * @brief set Placeholder Text + * @param text + */ void setPlaceholderText(const QString &text); - // Use this to make selection automatic based on mouse position. This is useful to trigger selection and therefore editing mode - // in trees that show editing widgets using a QStyledItemDelegate - - void setAutoSelect(bool b); + /** + * @brief Use this to make selection automatic based on mouse position. + * This is useful to trigger selection and therefore editing mode in trees that show editing widgets using a QStyledItemDelegate. + * @param b + */ + void setAutoSelect(bool b); signals: - void sizeChanged(QSize); - void zoomRequested(bool zoom_or_unzoom); + void sizeChanged(QSize); + void zoomRequested(bool zoom_or_unzoom); protected: virtual void mouseMoveEvent(QMouseEvent *e) override; // overriding so as to manage auto-selection + virtual void leaveEvent(QEvent *e) override; // overriding so as to manage auto-selection clear virtual void wheelEvent(QWheelEvent *e) override; // overriding so as to manage zoom - virtual void resizeEvent(QResizeEvent *e) override; + virtual void resizeEvent(QResizeEvent *e) override; virtual void paintEvent(QPaintEvent *event) override; QString placeholderText; + bool autoSelect; }; #endif diff --git a/retroshare-gui/src/gui/qss/stylesheet/Standard_Dark.qss b/retroshare-gui/src/gui/qss/stylesheet/Standard_Dark.qss index fc95d1d46..d3983c6b9 100644 --- a/retroshare-gui/src/gui/qss/stylesheet/Standard_Dark.qss +++ b/retroshare-gui/src/gui/qss/stylesheet/Standard_Dark.qss @@ -2316,7 +2316,7 @@ QFrame#titleBarFrame { background-color: qlineargradient(x1:0, y1:0, x2:0, y2:1, stop:0 #455364, stop: 0.5 #54687A,stop: 0.6 #44586A, stop:1 #455364); border: 0px; } -QFrame[objectName^="#headerBFrame"] { +QFrame[objectName^="headerBFrame"] { border: 1px; border-radius: 4px; } diff --git a/retroshare-gui/src/gui/qss/stylesheet/Standard_Light.qss b/retroshare-gui/src/gui/qss/stylesheet/Standard_Light.qss index e6616c855..42a727888 100644 --- a/retroshare-gui/src/gui/qss/stylesheet/Standard_Light.qss +++ b/retroshare-gui/src/gui/qss/stylesheet/Standard_Light.qss @@ -2315,7 +2315,7 @@ QToolBar#headerToolBar { background-color: qlineargradient(x1:0, y1:0, x2:0, y2:1, stop:0 #9BDBF9, stop:1 #1592CD); border: 0px; } -QFrame[objectName^="#headerBFrame"] { +QFrame[objectName^="headerBFrame"] { border: 1px; border-radius: 4px; } From a1a8bf1408111d76b77bfd7dea137734dfa35dc0 Mon Sep 17 00:00:00 2001 From: Gioacchino Mazzurco Date: Wed, 1 Dec 2021 08:26:34 +0100 Subject: [PATCH 044/113] Android Dockerfile do updates --- build_scripts/Android/Dockerfile | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/build_scripts/Android/Dockerfile b/build_scripts/Android/Dockerfile index 081d9126e..6c986ce51 100644 --- a/build_scripts/Android/Dockerfile +++ b/build_scripts/Android/Dockerfile @@ -26,7 +26,7 @@ FROM ubuntu:20.04 ENV DEBIAN_FRONTEND=noninteractive -RUN apt-get update && apt-get clean +RUN apt-get update && apt-get upgrade -y && apt-get clean RUN apt-get install -y -qq \ bash build-essential bzip2 cmake curl chrpath doxygen \ git p7zip python qt5-default qttools5-dev tclsh unzip wget zip @@ -74,11 +74,11 @@ ARG QT_INSTALLER_JWT_TOKEN RUN $PREPARE_TOOLCHAIN install_qt_android # Avoid Qt account details leak into the image RUN rm -f /root/.local/share/Qt/qtaccount.ini -# Shrink image by removing unneded Qt components +# Shrink image by removing unneeded Qt components RUN rm -r \ $NATIVE_LIBS_TOOLCHAIN_PATH/Qt/Docs/ \ $NATIVE_LIBS_TOOLCHAIN_PATH/Qt/Examples/ \ - $NATIVE_LIBS_TOOLCHAIN_PATH/Qt/Tools/ + $NATIVE_LIBS_TOOLCHAIN_PATH/Qt/Tools/ RUN mkdir /jsonapi-generator-build WORKDIR /jsonapi-generator-build/ From 475d8ffc11542b8da69e679d1f4f9492b0b3786a Mon Sep 17 00:00:00 2001 From: Gioacchino Mazzurco Date: Wed, 1 Dec 2021 08:32:09 +0100 Subject: [PATCH 045/113] Android Docker attempt to shrink image Do not install apt recommended packages Show upgraded packages on Android Gitlab CI Dockerfile --- build_scripts/Android/Dockerfile | 4 ++-- build_scripts/GitlabCI/Android.Dockerfile | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/build_scripts/Android/Dockerfile b/build_scripts/Android/Dockerfile index 6c986ce51..3d45bdf9a 100644 --- a/build_scripts/Android/Dockerfile +++ b/build_scripts/Android/Dockerfile @@ -27,12 +27,12 @@ FROM ubuntu:20.04 ENV DEBIAN_FRONTEND=noninteractive RUN apt-get update && apt-get upgrade -y && apt-get clean -RUN apt-get install -y -qq \ +RUN apt-get install --no-install-recommends --assume-yes --quiet \ bash build-essential bzip2 cmake curl chrpath doxygen \ git p7zip python qt5-default qttools5-dev tclsh unzip wget zip # Dependencies to create Android pkg -RUN apt-get install -y -qq \ +RUN apt-get install --no-install-recommends --assume-yes --quiet \ openjdk-8-jre openjdk-8-jdk openjdk-8-jdk-headless gradle ARG FRESHCLONE=0 diff --git a/build_scripts/GitlabCI/Android.Dockerfile b/build_scripts/GitlabCI/Android.Dockerfile index a0844972d..88c73cd44 100644 --- a/build_scripts/GitlabCI/Android.Dockerfile +++ b/build_scripts/GitlabCI/Android.Dockerfile @@ -1,7 +1,7 @@ ARG ANDROID_NDK_ARCH=arm FROM registry.gitlab.com/retroshare/retroshare:android_${ANDROID_NDK_ARCH}_base -RUN apt-get update -y && apt-get upgrade -y +RUN apt-get update -y && apt-get upgrade --assume-yes --quiet --show-upgraded ARG REPO_URL=https://gitlab.com/RetroShare/RetroShare.git ARG REPO_BRANCH=master From 72caa2aa68409d8b81fddaabf50356dd56c5e7bc Mon Sep 17 00:00:00 2001 From: Gioacchino Mazzurco Date: Wed, 1 Dec 2021 16:30:28 +0100 Subject: [PATCH 046/113] Android Dockerfiles better apt options --- build_scripts/Android/Dockerfile | 8 +++++--- build_scripts/GitlabCI/Android.Dockerfile | 4 +++- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/build_scripts/Android/Dockerfile b/build_scripts/Android/Dockerfile index 3d45bdf9a..490a247c9 100644 --- a/build_scripts/Android/Dockerfile +++ b/build_scripts/Android/Dockerfile @@ -25,14 +25,16 @@ FROM ubuntu:20.04 ENV DEBIAN_FRONTEND=noninteractive +ENV APT_UNAT="--assume-yes --quiet" -RUN apt-get update && apt-get upgrade -y && apt-get clean -RUN apt-get install --no-install-recommends --assume-yes --quiet \ +RUN apt-get update $APT_UNAT && apt-get upgrade --show-upgraded $APT_UNAT && \ + apt-get clean $APT_UNAT +RUN apt-get install --no-install-recommends $APT_UNAT \ bash build-essential bzip2 cmake curl chrpath doxygen \ git p7zip python qt5-default qttools5-dev tclsh unzip wget zip # Dependencies to create Android pkg -RUN apt-get install --no-install-recommends --assume-yes --quiet \ +RUN apt-get install --no-install-recommends $APT_UNAT \ openjdk-8-jre openjdk-8-jdk openjdk-8-jdk-headless gradle ARG FRESHCLONE=0 diff --git a/build_scripts/GitlabCI/Android.Dockerfile b/build_scripts/GitlabCI/Android.Dockerfile index 88c73cd44..bc4bd0755 100644 --- a/build_scripts/GitlabCI/Android.Dockerfile +++ b/build_scripts/GitlabCI/Android.Dockerfile @@ -1,7 +1,9 @@ ARG ANDROID_NDK_ARCH=arm FROM registry.gitlab.com/retroshare/retroshare:android_${ANDROID_NDK_ARCH}_base -RUN apt-get update -y && apt-get upgrade --assume-yes --quiet --show-upgraded +ENV APT_UNAT="--assume-yes --quiet" + +RUN apt-get update $APT_UNAT && apt-get upgrade $APT_UNAT --show-upgraded ARG REPO_URL=https://gitlab.com/RetroShare/RetroShare.git ARG REPO_BRANCH=master From d7afbea1dd958a1f71d21ac019dfe239c44ff90d Mon Sep 17 00:00:00 2001 From: csoler Date: Wed, 1 Dec 2021 23:05:16 +0100 Subject: [PATCH 047/113] 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 048/113] 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 777d0d9848e349753d0d57572a33e4f026809ac2 Mon Sep 17 00:00:00 2001 From: defnax Date: Sat, 4 Dec 2021 12:12:29 +0100 Subject: [PATCH 049/113] Fixed to display the right index for Image Page * Fixed to display the right index for Image Page * Fixed to disable share button when Identity is banned. --- retroshare-gui/src/gui/Posted/BoardPostDisplayWidget.cpp | 1 + retroshare-gui/src/gui/Posted/PostedCreatePostDialog.ui | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/retroshare-gui/src/gui/Posted/BoardPostDisplayWidget.cpp b/retroshare-gui/src/gui/Posted/BoardPostDisplayWidget.cpp index 6d2cbb4a4..da47d7596 100644 --- a/retroshare-gui/src/gui/Posted/BoardPostDisplayWidget.cpp +++ b/retroshare-gui/src/gui/Posted/BoardPostDisplayWidget.cpp @@ -182,6 +182,7 @@ void BoardPostDisplayWidgetBase::baseSetup() if(redacted) { commentButton()->setDisabled(true); + shareButton()->setDisabled(true); voteUpButton()->setDisabled(true); voteDownButton()->setDisabled(true); fromLabel()->setId(mPost.mMeta.mAuthorId); diff --git a/retroshare-gui/src/gui/Posted/PostedCreatePostDialog.ui b/retroshare-gui/src/gui/Posted/PostedCreatePostDialog.ui index a9ae69b46..a44f226b1 100644 --- a/retroshare-gui/src/gui/Posted/PostedCreatePostDialog.ui +++ b/retroshare-gui/src/gui/Posted/PostedCreatePostDialog.ui @@ -143,7 +143,7 @@ - 1 + 0 From bb37e2692b8b003635f4a964e0069412df7c8e17 Mon Sep 17 00:00:00 2001 From: csoler Date: Sun, 5 Dec 2021 00:02:12 +0100 Subject: [PATCH 050/113] 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 051/113] 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 16:05:43 +0100 Subject: [PATCH 052/113] Fix PostedCreatePostDialog when reject show double message. And stacked widget if current index is changed in ui file. --- .../src/gui/Posted/PostedCreatePostDialog.cpp | 51 ++++++------------- .../src/gui/Posted/PostedCreatePostDialog.h | 2 +- 2 files changed, 17 insertions(+), 36 deletions(-) diff --git a/retroshare-gui/src/gui/Posted/PostedCreatePostDialog.cpp b/retroshare-gui/src/gui/Posted/PostedCreatePostDialog.cpp index 9c08c8169..ce22fa7f3 100644 --- a/retroshare-gui/src/gui/Posted/PostedCreatePostDialog.cpp +++ b/retroshare-gui/src/gui/Posted/PostedCreatePostDialog.cpp @@ -41,9 +41,12 @@ #include "gui/common/FilesDefs.h" /* View Page */ -#define VIEW_POST 1 -#define VIEW_IMAGE 2 -#define VIEW_LINK 3 +#define VIEW_POST 0 +#define VIEW_IMAGE 1 +#define VIEW_LINK 2 +/* View Image */ +#define IMG_ATTACH 0 +#define IMG_PICTURE 1 PostedCreatePostDialog::PostedCreatePostDialog(RsPosted *posted, const RsGxsGroupId& grpId, const RsGxsId& default_author, QWidget *parent): QDialog(parent, Qt::WindowSystemMenuHint | Qt::WindowTitleHint | Qt::WindowMinimizeButtonHint | Qt::WindowMaximizeButtonHint | Qt::WindowCloseButtonHint), @@ -54,7 +57,6 @@ PostedCreatePostDialog::PostedCreatePostDialog(RsPosted *posted, const RsGxsGrou Settings->loadWidgetInformation(this); connect(ui->postButton, SIGNAL(clicked()), this, SLOT(createPost())); - connect(ui->buttonBox, SIGNAL(rejected()), this, SLOT(reject())); connect(ui->addPicButton, SIGNAL(clicked() ), this , SLOT(addPicture())); connect(ui->RichTextEditWidget, SIGNAL(textSizeOk(bool)),ui->postButton, SLOT(setEnabled(bool))); @@ -84,6 +86,7 @@ PostedCreatePostDialog::PostedCreatePostDialog(RsPosted *posted, const RsGxsGrou connect(signalMapper, SIGNAL(mapped(int)), this, SLOT(setPage(int))); ui->removeButton->hide(); + ui->stackedWidgetPicture->setCurrentIndex(IMG_ATTACH); /* load settings */ processSettings(true); @@ -202,7 +205,6 @@ void PostedCreatePostDialog::addPicture() // select a picture file if (misc::getOpenFileName(window(), RshareSettings::LASTDIR_IMAGES, tr("Load Picture File"), "Pictures (*.png *.xpm *.jpg *.jpeg *.gif *.webp )", imagefilename)) { - QString encodedImage; QImage image; if (image.load(imagefilename) == false) { fprintf (stderr, "RsHtml::makeEmbeddedImage() - image \"%s\" can't be load\n", imagefilename.toLatin1().constData()); @@ -213,7 +215,7 @@ void PostedCreatePostDialog::addPicture() QImage opt; if(ImageUtil::optimizeSizeBytes(imagebytes, image, opt, 640*480, MAXMESSAGESIZE - 2000)) { //Leave space for other stuff ui->imageLabel->setPixmap(QPixmap::fromImage(opt)); - ui->stackedWidgetPicture->setCurrentIndex(1); + ui->stackedWidgetPicture->setCurrentIndex(IMG_PICTURE); ui->removeButton->show(); } else { imagefilename = ""; @@ -259,45 +261,24 @@ int PostedCreatePostDialog::viewMode() void PostedCreatePostDialog::setPage(int viewMode) { - switch (viewMode) { - case VIEW_POST: - ui->stackedWidget->setCurrentIndex(0); + if( (viewMode < 0) || (viewMode > ui->stackedWidget->count()-1) ) + viewMode = VIEW_POST; - ui->viewPostButton->setChecked(true); - ui->viewImageButton->setChecked(false); - ui->viewLinkButton->setChecked(false); + ui->stackedWidget->setCurrentIndex(viewMode); - break; - case VIEW_IMAGE: - ui->stackedWidget->setCurrentIndex(1); + ui->viewPostButton ->setChecked(viewMode==VIEW_POST); + ui->viewImageButton->setChecked(viewMode==VIEW_IMAGE); + ui->viewLinkButton ->setChecked(viewMode==VIEW_LINK); - ui->viewImageButton->setChecked(true); - ui->viewPostButton->setChecked(false); - ui->viewLinkButton->setChecked(false); - - break; - case VIEW_LINK: - ui->stackedWidget->setCurrentIndex(2); - - ui->viewLinkButton->setChecked(true); - ui->viewPostButton->setChecked(false); - ui->viewImageButton->setChecked(false); - - break; - default: - setPage(VIEW_POST); - return; - } } void PostedCreatePostDialog::on_removeButton_clicked() { imagefilename = ""; imagebytes.clear(); - QPixmap empty; - ui->imageLabel->setPixmap(empty); + ui->imageLabel->setPixmap(QPixmap()); ui->removeButton->hide(); - ui->stackedWidgetPicture->setCurrentIndex(0); + ui->stackedWidgetPicture->setCurrentIndex(IMG_ATTACH); } void PostedCreatePostDialog::reject() diff --git a/retroshare-gui/src/gui/Posted/PostedCreatePostDialog.h b/retroshare-gui/src/gui/Posted/PostedCreatePostDialog.h index a62fe46c6..48ae3cbd4 100644 --- a/retroshare-gui/src/gui/Posted/PostedCreatePostDialog.h +++ b/retroshare-gui/src/gui/Posted/PostedCreatePostDialog.h @@ -52,7 +52,7 @@ private slots: void addPicture(); void on_removeButton_clicked(); void fileHashingFinished(QList hashedFiles); - void reject(); + void reject() override; //QDialog void setPage(int viewMode); private: From 7dc5c90d63e2b9866ab8e1d5d95cf07ab4b767e2 Mon Sep 17 00:00:00 2001 From: csoler Date: Mon, 6 Dec 2021 22:08:56 +0100 Subject: [PATCH 053/113] 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 054/113] 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 0afe305ca1f64b17cf0543da0471df3851b0b7f2 Mon Sep 17 00:00:00 2001 From: defnax Date: Tue, 7 Dec 2021 19:11:37 +0100 Subject: [PATCH 055/113] added classic stylesheet --- retroshare-gui/src/qss/retroclassic.qss | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) create mode 100644 retroshare-gui/src/qss/retroclassic.qss diff --git a/retroshare-gui/src/qss/retroclassic.qss b/retroshare-gui/src/qss/retroclassic.qss new file mode 100644 index 000000000..eb45b3379 --- /dev/null +++ b/retroshare-gui/src/qss/retroclassic.qss @@ -0,0 +1,21 @@ +/* HeaderFrame & TitleBarFrame */ + +QFrame[objectName^="headerFrame"] { + background-color: qlineargradient(x1:0, y1:0, x2:0, y2:1, stop:0 #9BDBF9, stop:1 #1592CD); +} +QFrame[objectName^="headerBFrame"] { + background-color: qlineargradient(x1:0, y1:0, x2:0, y2:1, stop:0 #9BDBF9, stop:1 #1592CD); + border: 1px; + border-radius: 4px; +} +QFrame[objectName^="headerFrame"] > *:!hover, +QFrame[objectName^="headerBFrame"] > *:!hover{ + background: transparent; + color: white; +} + +QFrame[objectName^="toolBarFrame"], +QFrame[objectName^="toolBarFrameTop"] { + background-color: qlineargradient(x1:0, y1:0, x2:0, y2:1, stop:0 #FEFEFE, stop:1 #E8E8E8); + border: 1px solid #CCCCCC; +} From e0812dce839d465014e18e2ca7d173f1f33e8268 Mon Sep 17 00:00:00 2001 From: csoler Date: Tue, 7 Dec 2021 21:20:19 +0100 Subject: [PATCH 056/113] 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 94bd09940722d1e4ca5dc8ab09488fd149f96aa5 Mon Sep 17 00:00:00 2001 From: Gioacchino Mazzurco Date: Thu, 9 Dec 2021 12:55:06 +0100 Subject: [PATCH 057/113] Rename DATA_DIR macro to less polluting RS_DATA_DIR --- build_scripts/OBS | 2 +- libretroshare/src/libretroshare.pro | 4 ++-- libretroshare/src/rsserver/rsaccounts.cc | 9 +++++---- libretroshare/src/services/broadcastdiscoveryservice.cc | 2 +- retroshare.pri | 1 - 5 files changed, 9 insertions(+), 9 deletions(-) diff --git a/build_scripts/OBS b/build_scripts/OBS index b260e5834..df16cb915 160000 --- a/build_scripts/OBS +++ b/build_scripts/OBS @@ -1 +1 @@ -Subproject commit b260e58346b1eec782bdf88a7e8f3c9d36fd3ecb +Subproject commit df16cb915465d058c75277678799ce4dadeae287 diff --git a/libretroshare/src/libretroshare.pro b/libretroshare/src/libretroshare.pro index 2bad4682f..413e0b0a8 100644 --- a/libretroshare/src/libretroshare.pro +++ b/libretroshare/src/libretroshare.pro @@ -205,7 +205,7 @@ linux-* { LIBS *= -ldl DEFINES *= PLUGIN_DIR=\"\\\"$${PLUGIN_DIR}\\\"\" - DEFINES *= DATA_DIR=\"\\\"$${DATA_DIR}\\\"\" + DEFINES *= RS_DATA_DIR=\"\\\"$${RS_DATA_DIR}\\\"\" } linux-g++ { @@ -289,7 +289,7 @@ mac { #LIBS += -lsqlite3 DEFINES *= PLUGIN_DIR=\"\\\"$${PLUGIN_DIR}\\\"\" - DEFINES *= DATA_DIR=\"\\\"$${DATA_DIR}\\\"\" + DEFINES *= RS_DATA_DIR=\"\\\"$${RS_DATA_DIR}\\\"\" } ################################# FreeBSD ########################################## diff --git a/libretroshare/src/rsserver/rsaccounts.cc b/libretroshare/src/rsserver/rsaccounts.cc index 1fa3802d1..e795ff1b6 100644 --- a/libretroshare/src/rsserver/rsaccounts.cc +++ b/libretroshare/src/rsserver/rsaccounts.cc @@ -841,14 +841,15 @@ static bool checkAccount(const std::string &accountdir, AccountDetails &account, /* Use RetroShare's exe dir */ dataDirectory = "."; -#elif defined(ANDROID) +#elif defined(__ANDROID__) + // TODO: This is probably not really used on Android dataDirectory = PathBaseDirectory()+"/usr/share/retroshare"; -#elif defined(DATA_DIR) +#elif defined(RS_DATA_DIR) // cppcheck-suppress ConfigurationNotChecked - dataDirectory = DATA_DIR; + dataDirectory = RS_DATA_DIR; // For all other OS the data directory must be set in libretroshare.pro #else -# error "For your target OS automatic data dir discovery is not supported, cannot compile if DATA_DIR variable not set." +# error "For your target OS automatic data dir discovery is not supported, cannot compile if RS_DATA_DIR variable not set." #endif if (!check) diff --git a/libretroshare/src/services/broadcastdiscoveryservice.cc b/libretroshare/src/services/broadcastdiscoveryservice.cc index 98b67cdcd..380cf8e5d 100644 --- a/libretroshare/src/services/broadcastdiscoveryservice.cc +++ b/libretroshare/src/services/broadcastdiscoveryservice.cc @@ -245,7 +245,7 @@ bool BroadcastDiscoveryService::isMulticastListeningEnabled() env, "isHeld" ); return mAndroidWifiMulticastLock.Call(env, isHeld); -#else if // def __ANDROID__ +#else // def __ANDROID__ return true; #endif // def __ANDROID__ } diff --git a/retroshare.pri b/retroshare.pri index d0439e5e2..d5bad4bd2 100644 --- a/retroshare.pri +++ b/retroshare.pri @@ -816,5 +816,4 @@ contains(RS_UPNP_LIB, upnp):DEFINES*=RS_USE_LIBUPNP isEmpty(BIN_DIR) : BIN_DIR = $${RS_BIN_DIR} isEmpty(INC_DIR) : INC_DIR = $${RS_INCLUDE_DIR} isEmpty(LIBDIR) : LIBDIR = $${QMAKE_LIBDIR} -isEmpty(DATA_DIR) : DATA_DIR = $${RS_DATA_DIR} isEmpty(PLUGIN_DIR): PLUGIN_DIR= $${RS_PLUGIN_DIR} From 6a92b99da3b02f217403afb2d093e01a3c638cdf Mon Sep 17 00:00:00 2001 From: Gioacchino Mazzurco Date: Thu, 9 Dec 2021 13:04:06 +0100 Subject: [PATCH 058/113] Initial CMake support for libretroshare libretroshare (not all build options yet) and it's dependencies can now be built using CMake instead of qmake. Even Qt itself deprecated qmake, which is not developed anymore, as build system and it was making many things much more difficult and requiring an enormous amount of black magic to support a wide range of platforms. libretroshare can now easly be build as static or shared library with simple commands and a maintaniable build system: ``` cmake \ -D RS_LIBRETROSHARE_STATIC=OFF -D RS_LIBRETROSHARE_SHARED=ON \ -S $YOUR_RS_SOURCE_DIR/libretroshare/ -B . make ``` --- libbitdht/CMakeLists.txt | 19 ++ libretroshare/CMakeLists.txt | 243 ++++++++++++++++++++++ libretroshare/src/CMakeLists.txt | 346 +++++++++++++++++++++++++++++++ openpgpsdk/CMakeLists.txt | 27 +++ 4 files changed, 635 insertions(+) create mode 100644 libbitdht/CMakeLists.txt create mode 100644 libretroshare/CMakeLists.txt create mode 100644 libretroshare/src/CMakeLists.txt create mode 100644 openpgpsdk/CMakeLists.txt diff --git a/libbitdht/CMakeLists.txt b/libbitdht/CMakeLists.txt new file mode 100644 index 000000000..2a996de48 --- /dev/null +++ b/libbitdht/CMakeLists.txt @@ -0,0 +1,19 @@ +# RetroShare decentralized communication platform +# +# Copyright (C) 2021 Gioacchino Mazzurco +# Copyright (C) 2021 Asociación Civil Altermundi +# +# SPDX-License-Identifier: CC0-1.0 + +cmake_minimum_required (VERSION 2.8.12) +project(libbitdht) + +file( + GLOB BITDHT_SOURCES + src/bitdht/*.c src/bitdht/*.cc src/udp/*.cc src/util/*.cc ) + +add_library(${PROJECT_NAME} ${BITDHT_SOURCES}) + +target_include_directories( + ${PROJECT_NAME} + PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/src ) diff --git a/libretroshare/CMakeLists.txt b/libretroshare/CMakeLists.txt new file mode 100644 index 000000000..0eb111dd7 --- /dev/null +++ b/libretroshare/CMakeLists.txt @@ -0,0 +1,243 @@ +# RetroShare decentralized communication platform +# +# Copyright (C) 2021 Gioacchino Mazzurco +# Copyright (C) 2021 Asociación Civil Altermundi +# +# SPDX-License-Identifier: CC0-1.0 + +cmake_minimum_required (VERSION 3.18.0) +project(retroshare) + +# sqlcipher +option( + RS_SQLCIPHER + "SQLCipher encryption for GXS database" + ON ) + +# rs_gxs_send_all +option( + RS_GXS_SEND_ALL + "GXS distribute all available messages on request, indipendently from \ + local sync timer" + ON ) + +# bitdht +option( + RS_BITDHT + "Use bitdht (BitTorrent DHT own implementation) to look for online peers" + ON ) + +# use_dht_stunner +option( + RS_BITDHT_STUNNER + "Use bitdht (BitTorrent DHT own implementation) for NAT type discovery and \ + attempt the STUN (Session Traversal Utilities for NAT)" + ON ) + +# use_dht_stunner_ext_ip +option( + RS_BITDHT_STUNNER_EXT_IP + "Use bitdht (BitTorrent DHT own implementation) stunner to figure out our \ + external IP. As this purely relying on random DHT peers that answer our \ + request, it can easily be abused. Therefore, it is turned off by default." + OFF ) + +# rs_jsonapi +option( + RS_JSON_API + "Use restbed to expose libretroshare as JSON API via HTTP" + OFF ) + +# rs_deep_forums_index +option( + RS_FORUM_DEEP_INDEX + "Xapian based full text index and search of GXS forums" + OFF ) + +# rs_broadcast_discovery +option( + RS_BRODCAST_DISCOVERY + "Local area network peer discovery via udp-discovery-cpp" + ON ) + +# rs_dh_init_check +option( + RS_DH_PRIME_INIT_CHECK + "Check Diffie Hellman prime at each startup. This is not necessary and on \ + all Android mobile phones tested this take at least one minute at startup \ + which is untolerable for most phone users." + ON ) + +option( + RS_MINIUPNPC + "Forward ports in NAT router via miniupnpc" + ON +) + +include(CMakeDependentOption) +cmake_dependent_option( + RS_LIBUPNP + "Forward ports in NAT router via libupnp (unstable)" + OFF + "NOT RS_MINIUPNPC" + OFF +) + +option( + RS_LIBRETROSHARE_STATIC + "Build RetroShare static library" + ON +) + +cmake_dependent_option( + RS_LIBRETROSHARE_SHARED + "Build RetroShare shared library" + OFF + "NOT RS_LIBRETROSHARE_STATIC" + OFF +) + +# rs_deprecatedwarning +option( + RS_WARN_DEPRECATED + "Print warning about RetroShare deprecated components usage during build" + ON +) + +# rs_cppwarning +option( + RS_WARN_LESS + "Silence a few at the moment very common warnings about RetroShare \ + components during build" + OFF +) + +# rs_v07_changes +option( + RS_V07_BREAKING_CHANGES + "Enable retro-compatibility breaking changes planned for RetroShare 0.7.0" + OFF +) + +set( + RS_DATA_DIR + "${CMAKE_INSTALL_PREFIX}/share/retroshare" + CACHE STRING + "Path where to install RetroShare system wide data" ) + +################################################################################ + +include(src/CMakeLists.txt) +list(TRANSFORM RS_SOURCES PREPEND src/) + +if(RS_LIBRETROSHARE_STATIC) + add_library(${PROJECT_NAME} STATIC ${RS_SOURCES}) +endif(RS_LIBRETROSHARE_STATIC) + +if(RS_LIBRETROSHARE_SHARED) + add_library(${PROJECT_NAME} SHARED ${RS_SOURCES}) + + ## Ensure statically linked libraries such as openpgpsdk are compiled with + ## PIC Which is needed for shared library + set(CMAKE_POSITION_INDEPENDENT_CODE ON) +endif(RS_LIBRETROSHARE_SHARED) + +target_include_directories( + ${PROJECT_NAME} + PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/src ) + + +find_package(OpenSSL REQUIRED) +target_include_directories(${PROJECT_NAME} PRIVATE ${OPENSSL_INCLUDE_DIR}) +target_link_libraries(${PROJECT_NAME} PRIVATE OpenSSL::SSL OpenSSL::Crypto) + +################################################################################ + +add_subdirectory(../openpgpsdk ${CMAKE_BINARY_DIR}/openpgpsdk) +target_link_libraries(${PROJECT_NAME} PRIVATE openpgpsdk) + +if(RS_BITDHT) + add_compile_definitions(RS_USE_BITDHT) + add_subdirectory(../libbitdht ${CMAKE_BINARY_DIR}/libbitdht) + target_link_libraries(${PROJECT_NAME} PRIVATE libbitdht) +endif(RS_BITDHT) + +## TODO: Check if https://github.com/rbock/sqlpp11 or +## https://github.com/rbock/sqlpp17 may improve GXS code +if(RS_SQLCIPHER) + find_library(RS_SQL_LIB "sqlcipher" REQUIRED) + find_path( + RS_SQL_LIB_INCLUDE "sqlcipher/sqlite3.h" + PATH_SUFFIXES "include" "includes" + REQUIRED ) + target_include_directories( + ${PROJECT_NAME} + PRIVATE "${RS_SQL_LIB_INCLUDE}/sqlcipher" ) + target_link_libraries(${PROJECT_NAME} PRIVATE ${RS_SQL_LIB}) +else() + add_compile_definitions(NO_SQLCIPHER) + find_package(SQLite3 REQUIRED) + target_link_libraries(${PROJECT_NAME} PRIVATE SQLite::SQLite3) +endif() + +add_compile_definitions( + SQLITE_HAS_CODEC + RS_ENABLE_GXS + GXS_ENABLE_SYNC_MSGS + RS_USE_GXS_DISTANT_SYNC + RS_GXS_TRANS + V07_NON_BACKWARD_COMPATIBLE_CHANGE_001 + V07_NON_BACKWARD_COMPATIBLE_CHANGE_002 + V07_NON_BACKWARD_COMPATIBLE_CHANGE_003 ) + +if(RS_V07_BREAKING_CHANGES) + add_compile_definitions( + V07_NON_BACKWARD_COMPATIBLE_CHANGE_004 + V07_NON_BACKWARD_COMPATIBLE_CHANGE_UNNAMED ) +endif() + +if(RS_MINIUPNPC) + add_compile_definitions(RS_USE_LIBMINIUPNPC) +endif(RS_MINIUPNPC) + +if(RS_LIBUPNP) + add_compile_definitions(RS_USE_LIBUPNP) +endif(RS_LIBUPNP) + +if(RS_GXS_SEND_ALL) + add_compile_definitions(RS_GXS_SEND_ALL) +endif(RS_GXS_SEND_ALL) + +if(RS_BRODCAST_DISCOVERY) + add_subdirectory( + ../supportlibs/udp-discovery-cpp/ + ${CMAKE_BINARY_DIR}/supportlibs/udp-discovery-cpp/ ) + target_link_libraries(${PROJECT_NAME} PRIVATE udp-discovery) + + ## Temporary work around target_include_directories should be added upstream + include_directories(../supportlibs/udp-discovery-cpp/) +endif(RS_BRODCAST_DISCOVERY) + +if(NOT RS_WARN_DEPRECATED) + add_compile_definitions(RS_NO_WARN_DEPRECATED) + target_compile_options( + ${PROJECT_NAME} PRIVATE + -Wno-deprecated -Wno-deprecated-declarations ) +endif(RS_WARN_DEPRECATED) + +if(RS_WARN_LESS) + add_compile_definitions(RS_NO_WARN_CPP) + + target_compile_options( + ${PROJECT_NAME} PRIVATE + -Wno-cpp -Wno-inconsistent-missing-override ) +endif(RS_WARN_LESS) + +################################################################################ + +if(CMAKE_SYSTEM_NAME STREQUAL "Linux") + add_compile_definitions(RS_DATA_DIR="${RS_DATA_DIR}") +endif(CMAKE_SYSTEM_NAME STREQUAL "Linux") + +## Useful to debug CMake +#set(CMAKE_EXPORT_COMPILE_COMMANDS ON) diff --git a/libretroshare/src/CMakeLists.txt b/libretroshare/src/CMakeLists.txt new file mode 100644 index 000000000..7bfbb52b1 --- /dev/null +++ b/libretroshare/src/CMakeLists.txt @@ -0,0 +1,346 @@ +# RetroShare decentralized communication platform +# +# Copyright (C) 2021 Gioacchino Mazzurco +# Copyright (C) 2021 Asociación Civil Altermundi +# +# SPDX-License-Identifier: CC0-1.0 + +list( + APPEND RS_SOURCES + chat/distantchat.cc + chat/p3chatservice.cc + chat/rschatitems.cc + chat/distributedchat.cc + crypto/chacha20.cpp + crypto/hashstream.cc + crypto/rsaes.cc + crypto/rscrypto.cpp ) + +if(RS_BITDHT) + list( + APPEND RS_SOURCES + dht/connectstatebox.cc + dht/p3bitdht.cc + dht/p3bitdht_interface.cc + dht/p3bitdht_peernet.cc + dht/p3bitdht_peers.cc + dht/p3bitdht_relay.cc ) +endif(RS_BITDHT) + +list( + APPEND RS_SOURCES + file_sharing/filelist_io.cc + file_sharing/rsfilelistitems.cc + file_sharing/file_tree.cc + file_sharing/directory_updater.cc + file_sharing/p3filelists.cc + file_sharing/hash_cache.cc + file_sharing/dir_hierarchy.cc + file_sharing/directory_storage.cc + ft/ftchunkmap.cc + ft/ftfilecreator.cc + ft/ftfileprovider.cc + ft/ftfilesearch.cc + ft/ftturtlefiletransferitem.cc + ft/fttransfermodule.cc + ft/ftcontroller.cc + ft/ftdatamultiplex.cc + ft/ftextralist.cc + ft/ftserver.cc ) + +list( + APPEND RS_SOURCES + grouter/groutermatrix.cc + grouter/grouteritems.cc + grouter/p3grouter.cc ) + +list( + APPEND RS_SOURCES + gxs/rsgxsdata.cc + gxs/rsgxsrequesttypes.cc + gxs/gxssecurity.cc + gxs/gxstokenqueue.cc + gxs/rsdataservice.cc + gxs/rsgxsdataaccess.cc + gxs/rsgxsnetutils.cc + gxs/rsgxsnettunnel.cc + gxs/rsgxsutil.cc + gxs/rsnxsobserver.cpp + gxs/rsgenexchange.cc + gxs/rsgxsnetservice.cc ) + +list( + APPEND RS_SOURCES + gxstrans/p3gxstransitems.cc + gxstrans/p3gxstrans.cc ) + +list( + APPEND RS_SOURCES + gxstunnel/rsgxstunnelitems.cc + gxstunnel/p3gxstunnel.cc ) + +if(RS_JSON_API) + list( + APPEND RS_SOURCES + jsonapi/jsonapi.cpp ) +endif(RS_JSON_API) + +list( + APPEND RS_SOURCES + pgp/pgpkeyutil.cc + pgp/pgpauxutils.cc + pgp/pgphandler.cc + pgp/rscertificate.cc ) + +#./plugins/dlfcn_win32.cc +#./plugins/dlfcn_win32.h +#./plugins/pluginmanager.h +#./plugins/rscacheservice.h +#./plugins/rspqiservice.h +#./plugins/pluginmanager.cc + +list( + APPEND RS_SOURCES + pqi/pqibin.cc + pqi/pqiipset.cc + pqi/pqiloopback.cc + pqi/pqimonitor.cc + pqi/pqipersongrp.cc + pqi/pqiqos.cc + pqi/pqiqosstreamer.cc + pqi/pqisslproxy.cc + pqi/pqistore.cc + pqi/authgpg.cc + pqi/p3cfgmgr.cc + pqi/p3notify.cc + pqi/p3servicecontrol.cc + pqi/pqinetstatebox.cc + pqi/pqiperson.cc + pqi/pqiservice.cc + pqi/pqissllistener.cc + pqi/pqissludp.cc + pqi/pqithreadstreamer.cc + pqi/sslfns.cc + pqi/authssl.cc + pqi/p3historymgr.cc + pqi/p3linkmgr.cc + pqi/pqihandler.cc + pqi/pqistreamer.cc + pqi/p3netmgr.cc + pqi/p3peermgr.cc + pqi/pqinetwork.cc + pqi/pqissl.cc + pqi/pqisslpersongrp.cc ) + +#./pqi/pqissli2psam3.cpp +#./pqi/pqissli2psam3.h + +list( + APPEND RS_SOURCES + rsitems/rsbanlistitems.cc + rsitems/rsbwctrlitems.cc + rsitems/rsconfigitems.cc + rsitems/rsfiletransferitems.cc + rsitems/rsgxscommentitems.cc + rsitems/rsgxsforumitems.cc + rsitems/rsgxsiditems.cc + rsitems/rsgxsrecognitems.cc + rsitems/rsgxsreputationitems.cc + rsitems/rsgxsupdateitems.cc + rsitems/rshistoryitems.cc + rsitems/rsrttitems.cc + rsitems/rsserviceinfoitems.cc ) + +#./rsitems/rswikiitems.cc +#./rsitems/rswikiitems.h +#./rsitems/rswireitems.h + +list( + APPEND RS_SOURCES + rsitems/rsgxschannelitems.cc + rsitems/rsgxscircleitems.cc + rsitems/rsgxsitems.cc + rsitems/rsmsgitems.cc ) + +#./rsitems/rsphotoitems.cc +#./rsitems/rsphotoitems.h +#./rsitems/rsposteditems.cc +#./rsitems/rsposteditems.h +#./rsitems/rswireitems.cc + +list( + APPEND RS_SOURCES + rsitems/rsnxsitems.cc ) + +list( + APPEND RS_SOURCES + rsserver/p3status.cc + rsserver/p3face-config.cc + rsserver/p3face-info.cc + rsserver/p3history.cc + rsserver/p3serverconfig.cc + rsserver/rsloginhandler.cc + rsserver/p3face-server.cc + rsserver/p3msgs.cc + rsserver/p3peers.cc + rsserver/rsaccounts.cc + rsserver/rsinit.cc ) + +list( + APPEND RS_SOURCES + serialiser/rsbaseserial.cc + serialiser/rsserializable.cc + serialiser/rstlvaddrs.cc + serialiser/rstlvbanlist.cc + serialiser/rstlvbase.cc + serialiser/rstlvbinary.cc + serialiser/rstlvfileitem.cc + serialiser/rstlvgenericmap.inl + serialiser/rstlvgenericparam.cc + serialiser/rstlvidset.cc + serialiser/rstlvimage.cc + serialiser/rstlvitem.cc + serialiser/rstlvkeys.cc + serialiser/rstlvkeyvalue.cc + serialiser/rstlvstring.cc + serialiser/rsserializer.cc + serialiser/rstypeserializer.cc + serialiser/rsserial.cc ) + +# ./services/autoproxy +#./services/autoproxy/p3i2psam3.cpp +#./services/autoproxy/p3i2psam3.h + +list( + APPEND RS_SOURCES + services/autoproxy/rsautoproxymonitor.cc + services/p3bwctrl.cc + services/p3heartbeat.cc + services/p3service.cc + services/p3serviceinfo.cc + services/p3statusservice.cc + services/p3banlist.cc + services/p3rtt.cc + services/rseventsservice.cc + services/p3gxscircles.cc + services/p3gxscommon.cc + services/p3gxsreputation.cc + services/p3msgservice.cc + services/p3idservice.cc + services/p3gxschannels.cc + services/p3gxsforums.cc ) + +#./services/p3wiki.cc +#./services/p3wiki.h +#./services/p3wire.cc +#./services/p3wire.h + +#./services/p3photoservice.cc +#./services/p3photoservice.h +#./services/p3postbase.cc +#./services/p3postbase.h +#./services/p3posted.cc +#./services/p3posted.h + +if(RS_BRODCAST_DISCOVERY) + list( + APPEND RS_SOURCES + services/broadcastdiscoveryservice.cc ) +endif(RS_BRODCAST_DISCOVERY) + +list( + APPEND RS_SOURCES + tcponudp/tcppacket.cc + tcponudp/tcpstream.cc + tcponudp/tou.cc + tcponudp/udppeer.cc + tcponudp/bss_tou.cc + tcponudp/udprelay.cc + tcponudp/udpstunner.cc ) + +list( + APPEND RS_SOURCES + turtle/rsturtleitem.cc + turtle/p3turtle.cc ) + +list( + APPEND RS_SOURCES +# util/contentvalue.cc +# util/exampletst.c +# util/rsdbbind.cc +# util/rsdiscspace.cc + util/rsexpr.cc + util/rsprint.cc +# util/rsrecogn.cc +# util/rssharedptr.h +# util/rstickevent.cc + util/rstime.cc + util/smallobject.cc +# util/retrodb.cc + util/rsbase64.cc + util/rsjson.cc +# util/rskbdinput.cc + util/rsrandom.cc + util/rsstring.cc + util/rsurl.cc + util/folderiterator.cc + util/rsdir.cc + util/dnsresolver.cc + util/extaddrfinder.cc + util/rsdebug.cc + util/rsdnsutils.cc + util/rsnet.cc + util/rsnet_ss.cc + util/rsthreads.cc ) + +# util/i2pcommon.cpp +# util/i2pcommon.h + +if(RS_FORUM_DEEP_INDEX) + list( + APPEND RS_SOURCES + deep_search/commonutils.cpp + deep_search/forumsindex.cpp ) +endif(RS_FORUM_DEEP_INDEX) + + +#./deep_search/filesflacindexer.hpp +#./deep_search/filesoggindexer.hpp +#./deep_search/filestaglibindexer.hpp +#./deep_search/filesindex.cpp +#./deep_search/filesindex.hpp +#./deep_search/channelsindex.cpp +#./deep_search/channelsindex.hpp + +list( + APPEND RS_SOURCES + gossipdiscovery/gossipdiscoveryitems.cc + gossipdiscovery/p3gossipdiscovery.cc ) + +if(RS_MINIUPNPC) +list( + APPEND RS_SOURCES + rs_upnp/upnphandler_miniupnp.cc ) +endif(RS_MINIUPNPC) + +#./rs_upnp/UPnPBase.cpp +#./rs_upnp/upnphandler_libupnp.cc +#./rs_upnp/upnptest.cc +#./rs_upnp/upnputil.cc + +#./rs_android/LocalArray.h +#./rs_android/README-ifaddrs-android.adoc +#./rs_android/ScopedFd.h +#./rs_android/androidcoutcerrcatcher.hpp +#./rs_android/errorconditionwrap.cpp +#./rs_android/ifaddrs-android.h +#./rs_android/org +#./rs_android/org/retroshare +#./rs_android/org/retroshare/service +#./rs_android/org/retroshare/service/AssetHelper.java +#./rs_android/org/retroshare/service/ErrorConditionWrap.java +#./rs_android/org/retroshare/service/RetroShareServiceAndroid.java +#./rs_android/retroshareserviceandroid.cpp +#./rs_android/retroshareserviceandroid.hpp +#./rs_android/rsjni.cpp +#./rs_android/rsjni.hpp diff --git a/openpgpsdk/CMakeLists.txt b/openpgpsdk/CMakeLists.txt new file mode 100644 index 000000000..32dd86c6a --- /dev/null +++ b/openpgpsdk/CMakeLists.txt @@ -0,0 +1,27 @@ +# RetroShare decentralized communication platform +# +# Copyright (C) 2021 Gioacchino Mazzurco +# Copyright (C) 2021 Asociación Civil Altermundi +# +# SPDX-License-Identifier: CC0-1.0 + +cmake_minimum_required (VERSION 3.12.0) +project(openpgpsdk) + +find_package(ZLIB REQUIRED) +find_package(BZip2 REQUIRED) +find_package(OpenSSL REQUIRED) + +file(GLOB SOURCES src/openpgpsdk/*.c) +add_library(${PROJECT_NAME} ${SOURCES}) + +target_include_directories( + ${PROJECT_NAME} + PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/src + PRIVATE ${OPENSSL_INCLUDE_DIR} + PRIVATE ${BZIP2_INCLUDE_DIRS} + PRIVATE ${ZLIB_INCLUDE_DIRS} ) + +target_link_libraries( + ${PROJECT_NAME} + OpenSSL::SSL OpenSSL::Crypto BZip2::BZip2 ZLIB::ZLIB ) From a757419d6591ad5ca42c8a7346ded175c5b66627 Mon Sep 17 00:00:00 2001 From: csoler Date: Thu, 9 Dec 2021 21:04:49 +0100 Subject: [PATCH 059/113] 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 060/113] 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 061/113] 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 062/113] 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 fddb88010e3fab4b3f3de468d55f28796834fcdf Mon Sep 17 00:00:00 2001 From: defnax Date: Sat, 11 Dec 2021 11:37:02 +0100 Subject: [PATCH 063/113] Fixed fonts size for boards title * Fixed fonts size for boards title * Fixed vertical spacer to not stretch the height of the Subscribe Button --- retroshare-gui/src/gui/Posted/PostedListWidgetWithModel.ui | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/retroshare-gui/src/gui/Posted/PostedListWidgetWithModel.ui b/retroshare-gui/src/gui/Posted/PostedListWidgetWithModel.ui index 0433fe838..9ed0fc3db 100644 --- a/retroshare-gui/src/gui/Posted/PostedListWidgetWithModel.ui +++ b/retroshare-gui/src/gui/Posted/PostedListWidgetWithModel.ui @@ -251,7 +251,7 @@ p, li { white-space: pre-wrap; } Qt::Vertical
- QSizePolicy::Preferred + QSizePolicy::Expanding @@ -310,7 +310,7 @@ p, li { white-space: pre-wrap; } - 11 + 25 75 true true From b5d1febac44371471569f4cfab3c170a325635ed Mon Sep 17 00:00:00 2001 From: defnax Date: Sun, 12 Dec 2021 19:01:29 +0100 Subject: [PATCH 064/113] Added spacing for the QPushButton --- retroshare-gui/src/gui/qss/stylesheet/Standard_Dark.qss | 9 +++++++++ retroshare-gui/src/gui/qss/stylesheet/Standard_Light.qss | 9 +++++++++ 2 files changed, 18 insertions(+) diff --git a/retroshare-gui/src/gui/qss/stylesheet/Standard_Dark.qss b/retroshare-gui/src/gui/qss/stylesheet/Standard_Dark.qss index d3983c6b9..536a14061 100644 --- a/retroshare-gui/src/gui/qss/stylesheet/Standard_Dark.qss +++ b/retroshare-gui/src/gui/qss/stylesheet/Standard_Dark.qss @@ -2230,6 +2230,15 @@ PlotWidget { /* RetroShare specific part */ /**********************************/ +/**** Fix QPushButton ****/ + +QPushButton, +QPushButton:disabled, +QPushButton:checked { + padding-left: 6px; + padding-right: 6px; +} + /**** Fix QTreeView Items ****/ QTreeView::item, diff --git a/retroshare-gui/src/gui/qss/stylesheet/Standard_Light.qss b/retroshare-gui/src/gui/qss/stylesheet/Standard_Light.qss index 42a727888..a7f1e6c8c 100644 --- a/retroshare-gui/src/gui/qss/stylesheet/Standard_Light.qss +++ b/retroshare-gui/src/gui/qss/stylesheet/Standard_Light.qss @@ -2230,6 +2230,15 @@ PlotWidget { /* RetroShare specific part */ /**********************************/ +/**** Fix QPushButton ****/ + +QPushButton, +QPushButton:disabled, +QPushButton:checked { + padding-left: 6px; + padding-right: 6px; +} + /**** Fix QTreeView Items ****/ QTreeView::item, From e62b8472345d54affdb0cacf02d0e9b90d0f5577 Mon Sep 17 00:00:00 2001 From: Gioacchino Mazzurco Date: Mon, 13 Dec 2021 18:42:28 +0100 Subject: [PATCH 065/113] Integrate python3 JSON API generator into libretroshare Add more options to CMake: Support for JSON API Support for forum deep index Fix bitdht CMake project name General CMake files improvements --- jsonapi-generator/README.adoc | 449 +----------------- .../async-method-wrapper-template.cpp.tmpl | 81 +--- .../src/jsonapi-generator-doxygen.conf | 231 +-------- .../src/method-wrapper-template.cpp.tmpl | 51 +- libbitdht/CMakeLists.txt | 2 +- libretroshare/CMakeLists.txt | 226 +++++++-- libretroshare/src/CMakeLists.txt | 68 ++- libretroshare/src/jsonapi/README.adoc | 447 +++++++++++++++++ .../async-method-wrapper-template.cpp.tmpl | 80 ++++ .../jsonapi/jsonapi-generator-doxygen.conf | 230 +++++++++ .../src/jsonapi/jsonapi-generator.py | 365 ++++++++++++++ .../jsonapi/method-wrapper-template.cpp.tmpl | 50 ++ 12 files changed, 1444 insertions(+), 836 deletions(-) mode change 100644 => 120000 jsonapi-generator/src/async-method-wrapper-template.cpp.tmpl mode change 100644 => 120000 jsonapi-generator/src/jsonapi-generator-doxygen.conf mode change 100644 => 120000 jsonapi-generator/src/method-wrapper-template.cpp.tmpl create mode 100644 libretroshare/src/jsonapi/README.adoc create mode 100644 libretroshare/src/jsonapi/async-method-wrapper-template.cpp.tmpl create mode 100644 libretroshare/src/jsonapi/jsonapi-generator-doxygen.conf create mode 100755 libretroshare/src/jsonapi/jsonapi-generator.py create mode 100644 libretroshare/src/jsonapi/method-wrapper-template.cpp.tmpl diff --git a/jsonapi-generator/README.adoc b/jsonapi-generator/README.adoc index 64284b85c..cea59a117 100644 --- a/jsonapi-generator/README.adoc +++ b/jsonapi-generator/README.adoc @@ -1,447 +1,10 @@ -// SPDX-FileCopyrightText: (C) 2004-2019 Retroshare Team +// SPDX-FileCopyrightText: (C) 2021 Retroshare Team // SPDX-License-Identifier: CC0-1.0 -RetroShare JSON API -=================== += Moved -:Cxx: C++ +JSON API generator is now part of `libretroshare` look under `src/jsonapi/` +directory in `libretroshare` repository. -== How to use RetroShare JSON API - -Look for methods marked with +@jsonapi+ doxygen custom command into -+libretroshare/src/retroshare+. The method path is composed by service instance -pointer name like +rsGxsChannels+ for +RsGxsChannels+, and the method name like -+createGroup+ and pass the input paramethers as a JSON object. - -.Service instance pointer in rsgxschannels.h -[source,cpp] --------------------------------------------------------------------------------- -/** - * Pointer to global instance of RsGxsChannels service implementation - * @jsonapi{development} - */ -extern RsGxsChannels* rsGxsChannels; --------------------------------------------------------------------------------- - -.Method declaration in rsgxschannels.h -[source,cpp] --------------------------------------------------------------------------------- - /** - * @brief Request channel creation. - * The action is performed asyncronously, so it could fail in a subsequent - * phase even after returning true. - * @jsonapi{development} - * @param[out] token Storage for RsTokenService token to track request - * status. - * @param[in] group Channel data (name, description...) - * @return false on error, true otherwise - */ - virtual bool createGroup(uint32_t& token, RsGxsChannelGroup& group) = 0; --------------------------------------------------------------------------------- - -.paramethers.json -[source,json] --------------------------------------------------------------------------------- -{ - "group":{ - "mMeta":{ - "mGroupName":"JSON test group", - "mGroupFlags":4, - "mSignFlags":520 - }, - "mDescription":"JSON test group description" - }, - "caller_data":"Here can go any kind of JSON data (even objects) that the caller want to get back together with the response" -} --------------------------------------------------------------------------------- - -.Calling the JSON API with curl on the terminal -[source,bash] --------------------------------------------------------------------------------- -curl -u $API_USER --data @paramethers.json http://127.0.0.1:9092/rsGxsChannels/createGroup --------------------------------------------------------------------------------- - -.JSON API call result -[source,json] --------------------------------------------------------------------------------- -{ - "caller_data": "Here can go any kind of JSON data (even objects) that the caller want to get back together with the response", - "retval": true, - "token": 3 -} --------------------------------------------------------------------------------- - -Even if it is less efficient because of URL encoding HTTP +GET+ method is -supported too, so in cases where the client cannot use +POST+ she can still use -+GET+ taking care of encoding the JSON data. With +curl+ this can be done at -least in two different ways. - -.Calling the JSON API with GET method with curl on the terminal -[source,bash] --------------------------------------------------------------------------------- -curl -u $API_USER --get --data-urlencode jsonData@paramethers.json \ - http://127.0.0.1:9092/rsGxsChannels/createGroup --------------------------------------------------------------------------------- - -Letting +curl+ do the encoding is much more elegant but it is semantically -equivalent to the following. - -.Calling the JSON API with GET method and pre-encoded data with curl on the terminal --------------------------------------------------------------------------------- -curl -u $API_USER http://127.0.0.1:9092/rsGxsChannels/createGroup?jsonData=%7B%0A%20%20%20%20%22group%22%3A%7B%0A%20%20%20%20%20%20%20%20%22mMeta%22%3A%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%22mGroupName%22%3A%22JSON%20test%20group%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%22mGroupFlags%22%3A4%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%22mSignFlags%22%3A520%0A%20%20%20%20%20%20%20%20%7D%2C%0A%20%20%20%20%20%20%20%20%22mDescription%22%3A%22JSON%20test%20group%20description%22%0A%20%20%20%20%7D%2C%0A%20%20%20%20%22caller_data%22%3A%22Here%20can%20go%20any%20kind%20of%20JSON%20data%20%28even%20objects%29%20that%20the%20caller%20want%20to%20get%20back%20together%20with%20the%20response%22%0A%7D --------------------------------------------------------------------------------- - -Note that using +GET+ method +?jsonData=+ and then the JSON data URL encoded are -added after the path in the HTTP request. - - -== JSON API authentication - -Most of JSON API methods require authentication as they give access to -RetroShare user data, and we don't want any application running on the system -eventually by other users be able to access private data indiscriminately. -JSON API support HTTP Basic as authentication scheme, this is enough as JSON API -server is intented for usage on the same system (127.0.0.1) not over an -untrusted network. -If you need to use JSON API over an untrusted network consider using a reverse -proxy with HTTPS such as NGINX in front of JSON API server. -If RetroShare login has been effectuated through the JSON API you can use your -location SSLID as username and your PGP password as credential for the JSON API, -but we suggests you use specific meaningful and human readable credentials for -each JSON API client so the human user can have better control over which client -can access the JSON API. - -.NewToken.json -[source,json] --------------------------------------------------------------------------------- -{ - "token": "myNewUser:myNewPassword" -} --------------------------------------------------------------------------------- - -.An authenticated client can authorize new tokens like this --------------------------------------------------------------------------------- -curl -u $API_USER --data @NewToken.json http://127.0.0.1:9092/jsonApiServer/authorizeToken --------------------------------------------------------------------------------- - -.An unauthenticated JSON API client can request access with --------------------------------------------------------------------------------- -curl --data @NewToken.json http://127.0.0.1:9092/jsonApiServer/requestNewTokenAutorization --------------------------------------------------------------------------------- - -When an unauthenticated client request his token to be authorized, JSON API -server will try to ask confirmation to the human user if possible through -+mNewAccessRequestCallback+, if it is not possible or the user didn't authorized -the token +false+ is returned. - - -== Offer new RetroShare services through JSON API - -To offer a retroshare service through the JSON API, first of all one need find -the global pointer to the service instance and document it in doxygen syntax, -plus marking with the custom doxygen command +@jsonapi{RS_VERSION}+ where -+RS_VERSION+ is the retroshare version in which this service became available -with the current semantic (major changes to the service semantic, changes the -meaning of the service itself, so the version should be updated in the -documentation in that case). - -.Service instance pointer in rsgxschannels.h -[source,cpp] --------------------------------------------------------------------------------- -/** - * Pointer to global instance of RsGxsChannels service implementation - * @jsonapi{development} - */ -extern RsGxsChannels* rsGxsChannels; --------------------------------------------------------------------------------- - - -Once the service instance itself is known to the JSON API you need to document -in doxygen syntax and mark with the custom doxygen command -+@jsonapi{RS_VERSION}+ the methods of the service that you want to make -available through JSON API. - -.Offering RsGxsChannels::getChannelDownloadDirectory in rsgxschannels.h -[source,cpp] --------------------------------------------------------------------------------- - /** - * Get download directory for the given channel - * @jsonapi{development} - * @param[in] channelId id of the channel - * @param[out] directory reference to string where to store the path - * @return false on error, true otherwise - */ - virtual bool getChannelDownloadDirectory( const RsGxsGroupId& channelId, - std::string& directory ) = 0; --------------------------------------------------------------------------------- - -For each paramether you must specify if it is used as input +@param[in]+ as -output +@param[out]+ or both +@param[inout]+. Paramethers and return value -types must be of a type supported by +RsTypeSerializer+ which already support -most basic types (+bool+, +std::string+...), +RsSerializable+ and containers of -them like +std::vector+. Paramethers passed by value and by -reference of those types are both supported, while passing by pointer is not -supported. If your paramether or return +class+/+struct+ type is not supported -yet by +RsTypeSerializer+ most convenient approach is to make it derive from -+RsSerializable+ and implement +serial_process+ method like I did with -+RsGxsChannelGroup+. - -.Deriving RsGxsChannelGroup from RsSerializable in rsgxschannels.h -[source,cpp] --------------------------------------------------------------------------------- -struct RsGxsChannelGroup : RsSerializable -{ - RsGroupMetaData mMeta; - std::string mDescription; - RsGxsImage mImage; - - bool mAutoDownload; - - /// @see RsSerializable - virtual void serial_process( RsGenericSerializer::SerializeJob j, - RsGenericSerializer::SerializeContext& ctx ) - { - RS_SERIAL_PROCESS(mMeta); - RS_SERIAL_PROCESS(mDescription); - RS_SERIAL_PROCESS(mImage); - RS_SERIAL_PROCESS(mAutoDownload); - } -}; --------------------------------------------------------------------------------- - -You can do the same recursively for any member of your +struct+ that is not yet -supported by +RsTypeSerializer+. - -Some Retroshare {Cxx} API functions are asyncronous, historically RetroShare -didn't follow a policy on how to expose asyncronous API so differents services -and some times even differents method of the same service follow differents -asyncronous patterns, thus making automatic generation of JSON API wrappers for -those methods impractical. Instead of dealing with all those differents patterns -I have chosed to support only one new pattern taking advantage of modern {Cxx}11 -and restbed features. On the {Cxx}11 side lambdas and +std::function+s are used, -on the restbed side Server Side Events are used to send asyncronous results. - -Lets see an example so it will be much esier to understand. - -.RsGxsChannels::turtleSearchRequest asyncronous API -[source,cpp] --------------------------------------------------------------------------------- - /** - * @brief Request remote channels search - * @jsonapi{development} - * @param[in] matchString string to look for in the search - * @param multiCallback function that will be called each time a search - * result is received - * @param[in] maxWait maximum wait time in seconds for search results - * @return false on error, true otherwise - */ - virtual bool turtleSearchRequest( - const std::string& matchString, - const std::function& multiCallback, - std::time_t maxWait = 300 ) = 0; --------------------------------------------------------------------------------- - -+RsGxsChannels::turtleSearchRequest(...)+ is an asyncronous method because it -send a channel search request on turtle network and then everytime a result is -received from the network +multiCallback+ is called and the result is passed as -parameter. To be supported by the automatic JSON API wrappers generator an -asyncronous method need a parameter of type +std::function+ called -+callback+ if the callback will be called only once or +multiCallback+ if the -callback is expected to be called more then once like in this case. -A second mandatory parameter is +maxWait+ of type +std::time_t+ it indicates the -maximum amount of time in seconds for which the caller is willing to wait for -results, in case the timeout is reached the callback will not be called anymore. - -[IMPORTANT] -================================================================================ -+callback+ and +multiCallback+ parameters documentation must *not* specify -+[in]+, +[out]+, +[inout]+, in Doxygen documentation as this would fool the -automatic wrapper generator, and ultimately break the compilation. -================================================================================ - -.RsFiles::turtleSearchRequest asyncronous JSON API usage example -[source,bash] --------------------------------------------------------------------------------- -$ cat turtle_search.json -{ - "matchString":"linux" -} -$ curl --data @turtle_search.json http://127.0.0.1:9092/rsFiles/turtleSearchRequest -data: {"retval":true} - -data: {"results":[{"size":157631,"hash":"69709b4d01025584a8def5cd78ebbd1a3cf3fd05","name":"kill_bill_linux_1024x768.jpg"},{"size":192560,"hash":"000000000000000000009a93e5be8486c496f46c","name":"coffee_box_linux2.jpg"},{"size":455087,"hash":"9a93e5be8486c496f46c00000000000000000000","name":"Linux.png"},{"size":182004,"hash":"e8845280912ebf3779e400000000000000000000","name":"Linux_2_6.png"}]} - -data: {"results":[{"size":668,"hash":"e8845280912ebf3779e400000000000000000000","name":"linux.png"},{"size":70,"hash":"e8845280912ebf3779e400000000000000000000","name":"kali-linux-2016.2-amd64.txt.sha1sum"},{"size":3076767744,"hash":"e8845280912ebf3779e400000000000000000000","name":"kali-linux-2016.2-amd64.iso"},{"size":2780872,"hash":"e8845280912ebf3779e400000000000000000000","name":"openwrt-ar71xx-generic-vmlinux.bin"},{"size":917504,"hash":"e8845280912ebf3779e400000000000000000000","name":"openwrt-ar71xx-generic-vmlinux.lzma"},{"size":2278404096,"hash":"e8845280912ebf3779e400000000000000000000","name":"gentoo-linux-livedvd-amd64-multilib-20160704.iso"},{"size":151770333,"hash":"e8845280912ebf3779e400000000000000000000","name":"flashtool-0.9.23.0-linux.tar.7z"},{"size":2847372,"hash":"e8845280912ebf3779e400000000000000000000","name":"openwrt-ar71xx-generic-vmlinux.elf"},{"size":1310720,"hash":"e8845280912ebf3779e400000000000000000000","name":"openwrt-ar71xx-generic-vmlinux.gz"},{"size":987809,"hash":"e8845280912ebf3779e400000000000000000000","name":"openwrt-ar71xx-generic-vmlinux-lzma.elf"}]} - --------------------------------------------------------------------------------- - -By default JSON API methods requires client authentication and their wrappers -are automatically generated by +json-api-generator+. -In some cases methods need do be accessible without authentication such as -+rsLoginHelper/getLocations+ so in the doxygen documentaion they have the custom -command +@jsonapi{RS_VERSION,unauthenticated}+. -Other methods such as +/rsControl/rsGlobalShutDown+ need special care so they -are marked with the custom doxygen command +@jsonapi{RS_VERSION,manualwrapper}+ -and their wrappers are not automatically generated but written manually into -+JsonApiServer::JsonApiServer(...)+. - -== Quirks - -=== 64 bits integers handling - -While JSON doesn't have problems representing 64 bits integers JavaScript, Dart -and other languages are not capable to handle those numbers natively. -To overcome this limitation JSON API output 64 bit integers as an object with -two keys, one as proper integer and one as string representation. - -.JSON API 64 bit integer output example -[source,json] --------------------------------------------------------------------------------- -"lobby_id": { "xint64": 6215642878098695544, "xstr64": "6215642878098695544" } --------------------------------------------------------------------------------- - -So from languages that have proper 64bit integers support like Python or C++ one -better read from `xint64` which is represented as a JSON integer, from languages -where there is no proper 64bit integers support like JavaScript one can read from -`xstr64` which is represented as JSON string (note that the first is not wrapped -in "" while the latter is). - -When one input a 64bit integer into the JSON API it first try to parse it as if -it was sent the old way for retrocompatibility. - -.JSON API 64 bit integer deprecated format input example -[source,json] --------------------------------------------------------------------------------- -"lobby_id":6215642878098695544 --------------------------------------------------------------------------------- - -This way is *DEPRECATED* and may disappear in the future, it is TEMPORALLY kept -only for retrocompatibiliy with old clients. - -If retrocompatible parsing attempt fail then it try to parse with the new way -with proper JSON integer format. - -.JSON API 64 bit integer new proper integer format input example -[source,json] --------------------------------------------------------------------------------- -lobby_id": { "xint64": 6215642878098695544 } --------------------------------------------------------------------------------- - -If this fails then it try to parse with the new way with JSON string format. - -.JSON API 64 bit integer new string format input example -[source,json] --------------------------------------------------------------------------------- -"lobby_id": { "xstr64": "6215642878098695544" } --------------------------------------------------------------------------------- - -[WARNING] -================================================================================ -Clients written in languages without proper 64bit integers support must -use *ONLY* the string format otherwise they will send approximated values and -get unexpected results from the JSON API, because parsing will success but the -value will not be exactly the one you believe you sent. -================================================================================ - - -== A bit of history - -=== First writings about this - -The previous attempt of exposing a RetroShare JSON API is called +libresapi+ and -unfortunatley it requires a bunch of boilerplate code when we want to expose -something present in the {Cxx} API in the JSON API. - -As an example here you can see the libresapi that exposes part of the retroshare -chat {Cxx} API and lot of boilerplate code just to convert {Cxx} objects to JSON - -https://github.com/RetroShare/RetroShare/blob/v0.6.4/libresapi/src/api/ChatHandler.cpp#L44 - -To avoid the {Cxx} to JSON and back conversion boilerplate code I have worked out -an extension to our {Cxx} serialization code so it is capable to serialize and -deserialize to JSON you can see it in this pull request - -https://github.com/RetroShare/RetroShare/pull/1155 - -So first step toward having a good API is to take advantage of the fact that RS -is now capable of converting C++ objects from and to JSON. - -The current API is accessible via HTTP and unix socket, there is no -authentication in both of them, so anyone having access to the HTTP server or to -the unix socket can access the API without extra restrictions. -Expecially for the HTTP API this is a big risk because also if the http server -listen on 127.0.0.1 every application on the machine (even rogue javascript -running on your web browser) can access that and for example on android it is -not safe at all (because of that I implemented the unix socket access so at -least in android API was reasonably safe) because of this. - -A second step to improve the API would be to implement some kind of API -authentication mechanism (it would be nice that the mechanism is handled at API -level and not at transport level so we can use it for any API trasport not just -HTTP for example) - -The HTTP server used by libresapi is libmicrohttpd server that is very minimal, -it doesn't provide HTTPS nor modern HTTP goodies, like server notifications, -websockets etc. because the lack of support we have a token polling mechanism in -libresapi to avoid polling for every thing but it is still ugly, so if we can -completely get rid of polling in the API that would be really nice. -I have done a crawl to look for a replacement and briefly looked at - -- https://www.gnu.org/software/libmicrohttpd/ -- http://wolkykim.github.io/libasyncd/ -- https://github.com/corvusoft/restbed -- https://code.facebook.com/posts/1503205539947302/introducing-proxygen-facebook-s-c-http-framework/ -- https://github.com/cmouse/yahttp - -taking in account a few metrics like modern HTTP goodies support, license, -platform support, external dependencies and documentation it seemed to me that -restbed is the more appropriate. - -Another source of boilerplate code into libresapi is the mapping between JSON -API requests and C++ API methods as an example you can look at this - -https://github.com/RetroShare/RetroShare/blob/v0.6.4/libresapi/src/api/ChatHandler.cpp#L158 - -and this - -https://github.com/RetroShare/RetroShare/blob/v0.6.4/libresapi/src/api/ApiServer.cpp#L253 - -The abstract logic of this thing is, when libreasapi get a request like -+/chat/initiate_distant_chat+ then call -+ChatHandler::handleInitiateDistantChatConnexion+ which in turn is just a -wrapper of +RsMsgs::initiateDistantChatConnexion+ all this process is basically -implemented as boilerplate code and would be unnecessary in a smarter design of -the API because almost all the information needed is already present in the -C++ API +libretroshare/src/retroshare+. - -So a third step to improve the JSON API would be to remove this source of -boilerplate code by automatizing the mapping between C++ and JSON API call. - -This may result a little tricky as language parsing or other adevanced things -may be required. - -Hope this dive is useful for you + -Cheers + -G10h4ck - -=== Second writings about this - -I have been investigating a bit more about: -[verse, G10h4ck] -________________________________________________________________________________ -So a third step to improve the JSON API would be to remove this source of -boilerplate code by automatizing the mapping between C++ and JSON API call -________________________________________________________________________________ - -After spending some hours investigating this topic the most reasonable approach -seems to: - -1. Properly document headers in +libretroshare/src/retroshare/+ in doxygen syntax -specifying wihich params are input and/or output (doxygen sysntax for this is -+@param[in/out/inout]+) this will be the API documentation too. - -2. At compile time use doxygen to generate XML description of the headers and use -the XML to generate the JSON api server stub. -http://www.stack.nl/~dimitri/doxygen/manual/customize.html#xmlgenerator - -3. Enjoy +This directory and all it's content is kept as is only for retro-compatibility +with the old, deprecated `qmake` build system. diff --git a/jsonapi-generator/src/async-method-wrapper-template.cpp.tmpl b/jsonapi-generator/src/async-method-wrapper-template.cpp.tmpl deleted file mode 100644 index 29f53ad48..000000000 --- a/jsonapi-generator/src/async-method-wrapper-template.cpp.tmpl +++ /dev/null @@ -1,80 +0,0 @@ -/******************************************************************************* - * RetroShare JSON API * - * * - * Copyright (C) 2018-2019 Gioacchino Mazzurco * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Affero General Public License version 3 as * - * published by the Free Software Foundation. * - * * - * 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 Affero General Public License for more details. * - * * - * You should have received a copy of the GNU Affero General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ - -registerHandler( "$%apiPath%$", - [this](const std::shared_ptr session) -{ - const std::multimap headers - { - { "Connection", "keep-alive" }, - { "Content-Type", "text/event-stream" } - }; - session->yield(rb::OK, headers); - - size_t reqSize = session->get_request()->get_header("Content-Length", 0); - session->fetch( reqSize, [this]( - const std::shared_ptr session, - const rb::Bytes& body ) - { - INITIALIZE_API_CALL_JSON_CONTEXT; - - if( !checkRsServicePtrReady( - $%instanceName%$, "$%instanceName%$", cAns, session ) ) - return; - -$%paramsDeclaration%$ - -$%inputParamsDeserialization%$ - - const std::weak_ptr weakService(mService); - const std::weak_ptr weakSession(session); - $%callbackName%$ = [weakService, weakSession]($%callbackParams%$) - { - auto session = weakSession.lock(); - if(!session || session->is_closed()) return; - - auto lService = weakService.lock(); - if(!lService || lService->is_down()) return; - -$%callbackParamsSerialization%$ - - std::stringstream sStream; - sStream << "data: " << compactJSON << ctx.mJson << "\n\n"; - const std::string message = sStream.str(); - - lService->schedule( [weakSession, message]() - { - auto session = weakSession.lock(); - if(!session || session->is_closed()) return; - session->yield(message); - $%sessionEarlyClose%$ - } ); - }; - -$%functionCall%$ - -$%outputParamsSerialization%$ - - // return them to the API caller - std::stringstream message; - message << "data: " << compactJSON << cAns.mJson << "\n\n"; - session->yield(message.str()); - $%sessionDelayedClose%$ - } ); -}, $%requiresAuth%$ ); diff --git a/jsonapi-generator/src/async-method-wrapper-template.cpp.tmpl b/jsonapi-generator/src/async-method-wrapper-template.cpp.tmpl new file mode 120000 index 000000000..1ae671997 --- /dev/null +++ b/jsonapi-generator/src/async-method-wrapper-template.cpp.tmpl @@ -0,0 +1 @@ +../../libretroshare/src/jsonapi/async-method-wrapper-template.cpp.tmpl \ No newline at end of file diff --git a/jsonapi-generator/src/jsonapi-generator-doxygen.conf b/jsonapi-generator/src/jsonapi-generator-doxygen.conf deleted file mode 100644 index 0edd1de3e..000000000 --- a/jsonapi-generator/src/jsonapi-generator-doxygen.conf +++ /dev/null @@ -1,230 +0,0 @@ -DOXYFILE_ENCODING = UTF-8 -PROJECT_NAME = "libretroshare" - -ALIASES += jsonapi{1}="\xmlonly\endxmlonly" -ALIASES += jsonapi{2}="\xmlonly\endxmlonly" - -# If the INHERIT_DOCS tag is set to YES then an undocumented member inherits the -# documentation from any documented member that it re-implements. -# The default value is: YES. - -INHERIT_DOCS = YES - -# If the MARKDOWN_SUPPORT tag is enabled then doxygen pre-processes all comments -# according to the Markdown format, which allows for more readable -# documentation. See http://daringfireball.net/projects/markdown/ for details. -# The output of markdown processing is further processed by doxygen, so you can -# mix doxygen, HTML, and XML commands with Markdown formatting. Disable only in -# case of backward compatibilities issues. -# The default value is: YES. - -MARKDOWN_SUPPORT = YES - -# When enabled doxygen tries to link words that correspond to documented -# classes, or namespaces to their corresponding documentation. Such a link can -# be prevented in individual cases by putting a % sign in front of the word or -# globally by setting AUTOLINK_SUPPORT to NO. -# The default value is: YES. - -AUTOLINK_SUPPORT = YES - - -# If the EXTRACT_ALL tag is set to YES, doxygen will assume all entities in -# documentation are documented, even if no documentation was available. Private -# class members and static file members will be hidden unless the -# EXTRACT_PRIVATE respectively EXTRACT_STATIC tags are set to YES. -# Note: This will also disable the warnings about undocumented members that are -# normally produced when WARNINGS is set to YES. -# The default value is: NO. - -EXTRACT_ALL = YES - - -# If the HIDE_UNDOC_MEMBERS tag is set to YES, doxygen will hide all -# undocumented members inside documented classes or files. If set to NO these -# members will be included in the various overviews, but no documentation -# section is generated. This option has no effect if EXTRACT_ALL is enabled. -# The default value is: NO. - -HIDE_UNDOC_MEMBERS = NO - -# If the HIDE_UNDOC_CLASSES tag is set to YES, doxygen will hide all -# undocumented classes that are normally visible in the class hierarchy. If set -# to NO, these classes will be included in the various overviews. This option -# has no effect if EXTRACT_ALL is enabled. -# The default value is: NO. - -HIDE_UNDOC_CLASSES = NO - - -#--------------------------------------------------------------------------- -# Configuration options related to the input files -#--------------------------------------------------------------------------- - -# The INPUT tag is used to specify the files and/or directories that contain -# documented source files. You may enter file names like myfile.cpp or -# directories like /usr/src/myproject. Separate the files or directories with -# spaces. See also FILE_PATTERNS and EXTENSION_MAPPING -# Note: If this tag is empty the current directory is searched. - -#INPUT = - -# This tag can be used to specify the character encoding of the source files -# that doxygen parses. Internally doxygen uses the UTF-8 encoding. Doxygen uses -# libiconv (or the iconv built into libc) for the transcoding. See the libiconv -# documentation (see: https://www.gnu.org/software/libiconv/) for the list of -# possible encodings. -# The default value is: UTF-8. - -INPUT_ENCODING = UTF-8 - -# If the value of the INPUT tag contains directories, you can use the -# FILE_PATTERNS tag to specify one or more wildcard patterns (like *.cpp and -# *.h) to filter out the source-files in the directories. -# -# Note that for custom extensions or not directly supported extensions you also -# need to set EXTENSION_MAPPING for the extension otherwise the files are not -# read by doxygen. -# -# If left blank the following patterns are tested:*.c, *.cc, *.cxx, *.cpp, -# *.c++, *.java, *.ii, *.ixx, *.ipp, *.i++, *.inl, *.idl, *.ddl, *.odl, *.h, -# *.hh, *.hxx, *.hpp, *.h++, *.cs, *.d, *.php, *.php4, *.php5, *.phtml, *.inc, -# *.m, *.markdown, *.md, *.mm, *.dox, *.py, *.pyw, *.f90, *.f95, *.f03, *.f08, -# *.f, *.for, *.tcl, *.vhd, *.vhdl, *.ucf and *.qsf. - -FILE_PATTERNS = *.c \ - *.cc \ - *.cxx \ - *.cpp \ - *.c++ \ - *.java \ - *.ii \ - *.ixx \ - *.ipp \ - *.i++ \ - *.inl \ - *.idl \ - *.ddl \ - *.odl \ - *.h \ - *.hh \ - *.hxx \ - *.hpp \ - *.h++ \ - *.cs \ - *.d \ - *.php \ - *.php4 \ - *.php5 \ - *.phtml \ - *.inc \ - *.m \ - *.markdown \ - *.md \ - *.mm \ - *.dox \ - *.py \ - *.pyw \ - *.f90 \ - *.f95 \ - *.f03 \ - *.f08 \ - *.f \ - *.for \ - *.tcl \ - *.vhd \ - *.vhdl \ - *.ucf \ - *.qsf - -# The RECURSIVE tag can be used to specify whether or not subdirectories should -# be searched for input files as well. -# The default value is: NO. - -RECURSIVE = YES - -# The EXCLUDE tag can be used to specify files and/or directories that should be -# excluded from the INPUT source files. This way you can easily exclude a -# subdirectory from a directory tree whose root is specified with the INPUT tag. -# -# Note that relative paths are relative to the directory from which doxygen is -# run. - -EXCLUDE = - -# The EXCLUDE_SYMLINKS tag can be used to select whether or not files or -# directories that are symbolic links (a Unix file system feature) are excluded -# from the input. -# The default value is: NO. - -EXCLUDE_SYMLINKS = NO - -# If the value of the INPUT tag contains directories, you can use the -# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude -# certain files from those directories. -# -# Note that the wildcards are matched against the file with absolute path, so to -# exclude all test directories for example use the pattern */test/* - -EXCLUDE_PATTERNS = - -# The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names -# (namespaces, classes, functions, etc.) that should be excluded from the -# output. The symbol name can be a fully qualified name, a word, or if the -# wildcard * is used, a substring. Examples: ANamespace, AClass, -# AClass::ANamespace, ANamespace::*Test -# -# Note that the wildcards are matched against the file with absolute path, so to -# exclude all test directories use the pattern */test/* - -EXCLUDE_SYMBOLS = - - -#--------------------------------------------------------------------------- -# Configuration options related to the HTML output -#--------------------------------------------------------------------------- - -# If the GENERATE_HTML tag is set to YES, doxygen will generate HTML output -# The default value is: YES. - -GENERATE_HTML = NO - -# If the GENERATE_LATEX tag is set to YES, doxygen will generate LaTeX output. -# The default value is: YES. - -GENERATE_LATEX = NO - -# If the GENERATE_XML tag is set to YES, doxygen will generate an XML file that -# captures the structure of the code including all documentation. -# The default value is: NO. - -GENERATE_XML = YES - - -#--------------------------------------------------------------------------- -# Configuration options related to the preprocessor -#--------------------------------------------------------------------------- - -# If the ENABLE_PREPROCESSING tag is set to YES, doxygen will evaluate all -# C-preprocessor directives found in the sources and include files. -# The default value is: YES. - -ENABLE_PREPROCESSING = YES - -# If the MACRO_EXPANSION tag is set to YES, doxygen will expand all macro names -# in the source code. If set to NO, only conditional compilation will be -# performed. Macro expansion can be done in a controlled way by setting -# EXPAND_ONLY_PREDEF to YES. -# The default value is: NO. -# This tag requires that the tag ENABLE_PREPROCESSING is set to YES. - -MACRO_EXPANSION = NO - -# If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES then -# the macro expansion is limited to the macros specified with the PREDEFINED and -# EXPAND_AS_DEFINED tags. -# The default value is: NO. -# This tag requires that the tag ENABLE_PREPROCESSING is set to YES. - -EXPAND_ONLY_PREDEF = NO - diff --git a/jsonapi-generator/src/jsonapi-generator-doxygen.conf b/jsonapi-generator/src/jsonapi-generator-doxygen.conf new file mode 120000 index 000000000..9aff33c39 --- /dev/null +++ b/jsonapi-generator/src/jsonapi-generator-doxygen.conf @@ -0,0 +1 @@ +../../libretroshare/src/jsonapi/jsonapi-generator-doxygen.conf \ No newline at end of file diff --git a/jsonapi-generator/src/method-wrapper-template.cpp.tmpl b/jsonapi-generator/src/method-wrapper-template.cpp.tmpl deleted file mode 100644 index a3927fba9..000000000 --- a/jsonapi-generator/src/method-wrapper-template.cpp.tmpl +++ /dev/null @@ -1,50 +0,0 @@ -/******************************************************************************* - * RetroShare JSON API * - * * - * Copyright (C) 2018-2019 Gioacchino Mazzurco * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Affero 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 Affero General Public License for more details. * - * * - * You should have received a copy of the GNU Affero General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ - -registerHandler( "$%apiPath%$", - [](const std::shared_ptr session) -{ - size_t reqSize = session->get_request()->get_header("Content-Length", 0); - session->fetch( reqSize, []( - const std::shared_ptr session, - const rb::Bytes& body ) - { - INITIALIZE_API_CALL_JSON_CONTEXT; - - if( !checkRsServicePtrReady( - $%instanceName%$, "$%instanceName%$", cAns, session ) ) - return; - -$%paramsDeclaration%$ - - // deserialize input parameters from JSON -$%inputParamsDeserialization%$ - - // call retroshare C++ API -$%functionCall%$ - - // serialize out parameters and return value to JSON -$%outputParamsSerialization%$ - - // return them to the API caller - DEFAULT_API_CALL_JSON_RETURN(rb::OK); - } ); -}, $%requiresAuth%$ ); - diff --git a/jsonapi-generator/src/method-wrapper-template.cpp.tmpl b/jsonapi-generator/src/method-wrapper-template.cpp.tmpl new file mode 120000 index 000000000..717044ed2 --- /dev/null +++ b/jsonapi-generator/src/method-wrapper-template.cpp.tmpl @@ -0,0 +1 @@ +../../libretroshare/src/jsonapi/method-wrapper-template.cpp.tmpl \ No newline at end of file diff --git a/libbitdht/CMakeLists.txt b/libbitdht/CMakeLists.txt index 2a996de48..af352651c 100644 --- a/libbitdht/CMakeLists.txt +++ b/libbitdht/CMakeLists.txt @@ -6,7 +6,7 @@ # SPDX-License-Identifier: CC0-1.0 cmake_minimum_required (VERSION 2.8.12) -project(libbitdht) +project(bitdht) file( GLOB BITDHT_SOURCES diff --git a/libretroshare/CMakeLists.txt b/libretroshare/CMakeLists.txt index 0eb111dd7..93c8b04a5 100644 --- a/libretroshare/CMakeLists.txt +++ b/libretroshare/CMakeLists.txt @@ -8,6 +8,11 @@ cmake_minimum_required (VERSION 3.18.0) project(retroshare) +include(CMakeDependentOption) + +set(FETCHCONTENT_QUIET OFF) +include(FetchContent) + # sqlcipher option( RS_SQLCIPHER @@ -28,18 +33,22 @@ option( ON ) # use_dht_stunner -option( +cmake_dependent_option( RS_BITDHT_STUNNER "Use bitdht (BitTorrent DHT own implementation) for NAT type discovery and \ attempt the STUN (Session Traversal Utilities for NAT)" - ON ) + ON + "RS_BITDHT" + OFF ) # use_dht_stunner_ext_ip -option( +cmake_dependent_option( RS_BITDHT_STUNNER_EXT_IP "Use bitdht (BitTorrent DHT own implementation) stunner to figure out our \ external IP. As this purely relying on random DHT peers that answer our \ request, it can easily be abused. Therefore, it is turned off by default." + OFF + "RS_BITDHT_STUNNER" OFF ) # rs_jsonapi @@ -71,53 +80,45 @@ option( option( RS_MINIUPNPC "Forward ports in NAT router via miniupnpc" - ON -) + ON ) -include(CMakeDependentOption) cmake_dependent_option( RS_LIBUPNP "Forward ports in NAT router via libupnp (unstable)" OFF "NOT RS_MINIUPNPC" - OFF -) + OFF ) option( RS_LIBRETROSHARE_STATIC "Build RetroShare static library" - ON -) + ON ) cmake_dependent_option( RS_LIBRETROSHARE_SHARED "Build RetroShare shared library" OFF "NOT RS_LIBRETROSHARE_STATIC" - OFF -) + OFF ) # rs_deprecatedwarning option( RS_WARN_DEPRECATED "Print warning about RetroShare deprecated components usage during build" - ON -) + ON ) # rs_cppwarning option( RS_WARN_LESS "Silence a few at the moment very common warnings about RetroShare \ components during build" - OFF -) + OFF ) # rs_v07_changes option( RS_V07_BREAKING_CHANGES "Enable retro-compatibility breaking changes planned for RetroShare 0.7.0" - OFF -) + OFF ) set( RS_DATA_DIR @@ -127,8 +128,24 @@ set( ################################################################################ +find_package(Git REQUIRED) + +#function(check_submodule sPath) +# if(NOT EXISTS "${sPath}/.git" ) +# message("Initializing submodule ${sPath}") +# execute_process( +# COMMAND "${GIT_EXECUTABLE}" submodule update --init +# WORKING_DIRECTORY "${sPath}" +# COMMAND_ECHO STDERR +# COMMAND_ERROR_IS_FATAL ANY) +# endif() +#endfunction() + +################################################################################ + include(src/CMakeLists.txt) list(TRANSFORM RS_SOURCES PREPEND src/) +list(TRANSFORM RS_PUBLIC_HEADERS PREPEND src/) if(RS_LIBRETROSHARE_STATIC) add_library(${PROJECT_NAME} STATIC ${RS_SOURCES}) @@ -153,15 +170,150 @@ target_link_libraries(${PROJECT_NAME} PRIVATE OpenSSL::SSL OpenSSL::Crypto) ################################################################################ -add_subdirectory(../openpgpsdk ${CMAKE_BINARY_DIR}/openpgpsdk) +set(OPENPGPSDK_DEVEL_DIR "${CMAKE_CURRENT_SOURCE_DIR}/../openpgpsdk/") +if(EXISTS "${OPENPGPSDK_DEVEL_DIR}/.git" ) + message( + CHECK_PASS + "openpgpsdk submodule found at ${OPENPGPSDK_DEVEL_DIR} using it" ) + add_subdirectory(${OPENPGPSDK_DEVEL_DIR} ${CMAKE_BINARY_DIR}/openpgpsdk) +else() + FetchContent_Declare( + openpgpsdk + GIT_REPOSITORY "https://gitlab.com/RetroShare/openpgpsdk.git" + GIT_TAG "origin/master" + GIT_SHALLOW TRUE + GIT_PROGRESS TRUE + TIMEOUT 10 + ) + FetchContent_MakeAvailable(openpgpsdk) +endif() + target_link_libraries(${PROJECT_NAME} PRIVATE openpgpsdk) +################################################################################ + if(RS_BITDHT) + set(BITDHT_DEVEL_DIR "${CMAKE_CURRENT_SOURCE_DIR}/../libbitdht/") + if(EXISTS "${BITDHT_DEVEL_DIR}/.git" ) + message( + CHECK_PASS + "BitDHT submodule found at ${BITDHT_DEVEL_DIR} using it" ) + add_subdirectory(${BITDHT_DEVEL_DIR} ${CMAKE_BINARY_DIR}/bitdht) + else() + FetchContent_Declare( + bitdht + GIT_REPOSITORY "https://gitlab.com/RetroShare/bitdht.git" + GIT_TAG "origin/master" + GIT_SHALLOW TRUE + GIT_PROGRESS TRUE + TIMEOUT 10 + ) + FetchContent_MakeAvailable(bitdht) + endif() + add_compile_definitions(RS_USE_BITDHT) - add_subdirectory(../libbitdht ${CMAKE_BINARY_DIR}/libbitdht) - target_link_libraries(${PROJECT_NAME} PRIVATE libbitdht) + target_link_libraries(${PROJECT_NAME} PRIVATE bitdht) + + if(RS_BITDHT_STUNNER) + add_compile_definitions(RS_USE_DHT_STUNNER) + + if(RS_BITDHT_STUNNER_EXT_IP) + # TODO: Refactor this define to use proper naming + add_compile_definitions(ALLOW_DHT_STUNNER) + endif(RS_BITDHT_STUNNER_EXT_IP) + endif(RS_BITDHT_STUNNER) endif(RS_BITDHT) +################################################################################ + +if(RS_JSON_API) + find_package(Doxygen REQUIRED) + find_package(Python3 REQUIRED) + + ## TODO: execute at build time instead that at cofiguration time see + ## add_custom_command or add_custom_target + + set( + JSON_API_GENERATOR_WORK_DIR + "${CMAKE_BINARY_DIR}/jsonapi-generator.workdir/" ) + + set( + JSON_API_GENERATOR_DOXYFILE + "${JSON_API_GENERATOR_WORK_DIR}/jsonapi-generator-doxygen.conf" ) + + set( + JSONAPI_GENERATOR_OUTPUT_DIR + "${JSON_API_GENERATOR_WORK_DIR}/src/" ) + + set( + JSONAPI_GENERATOR_SOURCE_DIR + "${CMAKE_CURRENT_SOURCE_DIR}/src/jsonapi/" ) + + set( + JSONAPI_GENERATOR_EXECUTABLE + "${JSONAPI_GENERATOR_SOURCE_DIR}/jsonapi-generator.py" ) + + file( + COPY "src/jsonapi/jsonapi-generator-doxygen.conf" + DESTINATION "${JSON_API_GENERATOR_WORK_DIR}" ) + + file( + APPEND + "${JSON_API_GENERATOR_DOXYFILE}" + "OUTPUT_DIRECTORY=${JSONAPI_GENERATOR_OUTPUT_DIR}\n" + "INPUT=${CMAKE_CURRENT_SOURCE_DIR}" ) + + add_custom_command( + OUTPUT + "${JSONAPI_GENERATOR_OUTPUT_DIR}/jsonapi-includes.inl" + "${JSONAPI_GENERATOR_OUTPUT_DIR}/jsonapi-wrappers.inl" + COMMAND ${DOXYGEN_EXECUTABLE} ${JSON_API_GENERATOR_DOXYFILE} + COMMAND + ${Python3_EXECUTABLE} ${JSONAPI_GENERATOR_EXECUTABLE} + ${JSONAPI_GENERATOR_SOURCE_DIR} ${JSONAPI_GENERATOR_OUTPUT_DIR} + MAIN_DEPENDENCY "${JSONAPI_GENERATOR_EXECUTABLE}" + DEPENDS ${JSON_API_GENERATOR_DOXYFILE} ${RS_PUBLIC_HEADERS} ) + + target_sources( + ${PROJECT_NAME} PRIVATE + "${JSONAPI_GENERATOR_OUTPUT_DIR}/jsonapi-includes.inl" + "${JSONAPI_GENERATOR_OUTPUT_DIR}/jsonapi-wrappers.inl" ) + + include_directories(${JSONAPI_GENERATOR_OUTPUT_DIR}) + + set(BUILD_TESTS OFF CACHE BOOL "Do not build restbed tests") + set(BUILD_SSL OFF CACHE BOOL "Do not build restbed SSL support") + + FetchContent_Declare( + restbed + GIT_REPOSITORY "https://github.com/Corvusoft/restbed.git" + GIT_TAG "4.8" + GIT_SUBMODULES dependency/asio dependency/catch + GIT_SHALLOW TRUE + GIT_PROGRESS TRUE + TIMEOUT 10 + ) + FetchContent_MakeAvailable(restbed) + + target_link_libraries(${PROJECT_NAME} PRIVATE restbed) + + ## TODO: work around target_include_directories should be added upstream + include_directories(${restbed_SOURCE_DIR}/source/) + + add_compile_definitions(RS_JSONAPI) +endif(RS_JSON_API) + +################################################################################ + +if(RS_FORUM_DEEP_INDEX) + find_package(Xapian REQUIRED) + target_link_libraries(${PROJECT_NAME} PRIVATE ${XAPIAN_LIBRARIES}) + + add_compile_definitions(RS_DEEP_FORUMS_INDEX) +endif(RS_FORUM_DEEP_INDEX) + +################################################################################ + ## TODO: Check if https://github.com/rbock/sqlpp11 or ## https://github.com/rbock/sqlpp17 may improve GXS code if(RS_SQLCIPHER) @@ -196,12 +348,17 @@ if(RS_V07_BREAKING_CHANGES) V07_NON_BACKWARD_COMPATIBLE_CHANGE_UNNAMED ) endif() +if(RS_DH_PRIME_INIT_CHECK) + add_compile_definitions(RS_DISABLE_DIFFIE_HELLMAN_INIT_CHECK) +endif(RS_DH_PRIME_INIT_CHECK) + if(RS_MINIUPNPC) add_compile_definitions(RS_USE_LIBMINIUPNPC) endif(RS_MINIUPNPC) if(RS_LIBUPNP) - add_compile_definitions(RS_USE_LIBUPNP) + message(FATAL_ERROR "UPnP support via libupnp is currently not supported") + #add_compile_definitions(RS_USE_LIBUPNP) endif(RS_LIBUPNP) if(RS_GXS_SEND_ALL) @@ -209,13 +366,24 @@ if(RS_GXS_SEND_ALL) endif(RS_GXS_SEND_ALL) if(RS_BRODCAST_DISCOVERY) - add_subdirectory( - ../supportlibs/udp-discovery-cpp/ - ${CMAKE_BINARY_DIR}/supportlibs/udp-discovery-cpp/ ) - target_link_libraries(${PROJECT_NAME} PRIVATE udp-discovery) + ## TODO: upstream option to disable tests building + set(BUILD_EXAMPLE OFF CACHE BOOL "Do not build udp-discovery-cpp examples") + set(BUILD_TOOL OFF CACHE BOOL "Do not build udp-discovery-tool application") + FetchContent_Declare( + udp-discovery-cpp + GIT_REPOSITORY "https://github.com/truvorskameikin/udp-discovery-cpp.git" + GIT_TAG "origin/master" + GIT_SHALLOW TRUE + GIT_PROGRESS TRUE + TIMEOUT 10 + ) + FetchContent_MakeAvailable(udp-discovery-cpp) - ## Temporary work around target_include_directories should be added upstream - include_directories(../supportlibs/udp-discovery-cpp/) + target_link_libraries(${PROJECT_NAME} PRIVATE udp-discovery-cpp) + + ## TODO: Temporary work around target_include_directories should be added + ## upstream + include_directories(${udp-discovery-cpp_SOURCE_DIR}) endif(RS_BRODCAST_DISCOVERY) if(NOT RS_WARN_DEPRECATED) @@ -223,7 +391,7 @@ if(NOT RS_WARN_DEPRECATED) target_compile_options( ${PROJECT_NAME} PRIVATE -Wno-deprecated -Wno-deprecated-declarations ) -endif(RS_WARN_DEPRECATED) +endif(NOT RS_WARN_DEPRECATED) if(RS_WARN_LESS) add_compile_definitions(RS_NO_WARN_CPP) diff --git a/libretroshare/src/CMakeLists.txt b/libretroshare/src/CMakeLists.txt index 7bfbb52b1..d3ceffecf 100644 --- a/libretroshare/src/CMakeLists.txt +++ b/libretroshare/src/CMakeLists.txt @@ -5,6 +5,49 @@ # # SPDX-License-Identifier: CC0-1.0 +list( + APPEND RS_PUBLIC_HEADERS + retroshare/rsexpr.h + retroshare/rsgxsdistsync.h + retroshare/rsiface.h + retroshare/rsrtt.h + retroshare/rsbanlist.h + retroshare/rsconfig.h + retroshare/rsdisc.h + retroshare/rsflags.h + retroshare/rsgrouter.h + retroshare/rsgxsflags.h + retroshare/rsgxsservice.h + retroshare/rsgxstrans.h + retroshare/rsgxstunnel.h + retroshare/rsids.h + retroshare/rsnotify.h + retroshare/rsphoto.h + retroshare/rsplugin.h + retroshare/rsreputations.h + retroshare/rsservicecontrol.h + retroshare/rstokenservice.h + retroshare/rsturtle.h + retroshare/rsgossipdiscovery.h + retroshare/rsgxscommon.h + retroshare/rsposted.h + retroshare/rsstatus.h + retroshare/rsversion.h + retroshare/rsgxsifacehelper.h + retroshare/rshistory.h + retroshare/rsidentity.h + retroshare/rsmsgs.h + retroshare/rsgxschannels.h + retroshare/rsgxscircles.h + retroshare/rsgxsiface.h + retroshare/rsgxsifacetypes.h + retroshare/rstypes.h + retroshare/rsgxsforums.h + retroshare/rsevents.h + retroshare/rsfiles.h + retroshare/rsinit.h + retroshare/rspeers.h ) + list( APPEND RS_SOURCES chat/distantchat.cc @@ -17,6 +60,10 @@ list( crypto/rscrypto.cpp ) if(RS_BITDHT) + list( + APPEND RS_PUBLIC_HEADERS + retroshare/rsdht.h ) + list( APPEND RS_SOURCES dht/connectstatebox.cc @@ -80,6 +127,10 @@ list( gxstunnel/p3gxstunnel.cc ) if(RS_JSON_API) + list( + APPEND RS_PUBLIC_HEADERS + retroshare/rsjsonapi.h ) + list( APPEND RS_SOURCES jsonapi/jsonapi.cpp ) @@ -151,6 +202,7 @@ list( rsitems/rsrttitems.cc rsitems/rsserviceinfoitems.cc ) +#retroshare/rswiki.h #./rsitems/rswikiitems.cc #./rsitems/rswikiitems.h #./rsitems/rswireitems.h @@ -167,6 +219,7 @@ list( #./rsitems/rsposteditems.cc #./rsitems/rsposteditems.h #./rsitems/rswireitems.cc +#retroshare/rswire.h list( APPEND RS_SOURCES @@ -243,6 +296,10 @@ list( #./services/p3posted.h if(RS_BRODCAST_DISCOVERY) + list( + APPEND RS_PUBLIC_HEADERS + retroshare/rsbroadcastdiscovery.h ) + list( APPEND RS_SOURCES services/broadcastdiscoveryservice.cc ) @@ -255,9 +312,14 @@ list( tcponudp/tou.cc tcponudp/udppeer.cc tcponudp/bss_tou.cc - tcponudp/udprelay.cc - tcponudp/udpstunner.cc ) - + tcponudp/udprelay.cc ) + +if(RS_BITDHT_STUNNER) + list( + APPEND RS_SOURCES + tcponudp/udpstunner.cc ) +endif(RS_BITDHT_STUNNER) + list( APPEND RS_SOURCES turtle/rsturtleitem.cc diff --git a/libretroshare/src/jsonapi/README.adoc b/libretroshare/src/jsonapi/README.adoc new file mode 100644 index 000000000..64284b85c --- /dev/null +++ b/libretroshare/src/jsonapi/README.adoc @@ -0,0 +1,447 @@ +// SPDX-FileCopyrightText: (C) 2004-2019 Retroshare Team +// SPDX-License-Identifier: CC0-1.0 + +RetroShare JSON API +=================== + +:Cxx: C++ + +== How to use RetroShare JSON API + +Look for methods marked with +@jsonapi+ doxygen custom command into ++libretroshare/src/retroshare+. The method path is composed by service instance +pointer name like +rsGxsChannels+ for +RsGxsChannels+, and the method name like ++createGroup+ and pass the input paramethers as a JSON object. + +.Service instance pointer in rsgxschannels.h +[source,cpp] +-------------------------------------------------------------------------------- +/** + * Pointer to global instance of RsGxsChannels service implementation + * @jsonapi{development} + */ +extern RsGxsChannels* rsGxsChannels; +-------------------------------------------------------------------------------- + +.Method declaration in rsgxschannels.h +[source,cpp] +-------------------------------------------------------------------------------- + /** + * @brief Request channel creation. + * The action is performed asyncronously, so it could fail in a subsequent + * phase even after returning true. + * @jsonapi{development} + * @param[out] token Storage for RsTokenService token to track request + * status. + * @param[in] group Channel data (name, description...) + * @return false on error, true otherwise + */ + virtual bool createGroup(uint32_t& token, RsGxsChannelGroup& group) = 0; +-------------------------------------------------------------------------------- + +.paramethers.json +[source,json] +-------------------------------------------------------------------------------- +{ + "group":{ + "mMeta":{ + "mGroupName":"JSON test group", + "mGroupFlags":4, + "mSignFlags":520 + }, + "mDescription":"JSON test group description" + }, + "caller_data":"Here can go any kind of JSON data (even objects) that the caller want to get back together with the response" +} +-------------------------------------------------------------------------------- + +.Calling the JSON API with curl on the terminal +[source,bash] +-------------------------------------------------------------------------------- +curl -u $API_USER --data @paramethers.json http://127.0.0.1:9092/rsGxsChannels/createGroup +-------------------------------------------------------------------------------- + +.JSON API call result +[source,json] +-------------------------------------------------------------------------------- +{ + "caller_data": "Here can go any kind of JSON data (even objects) that the caller want to get back together with the response", + "retval": true, + "token": 3 +} +-------------------------------------------------------------------------------- + +Even if it is less efficient because of URL encoding HTTP +GET+ method is +supported too, so in cases where the client cannot use +POST+ she can still use ++GET+ taking care of encoding the JSON data. With +curl+ this can be done at +least in two different ways. + +.Calling the JSON API with GET method with curl on the terminal +[source,bash] +-------------------------------------------------------------------------------- +curl -u $API_USER --get --data-urlencode jsonData@paramethers.json \ + http://127.0.0.1:9092/rsGxsChannels/createGroup +-------------------------------------------------------------------------------- + +Letting +curl+ do the encoding is much more elegant but it is semantically +equivalent to the following. + +.Calling the JSON API with GET method and pre-encoded data with curl on the terminal +-------------------------------------------------------------------------------- +curl -u $API_USER http://127.0.0.1:9092/rsGxsChannels/createGroup?jsonData=%7B%0A%20%20%20%20%22group%22%3A%7B%0A%20%20%20%20%20%20%20%20%22mMeta%22%3A%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%22mGroupName%22%3A%22JSON%20test%20group%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%22mGroupFlags%22%3A4%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%22mSignFlags%22%3A520%0A%20%20%20%20%20%20%20%20%7D%2C%0A%20%20%20%20%20%20%20%20%22mDescription%22%3A%22JSON%20test%20group%20description%22%0A%20%20%20%20%7D%2C%0A%20%20%20%20%22caller_data%22%3A%22Here%20can%20go%20any%20kind%20of%20JSON%20data%20%28even%20objects%29%20that%20the%20caller%20want%20to%20get%20back%20together%20with%20the%20response%22%0A%7D +-------------------------------------------------------------------------------- + +Note that using +GET+ method +?jsonData=+ and then the JSON data URL encoded are +added after the path in the HTTP request. + + +== JSON API authentication + +Most of JSON API methods require authentication as they give access to +RetroShare user data, and we don't want any application running on the system +eventually by other users be able to access private data indiscriminately. +JSON API support HTTP Basic as authentication scheme, this is enough as JSON API +server is intented for usage on the same system (127.0.0.1) not over an +untrusted network. +If you need to use JSON API over an untrusted network consider using a reverse +proxy with HTTPS such as NGINX in front of JSON API server. +If RetroShare login has been effectuated through the JSON API you can use your +location SSLID as username and your PGP password as credential for the JSON API, +but we suggests you use specific meaningful and human readable credentials for +each JSON API client so the human user can have better control over which client +can access the JSON API. + +.NewToken.json +[source,json] +-------------------------------------------------------------------------------- +{ + "token": "myNewUser:myNewPassword" +} +-------------------------------------------------------------------------------- + +.An authenticated client can authorize new tokens like this +-------------------------------------------------------------------------------- +curl -u $API_USER --data @NewToken.json http://127.0.0.1:9092/jsonApiServer/authorizeToken +-------------------------------------------------------------------------------- + +.An unauthenticated JSON API client can request access with +-------------------------------------------------------------------------------- +curl --data @NewToken.json http://127.0.0.1:9092/jsonApiServer/requestNewTokenAutorization +-------------------------------------------------------------------------------- + +When an unauthenticated client request his token to be authorized, JSON API +server will try to ask confirmation to the human user if possible through ++mNewAccessRequestCallback+, if it is not possible or the user didn't authorized +the token +false+ is returned. + + +== Offer new RetroShare services through JSON API + +To offer a retroshare service through the JSON API, first of all one need find +the global pointer to the service instance and document it in doxygen syntax, +plus marking with the custom doxygen command +@jsonapi{RS_VERSION}+ where ++RS_VERSION+ is the retroshare version in which this service became available +with the current semantic (major changes to the service semantic, changes the +meaning of the service itself, so the version should be updated in the +documentation in that case). + +.Service instance pointer in rsgxschannels.h +[source,cpp] +-------------------------------------------------------------------------------- +/** + * Pointer to global instance of RsGxsChannels service implementation + * @jsonapi{development} + */ +extern RsGxsChannels* rsGxsChannels; +-------------------------------------------------------------------------------- + + +Once the service instance itself is known to the JSON API you need to document +in doxygen syntax and mark with the custom doxygen command ++@jsonapi{RS_VERSION}+ the methods of the service that you want to make +available through JSON API. + +.Offering RsGxsChannels::getChannelDownloadDirectory in rsgxschannels.h +[source,cpp] +-------------------------------------------------------------------------------- + /** + * Get download directory for the given channel + * @jsonapi{development} + * @param[in] channelId id of the channel + * @param[out] directory reference to string where to store the path + * @return false on error, true otherwise + */ + virtual bool getChannelDownloadDirectory( const RsGxsGroupId& channelId, + std::string& directory ) = 0; +-------------------------------------------------------------------------------- + +For each paramether you must specify if it is used as input +@param[in]+ as +output +@param[out]+ or both +@param[inout]+. Paramethers and return value +types must be of a type supported by +RsTypeSerializer+ which already support +most basic types (+bool+, +std::string+...), +RsSerializable+ and containers of +them like +std::vector+. Paramethers passed by value and by +reference of those types are both supported, while passing by pointer is not +supported. If your paramether or return +class+/+struct+ type is not supported +yet by +RsTypeSerializer+ most convenient approach is to make it derive from ++RsSerializable+ and implement +serial_process+ method like I did with ++RsGxsChannelGroup+. + +.Deriving RsGxsChannelGroup from RsSerializable in rsgxschannels.h +[source,cpp] +-------------------------------------------------------------------------------- +struct RsGxsChannelGroup : RsSerializable +{ + RsGroupMetaData mMeta; + std::string mDescription; + RsGxsImage mImage; + + bool mAutoDownload; + + /// @see RsSerializable + virtual void serial_process( RsGenericSerializer::SerializeJob j, + RsGenericSerializer::SerializeContext& ctx ) + { + RS_SERIAL_PROCESS(mMeta); + RS_SERIAL_PROCESS(mDescription); + RS_SERIAL_PROCESS(mImage); + RS_SERIAL_PROCESS(mAutoDownload); + } +}; +-------------------------------------------------------------------------------- + +You can do the same recursively for any member of your +struct+ that is not yet +supported by +RsTypeSerializer+. + +Some Retroshare {Cxx} API functions are asyncronous, historically RetroShare +didn't follow a policy on how to expose asyncronous API so differents services +and some times even differents method of the same service follow differents +asyncronous patterns, thus making automatic generation of JSON API wrappers for +those methods impractical. Instead of dealing with all those differents patterns +I have chosed to support only one new pattern taking advantage of modern {Cxx}11 +and restbed features. On the {Cxx}11 side lambdas and +std::function+s are used, +on the restbed side Server Side Events are used to send asyncronous results. + +Lets see an example so it will be much esier to understand. + +.RsGxsChannels::turtleSearchRequest asyncronous API +[source,cpp] +-------------------------------------------------------------------------------- + /** + * @brief Request remote channels search + * @jsonapi{development} + * @param[in] matchString string to look for in the search + * @param multiCallback function that will be called each time a search + * result is received + * @param[in] maxWait maximum wait time in seconds for search results + * @return false on error, true otherwise + */ + virtual bool turtleSearchRequest( + const std::string& matchString, + const std::function& multiCallback, + std::time_t maxWait = 300 ) = 0; +-------------------------------------------------------------------------------- + ++RsGxsChannels::turtleSearchRequest(...)+ is an asyncronous method because it +send a channel search request on turtle network and then everytime a result is +received from the network +multiCallback+ is called and the result is passed as +parameter. To be supported by the automatic JSON API wrappers generator an +asyncronous method need a parameter of type +std::function+ called ++callback+ if the callback will be called only once or +multiCallback+ if the +callback is expected to be called more then once like in this case. +A second mandatory parameter is +maxWait+ of type +std::time_t+ it indicates the +maximum amount of time in seconds for which the caller is willing to wait for +results, in case the timeout is reached the callback will not be called anymore. + +[IMPORTANT] +================================================================================ ++callback+ and +multiCallback+ parameters documentation must *not* specify ++[in]+, +[out]+, +[inout]+, in Doxygen documentation as this would fool the +automatic wrapper generator, and ultimately break the compilation. +================================================================================ + +.RsFiles::turtleSearchRequest asyncronous JSON API usage example +[source,bash] +-------------------------------------------------------------------------------- +$ cat turtle_search.json +{ + "matchString":"linux" +} +$ curl --data @turtle_search.json http://127.0.0.1:9092/rsFiles/turtleSearchRequest +data: {"retval":true} + +data: {"results":[{"size":157631,"hash":"69709b4d01025584a8def5cd78ebbd1a3cf3fd05","name":"kill_bill_linux_1024x768.jpg"},{"size":192560,"hash":"000000000000000000009a93e5be8486c496f46c","name":"coffee_box_linux2.jpg"},{"size":455087,"hash":"9a93e5be8486c496f46c00000000000000000000","name":"Linux.png"},{"size":182004,"hash":"e8845280912ebf3779e400000000000000000000","name":"Linux_2_6.png"}]} + +data: {"results":[{"size":668,"hash":"e8845280912ebf3779e400000000000000000000","name":"linux.png"},{"size":70,"hash":"e8845280912ebf3779e400000000000000000000","name":"kali-linux-2016.2-amd64.txt.sha1sum"},{"size":3076767744,"hash":"e8845280912ebf3779e400000000000000000000","name":"kali-linux-2016.2-amd64.iso"},{"size":2780872,"hash":"e8845280912ebf3779e400000000000000000000","name":"openwrt-ar71xx-generic-vmlinux.bin"},{"size":917504,"hash":"e8845280912ebf3779e400000000000000000000","name":"openwrt-ar71xx-generic-vmlinux.lzma"},{"size":2278404096,"hash":"e8845280912ebf3779e400000000000000000000","name":"gentoo-linux-livedvd-amd64-multilib-20160704.iso"},{"size":151770333,"hash":"e8845280912ebf3779e400000000000000000000","name":"flashtool-0.9.23.0-linux.tar.7z"},{"size":2847372,"hash":"e8845280912ebf3779e400000000000000000000","name":"openwrt-ar71xx-generic-vmlinux.elf"},{"size":1310720,"hash":"e8845280912ebf3779e400000000000000000000","name":"openwrt-ar71xx-generic-vmlinux.gz"},{"size":987809,"hash":"e8845280912ebf3779e400000000000000000000","name":"openwrt-ar71xx-generic-vmlinux-lzma.elf"}]} + +-------------------------------------------------------------------------------- + +By default JSON API methods requires client authentication and their wrappers +are automatically generated by +json-api-generator+. +In some cases methods need do be accessible without authentication such as ++rsLoginHelper/getLocations+ so in the doxygen documentaion they have the custom +command +@jsonapi{RS_VERSION,unauthenticated}+. +Other methods such as +/rsControl/rsGlobalShutDown+ need special care so they +are marked with the custom doxygen command +@jsonapi{RS_VERSION,manualwrapper}+ +and their wrappers are not automatically generated but written manually into ++JsonApiServer::JsonApiServer(...)+. + +== Quirks + +=== 64 bits integers handling + +While JSON doesn't have problems representing 64 bits integers JavaScript, Dart +and other languages are not capable to handle those numbers natively. +To overcome this limitation JSON API output 64 bit integers as an object with +two keys, one as proper integer and one as string representation. + +.JSON API 64 bit integer output example +[source,json] +-------------------------------------------------------------------------------- +"lobby_id": { "xint64": 6215642878098695544, "xstr64": "6215642878098695544" } +-------------------------------------------------------------------------------- + +So from languages that have proper 64bit integers support like Python or C++ one +better read from `xint64` which is represented as a JSON integer, from languages +where there is no proper 64bit integers support like JavaScript one can read from +`xstr64` which is represented as JSON string (note that the first is not wrapped +in "" while the latter is). + +When one input a 64bit integer into the JSON API it first try to parse it as if +it was sent the old way for retrocompatibility. + +.JSON API 64 bit integer deprecated format input example +[source,json] +-------------------------------------------------------------------------------- +"lobby_id":6215642878098695544 +-------------------------------------------------------------------------------- + +This way is *DEPRECATED* and may disappear in the future, it is TEMPORALLY kept +only for retrocompatibiliy with old clients. + +If retrocompatible parsing attempt fail then it try to parse with the new way +with proper JSON integer format. + +.JSON API 64 bit integer new proper integer format input example +[source,json] +-------------------------------------------------------------------------------- +lobby_id": { "xint64": 6215642878098695544 } +-------------------------------------------------------------------------------- + +If this fails then it try to parse with the new way with JSON string format. + +.JSON API 64 bit integer new string format input example +[source,json] +-------------------------------------------------------------------------------- +"lobby_id": { "xstr64": "6215642878098695544" } +-------------------------------------------------------------------------------- + +[WARNING] +================================================================================ +Clients written in languages without proper 64bit integers support must +use *ONLY* the string format otherwise they will send approximated values and +get unexpected results from the JSON API, because parsing will success but the +value will not be exactly the one you believe you sent. +================================================================================ + + +== A bit of history + +=== First writings about this + +The previous attempt of exposing a RetroShare JSON API is called +libresapi+ and +unfortunatley it requires a bunch of boilerplate code when we want to expose +something present in the {Cxx} API in the JSON API. + +As an example here you can see the libresapi that exposes part of the retroshare +chat {Cxx} API and lot of boilerplate code just to convert {Cxx} objects to JSON + +https://github.com/RetroShare/RetroShare/blob/v0.6.4/libresapi/src/api/ChatHandler.cpp#L44 + +To avoid the {Cxx} to JSON and back conversion boilerplate code I have worked out +an extension to our {Cxx} serialization code so it is capable to serialize and +deserialize to JSON you can see it in this pull request + +https://github.com/RetroShare/RetroShare/pull/1155 + +So first step toward having a good API is to take advantage of the fact that RS +is now capable of converting C++ objects from and to JSON. + +The current API is accessible via HTTP and unix socket, there is no +authentication in both of them, so anyone having access to the HTTP server or to +the unix socket can access the API without extra restrictions. +Expecially for the HTTP API this is a big risk because also if the http server +listen on 127.0.0.1 every application on the machine (even rogue javascript +running on your web browser) can access that and for example on android it is +not safe at all (because of that I implemented the unix socket access so at +least in android API was reasonably safe) because of this. + +A second step to improve the API would be to implement some kind of API +authentication mechanism (it would be nice that the mechanism is handled at API +level and not at transport level so we can use it for any API trasport not just +HTTP for example) + +The HTTP server used by libresapi is libmicrohttpd server that is very minimal, +it doesn't provide HTTPS nor modern HTTP goodies, like server notifications, +websockets etc. because the lack of support we have a token polling mechanism in +libresapi to avoid polling for every thing but it is still ugly, so if we can +completely get rid of polling in the API that would be really nice. +I have done a crawl to look for a replacement and briefly looked at + +- https://www.gnu.org/software/libmicrohttpd/ +- http://wolkykim.github.io/libasyncd/ +- https://github.com/corvusoft/restbed +- https://code.facebook.com/posts/1503205539947302/introducing-proxygen-facebook-s-c-http-framework/ +- https://github.com/cmouse/yahttp + +taking in account a few metrics like modern HTTP goodies support, license, +platform support, external dependencies and documentation it seemed to me that +restbed is the more appropriate. + +Another source of boilerplate code into libresapi is the mapping between JSON +API requests and C++ API methods as an example you can look at this + +https://github.com/RetroShare/RetroShare/blob/v0.6.4/libresapi/src/api/ChatHandler.cpp#L158 + +and this + +https://github.com/RetroShare/RetroShare/blob/v0.6.4/libresapi/src/api/ApiServer.cpp#L253 + +The abstract logic of this thing is, when libreasapi get a request like ++/chat/initiate_distant_chat+ then call ++ChatHandler::handleInitiateDistantChatConnexion+ which in turn is just a +wrapper of +RsMsgs::initiateDistantChatConnexion+ all this process is basically +implemented as boilerplate code and would be unnecessary in a smarter design of +the API because almost all the information needed is already present in the +C++ API +libretroshare/src/retroshare+. + +So a third step to improve the JSON API would be to remove this source of +boilerplate code by automatizing the mapping between C++ and JSON API call. + +This may result a little tricky as language parsing or other adevanced things +may be required. + +Hope this dive is useful for you + +Cheers + +G10h4ck + +=== Second writings about this + +I have been investigating a bit more about: +[verse, G10h4ck] +________________________________________________________________________________ +So a third step to improve the JSON API would be to remove this source of +boilerplate code by automatizing the mapping between C++ and JSON API call +________________________________________________________________________________ + +After spending some hours investigating this topic the most reasonable approach +seems to: + +1. Properly document headers in +libretroshare/src/retroshare/+ in doxygen syntax +specifying wihich params are input and/or output (doxygen sysntax for this is ++@param[in/out/inout]+) this will be the API documentation too. + +2. At compile time use doxygen to generate XML description of the headers and use +the XML to generate the JSON api server stub. +http://www.stack.nl/~dimitri/doxygen/manual/customize.html#xmlgenerator + +3. Enjoy diff --git a/libretroshare/src/jsonapi/async-method-wrapper-template.cpp.tmpl b/libretroshare/src/jsonapi/async-method-wrapper-template.cpp.tmpl new file mode 100644 index 000000000..29f53ad48 --- /dev/null +++ b/libretroshare/src/jsonapi/async-method-wrapper-template.cpp.tmpl @@ -0,0 +1,80 @@ +/******************************************************************************* + * RetroShare JSON API * + * * + * Copyright (C) 2018-2019 Gioacchino Mazzurco * + * * + * This program is free software: you can redistribute it and/or modify * + * it under the terms of the GNU Affero General Public License version 3 as * + * published by the Free Software Foundation. * + * * + * 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 Affero General Public License for more details. * + * * + * You should have received a copy of the GNU Affero General Public License * + * along with this program. If not, see . * + * * + *******************************************************************************/ + +registerHandler( "$%apiPath%$", + [this](const std::shared_ptr session) +{ + const std::multimap headers + { + { "Connection", "keep-alive" }, + { "Content-Type", "text/event-stream" } + }; + session->yield(rb::OK, headers); + + size_t reqSize = session->get_request()->get_header("Content-Length", 0); + session->fetch( reqSize, [this]( + const std::shared_ptr session, + const rb::Bytes& body ) + { + INITIALIZE_API_CALL_JSON_CONTEXT; + + if( !checkRsServicePtrReady( + $%instanceName%$, "$%instanceName%$", cAns, session ) ) + return; + +$%paramsDeclaration%$ + +$%inputParamsDeserialization%$ + + const std::weak_ptr weakService(mService); + const std::weak_ptr weakSession(session); + $%callbackName%$ = [weakService, weakSession]($%callbackParams%$) + { + auto session = weakSession.lock(); + if(!session || session->is_closed()) return; + + auto lService = weakService.lock(); + if(!lService || lService->is_down()) return; + +$%callbackParamsSerialization%$ + + std::stringstream sStream; + sStream << "data: " << compactJSON << ctx.mJson << "\n\n"; + const std::string message = sStream.str(); + + lService->schedule( [weakSession, message]() + { + auto session = weakSession.lock(); + if(!session || session->is_closed()) return; + session->yield(message); + $%sessionEarlyClose%$ + } ); + }; + +$%functionCall%$ + +$%outputParamsSerialization%$ + + // return them to the API caller + std::stringstream message; + message << "data: " << compactJSON << cAns.mJson << "\n\n"; + session->yield(message.str()); + $%sessionDelayedClose%$ + } ); +}, $%requiresAuth%$ ); diff --git a/libretroshare/src/jsonapi/jsonapi-generator-doxygen.conf b/libretroshare/src/jsonapi/jsonapi-generator-doxygen.conf new file mode 100644 index 000000000..0edd1de3e --- /dev/null +++ b/libretroshare/src/jsonapi/jsonapi-generator-doxygen.conf @@ -0,0 +1,230 @@ +DOXYFILE_ENCODING = UTF-8 +PROJECT_NAME = "libretroshare" + +ALIASES += jsonapi{1}="\xmlonly\endxmlonly" +ALIASES += jsonapi{2}="\xmlonly\endxmlonly" + +# If the INHERIT_DOCS tag is set to YES then an undocumented member inherits the +# documentation from any documented member that it re-implements. +# The default value is: YES. + +INHERIT_DOCS = YES + +# If the MARKDOWN_SUPPORT tag is enabled then doxygen pre-processes all comments +# according to the Markdown format, which allows for more readable +# documentation. See http://daringfireball.net/projects/markdown/ for details. +# The output of markdown processing is further processed by doxygen, so you can +# mix doxygen, HTML, and XML commands with Markdown formatting. Disable only in +# case of backward compatibilities issues. +# The default value is: YES. + +MARKDOWN_SUPPORT = YES + +# When enabled doxygen tries to link words that correspond to documented +# classes, or namespaces to their corresponding documentation. Such a link can +# be prevented in individual cases by putting a % sign in front of the word or +# globally by setting AUTOLINK_SUPPORT to NO. +# The default value is: YES. + +AUTOLINK_SUPPORT = YES + + +# If the EXTRACT_ALL tag is set to YES, doxygen will assume all entities in +# documentation are documented, even if no documentation was available. Private +# class members and static file members will be hidden unless the +# EXTRACT_PRIVATE respectively EXTRACT_STATIC tags are set to YES. +# Note: This will also disable the warnings about undocumented members that are +# normally produced when WARNINGS is set to YES. +# The default value is: NO. + +EXTRACT_ALL = YES + + +# If the HIDE_UNDOC_MEMBERS tag is set to YES, doxygen will hide all +# undocumented members inside documented classes or files. If set to NO these +# members will be included in the various overviews, but no documentation +# section is generated. This option has no effect if EXTRACT_ALL is enabled. +# The default value is: NO. + +HIDE_UNDOC_MEMBERS = NO + +# If the HIDE_UNDOC_CLASSES tag is set to YES, doxygen will hide all +# undocumented classes that are normally visible in the class hierarchy. If set +# to NO, these classes will be included in the various overviews. This option +# has no effect if EXTRACT_ALL is enabled. +# The default value is: NO. + +HIDE_UNDOC_CLASSES = NO + + +#--------------------------------------------------------------------------- +# Configuration options related to the input files +#--------------------------------------------------------------------------- + +# The INPUT tag is used to specify the files and/or directories that contain +# documented source files. You may enter file names like myfile.cpp or +# directories like /usr/src/myproject. Separate the files or directories with +# spaces. See also FILE_PATTERNS and EXTENSION_MAPPING +# Note: If this tag is empty the current directory is searched. + +#INPUT = + +# This tag can be used to specify the character encoding of the source files +# that doxygen parses. Internally doxygen uses the UTF-8 encoding. Doxygen uses +# libiconv (or the iconv built into libc) for the transcoding. See the libiconv +# documentation (see: https://www.gnu.org/software/libiconv/) for the list of +# possible encodings. +# The default value is: UTF-8. + +INPUT_ENCODING = UTF-8 + +# If the value of the INPUT tag contains directories, you can use the +# FILE_PATTERNS tag to specify one or more wildcard patterns (like *.cpp and +# *.h) to filter out the source-files in the directories. +# +# Note that for custom extensions or not directly supported extensions you also +# need to set EXTENSION_MAPPING for the extension otherwise the files are not +# read by doxygen. +# +# If left blank the following patterns are tested:*.c, *.cc, *.cxx, *.cpp, +# *.c++, *.java, *.ii, *.ixx, *.ipp, *.i++, *.inl, *.idl, *.ddl, *.odl, *.h, +# *.hh, *.hxx, *.hpp, *.h++, *.cs, *.d, *.php, *.php4, *.php5, *.phtml, *.inc, +# *.m, *.markdown, *.md, *.mm, *.dox, *.py, *.pyw, *.f90, *.f95, *.f03, *.f08, +# *.f, *.for, *.tcl, *.vhd, *.vhdl, *.ucf and *.qsf. + +FILE_PATTERNS = *.c \ + *.cc \ + *.cxx \ + *.cpp \ + *.c++ \ + *.java \ + *.ii \ + *.ixx \ + *.ipp \ + *.i++ \ + *.inl \ + *.idl \ + *.ddl \ + *.odl \ + *.h \ + *.hh \ + *.hxx \ + *.hpp \ + *.h++ \ + *.cs \ + *.d \ + *.php \ + *.php4 \ + *.php5 \ + *.phtml \ + *.inc \ + *.m \ + *.markdown \ + *.md \ + *.mm \ + *.dox \ + *.py \ + *.pyw \ + *.f90 \ + *.f95 \ + *.f03 \ + *.f08 \ + *.f \ + *.for \ + *.tcl \ + *.vhd \ + *.vhdl \ + *.ucf \ + *.qsf + +# The RECURSIVE tag can be used to specify whether or not subdirectories should +# be searched for input files as well. +# The default value is: NO. + +RECURSIVE = YES + +# The EXCLUDE tag can be used to specify files and/or directories that should be +# excluded from the INPUT source files. This way you can easily exclude a +# subdirectory from a directory tree whose root is specified with the INPUT tag. +# +# Note that relative paths are relative to the directory from which doxygen is +# run. + +EXCLUDE = + +# The EXCLUDE_SYMLINKS tag can be used to select whether or not files or +# directories that are symbolic links (a Unix file system feature) are excluded +# from the input. +# The default value is: NO. + +EXCLUDE_SYMLINKS = NO + +# If the value of the INPUT tag contains directories, you can use the +# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude +# certain files from those directories. +# +# Note that the wildcards are matched against the file with absolute path, so to +# exclude all test directories for example use the pattern */test/* + +EXCLUDE_PATTERNS = + +# The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names +# (namespaces, classes, functions, etc.) that should be excluded from the +# output. The symbol name can be a fully qualified name, a word, or if the +# wildcard * is used, a substring. Examples: ANamespace, AClass, +# AClass::ANamespace, ANamespace::*Test +# +# Note that the wildcards are matched against the file with absolute path, so to +# exclude all test directories use the pattern */test/* + +EXCLUDE_SYMBOLS = + + +#--------------------------------------------------------------------------- +# Configuration options related to the HTML output +#--------------------------------------------------------------------------- + +# If the GENERATE_HTML tag is set to YES, doxygen will generate HTML output +# The default value is: YES. + +GENERATE_HTML = NO + +# If the GENERATE_LATEX tag is set to YES, doxygen will generate LaTeX output. +# The default value is: YES. + +GENERATE_LATEX = NO + +# If the GENERATE_XML tag is set to YES, doxygen will generate an XML file that +# captures the structure of the code including all documentation. +# The default value is: NO. + +GENERATE_XML = YES + + +#--------------------------------------------------------------------------- +# Configuration options related to the preprocessor +#--------------------------------------------------------------------------- + +# If the ENABLE_PREPROCESSING tag is set to YES, doxygen will evaluate all +# C-preprocessor directives found in the sources and include files. +# The default value is: YES. + +ENABLE_PREPROCESSING = YES + +# If the MACRO_EXPANSION tag is set to YES, doxygen will expand all macro names +# in the source code. If set to NO, only conditional compilation will be +# performed. Macro expansion can be done in a controlled way by setting +# EXPAND_ONLY_PREDEF to YES. +# The default value is: NO. +# This tag requires that the tag ENABLE_PREPROCESSING is set to YES. + +MACRO_EXPANSION = NO + +# If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES then +# the macro expansion is limited to the macros specified with the PREDEFINED and +# EXPAND_AS_DEFINED tags. +# The default value is: NO. +# This tag requires that the tag ENABLE_PREPROCESSING is set to YES. + +EXPAND_ONLY_PREDEF = NO + diff --git a/libretroshare/src/jsonapi/jsonapi-generator.py b/libretroshare/src/jsonapi/jsonapi-generator.py new file mode 100755 index 000000000..accf9a0cd --- /dev/null +++ b/libretroshare/src/jsonapi/jsonapi-generator.py @@ -0,0 +1,365 @@ +#!/usr/bin/python3 + +# RetroShare JSON API generator +# +# Copyright (C) 2019 selankon +# Copyright (C) 2021 Gioacchino Mazzurco +# Copyright (C) 2021 Asociación Civil Altermundi +# +# This program is free software: you can redistribute it and/or modify it under +# the terms of the GNU Affero General Public License as published by the +# Free Software Foundation, version 3. +# +# 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 Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License along +# with this program. If not, see +# +# SPDX-FileCopyrightText: Retroshare Team +# SPDX-License-Identifier: AGPL-3.0-only + + +# Original idea and implementation by G10h4ck (jsonapi-generator.cpp) +# Initial python reimplementation by Sehraf +# +# This python 3 script has superseded the original C++/Qt implementation this +# and is now used at build time in without depending on Qt. + +import os +import sys + +import xml.etree.ElementTree as ET +from string import Template + + +class MethodParam: + _type = '' + _name = '' + _defval = '' + _in = False + _out = False + _isMultiCallback = False + _isSingleCallback = False + + +class TemplateOwn(Template): + delimiter = '$%' + pattern = ''' + \$%(?: + (?P\$\%) | # Escape sequence of two delimiters + (?P[_a-z][_a-z0-9]*)%\$ | # delimiter and a Python identifier + {(?P[_a-z][_a-z0-9]*)} | # delimiter and a braced identifier + (?P) # Other ill-formed delimiter exprs + ) + ''' + + +def getText(e): + return "".join(e.itertext()) + + +def processFile(file): + try: + dom1 = ET.parse(file).getroot() + except FileNotFoundError: + print('Can\'t open:', file) + + headerFileInfo = dom1[0].findall('location')[0].attrib['file'] + headerRelPath = os.path.dirname(headerFileInfo).split('/')[-1] + '/' + os.path.basename(headerFileInfo) + + for sectDef in dom1.findall('.//memberdef'): + if sectDef.attrib['kind'] != 'variable' or sectDef.find('.//jsonapi') == None: + continue + + instanceName = sectDef.find('name').text + typeName = sectDef.find('type/ref').text + + typeFilePath = sectDef.find('type/ref').attrib['refid'] + + try: + dom2 = ET.parse(doxPrefix + typeFilePath + '.xml').getroot() + except FileNotFoundError: + print('Can\'t open:', doxPrefix + typeFilePath + '.xml') + + for member in dom2.findall('.//member'): + refid = member.attrib['refid'] + methodName = member.find('name').text + + requiresAuth = True + + defFilePath = refid.split('_')[0] + '.xml' + defFile = defFilePath + + print('Looking for', typeName, methodName, 'into', typeFilePath) + + try: + defDoc = ET.parse(doxPrefix + defFilePath).getroot() + except FileNotFoundError: + print('Can\'t open:', doxPrefix + defFilePath) + + memberdef = None + for tmpMBD in defDoc.findall('.//memberdef'): + tmpId = tmpMBD.attrib['id'] + tmpKind = tmpMBD.attrib['kind'] + tmpJsonApiTagList = tmpMBD.findall('.//jsonapi') + + if len(tmpJsonApiTagList) != 0 and tmpId == refid and tmpKind == 'function': + tmpJsonApiTag = tmpJsonApiTagList[0] + + tmpAccessValue = None + if 'access' in tmpJsonApiTag.attrib: + tmpAccessValue = tmpJsonApiTag.attrib['access'] + + requiresAuth = 'unauthenticated' != tmpAccessValue; + + if 'manualwrapper' != tmpAccessValue: + memberdef = tmpMBD + + break + + if memberdef == None: + continue + + apiPath = '/' + instanceName + '/' + methodName + + retvalType = getText(memberdef.find('type')) + # Apparently some xml declarations include new lines ('\n') and/or multiple spaces + # Strip them using python magic + retvalType = ' '.join(retvalType.split()) + + paramsMap = {} + orderedParamNames = [] + + hasInput = False + hasOutput = False + hasSingleCallback = False + hasMultiCallback = False + callbackName = '' + callbackParams = '' + + for tmpPE in memberdef.findall('param'): + mp = MethodParam() + + pName = getText(tmpPE.find('declname')) + tmpDefval = tmpPE.find('defval') + mp._defval = getText(tmpDefval) if tmpDefval != None else '' + pType = getText(tmpPE.find('type')) + + if pType.startswith('const '): pType = pType[6:] + if pType.startswith('std::function'): + if pType.endswith('&'): pType = pType[:-1] + if pName.startswith('multiCallback'): + mp._isMultiCallback = True + hasMultiCallback = True + elif pName.startswith('callback'): + mp._isSingleCallback = True + hasSingleCallback = True + callbackName = pName + callbackParams = pType + else: + pType = pType.replace('&', '').replace(' ', '') + + # Apparently some xml declarations include new lines ('\n') and/or multiple spaces + # Strip them using python magic + pType = ' '.join(pType.split()) + mp._defval = ' '.join(mp._defval.split()) + + mp._type = pType + mp._name = pName + + paramsMap[pName] = mp + orderedParamNames.append(pName) + + for tmpPN in memberdef.findall('.//parametername'): + tmpParam = paramsMap[tmpPN.text] + tmpD = tmpPN.attrib['direction'] if 'direction' in tmpPN.attrib else '' + + if 'in' in tmpD: + tmpParam._in = True + hasInput = True + if 'out' in tmpD: + tmpParam._out = True + hasOutput = True + + # Params sanity check + for pmKey in paramsMap: + pm = paramsMap[pmKey] + if not (pm._isMultiCallback or pm._isSingleCallback or pm._in or pm._out): + print('ERROR', 'Parameter:', pm._name, 'of:', apiPath, + 'declared in:', headerRelPath, + 'miss doxygen parameter direction attribute!', + defFile) + sys.exit() + + functionCall = '\t\t' + if retvalType != 'void': + functionCall += retvalType + ' retval = ' + hasOutput = True + functionCall += instanceName + '->' + methodName + '(' + functionCall += ', '.join(orderedParamNames) + ');\n' + + print(instanceName, apiPath, retvalType, typeName, methodName) + for pn in orderedParamNames: + mp = paramsMap[pn] + print('\t', mp._type, mp._name, mp._in, mp._out) + + inputParamsDeserialization = '' + if hasInput: + inputParamsDeserialization += '\t\t{\n' + inputParamsDeserialization += '\t\t\tRsGenericSerializer::SerializeContext& ctx(cReq);\n' + inputParamsDeserialization += '\t\t\tRsGenericSerializer::SerializeJob j(RsGenericSerializer::FROM_JSON);\n'; + + outputParamsSerialization = '' + if hasOutput: + outputParamsSerialization += '\t\t{\n' + outputParamsSerialization += '\t\t\tRsGenericSerializer::SerializeContext& ctx(cAns);\n' + outputParamsSerialization += '\t\t\tRsGenericSerializer::SerializeJob j(RsGenericSerializer::TO_JSON);\n'; + + paramsDeclaration = '' + for pn in orderedParamNames: + mp = paramsMap[pn] + paramsDeclaration += '\t\t' + mp._type + ' ' + mp._name + if mp._defval != '': + paramsDeclaration += ' = ' + mp._defval + paramsDeclaration += ';\n' + if mp._in: + inputParamsDeserialization += '\t\t\tRS_SERIAL_PROCESS(' + inputParamsDeserialization += mp._name + ');\n' + if mp._out: + outputParamsSerialization += '\t\t\tRS_SERIAL_PROCESS(' + outputParamsSerialization += mp._name + ');\n' + + if hasInput: + inputParamsDeserialization += '\t\t}\n' + if retvalType != 'void': + outputParamsSerialization += '\t\t\tRS_SERIAL_PROCESS(retval);\n' + if hasOutput: + outputParamsSerialization += '\t\t}\n' + + captureVars = '' + + sessionEarlyClose = '' + if hasSingleCallback: + sessionEarlyClose = 'session->close();' + + sessionDelayedClose = '' + if hasMultiCallback: + sessionDelayedClose = """ + RsThread::async( [=]() + { + std::this_thread::sleep_for( + std::chrono::seconds(maxWait+120) ); + auto lService = weakService.lock(); + if(!lService || lService->is_down()) return; + lService->schedule( [=]() + { + auto session = weakSession.lock(); + if(session && session->is_open()) + session->close(); + } ); + } ); +""" + captureVars = 'this' + + callbackParamsSerialization = '' + + if hasSingleCallback or hasMultiCallback or (callbackParams.find('(') + 2 < callbackParams.find(')')): + cbs = '' + + callbackParams = callbackParams.split('(')[1] + callbackParams = callbackParams.split(')')[0] + + cbs += '\t\t\tRsGenericSerializer::SerializeContext ctx;\n' + + for cbPar in callbackParams.split(','): + isConst = cbPar.startswith('const ') + pSep = ' ' + isRef = '&' in cbPar + if isRef: pSep = '&' + sepIndex = cbPar.rfind(pSep) + 1 + cpt = cbPar[0:sepIndex][6:] + cpn = cbPar[sepIndex:] + + cbs += '\t\t\tRsTypeSerializer::serial_process(' + cbs += 'RsGenericSerializer::TO_JSON, ctx, ' + if isConst: + cbs += 'const_cast<' + cbs += cpt + cbs += '>(' + cbs += cpn + if isConst: cbs += ')' + cbs += ', "' + cbs += cpn + cbs += '" );\n' + + callbackParamsSerialization += cbs + + substitutionsMap = dict() + substitutionsMap['paramsDeclaration'] = paramsDeclaration + substitutionsMap['inputParamsDeserialization'] = inputParamsDeserialization + substitutionsMap['outputParamsSerialization'] = outputParamsSerialization + substitutionsMap['instanceName'] = instanceName + substitutionsMap['functionCall'] = functionCall + substitutionsMap['apiPath'] = apiPath + substitutionsMap['sessionEarlyClose'] = sessionEarlyClose + substitutionsMap['sessionDelayedClose'] = sessionDelayedClose + substitutionsMap['captureVars'] = captureVars + substitutionsMap['callbackName'] = callbackName + substitutionsMap['callbackParams'] = callbackParams + substitutionsMap['callbackParamsSerialization'] = callbackParamsSerialization + substitutionsMap['requiresAuth'] = 'true' if requiresAuth else 'false' + + # print(substitutionsMap) + + templFilePath = sourcePath + if hasMultiCallback or hasSingleCallback: + templFilePath += '/async-method-wrapper-template.cpp.tmpl' + else: + templFilePath += '/method-wrapper-template.cpp.tmpl' + + templFile = open(templFilePath, 'r') + wrapperDef = TemplateOwn(templFile.read()) + + tmp = wrapperDef.substitute(substitutionsMap) + wrappersDefFile.write(tmp) + + cppApiIncludesSet.add('#include "' + headerRelPath + '"\n') + + +if len(sys.argv) != 3: + print('Usage:', sys.argv[0], 'SOURCE_PATH OUTPUT_PATH Got:', sys.argv[:]) + sys.exit(-1) + +sourcePath = str(sys.argv[1]) +outputPath = str(sys.argv[2]) +doxPrefix = outputPath + '/xml/' + +try: + wrappersDefFile = open(outputPath + '/jsonapi-wrappers.inl', 'w') +except FileNotFoundError: + print('Can\'t open:', outputPath + '/jsonapi-wrappers.inl') + +try: + cppApiIncludesFile = open(outputPath + '/jsonapi-includes.inl', 'w'); +except FileNotFoundError: + print('Can\'t open:', outputPath + '/jsonapi-includes.inl') + +cppApiIncludesSet = set() + +filesIterator = None +try: + filesIterator = os.listdir(doxPrefix) +except FileNotFoundError: + print("Doxygen xml output dir not found: ", doxPrefix) + os.exit(-1) + +for file in filesIterator: + if file.endswith("8h.xml"): + processFile(os.path.join(doxPrefix, file)) + + +for incl in cppApiIncludesSet: + cppApiIncludesFile.write(incl) diff --git a/libretroshare/src/jsonapi/method-wrapper-template.cpp.tmpl b/libretroshare/src/jsonapi/method-wrapper-template.cpp.tmpl new file mode 100644 index 000000000..a3927fba9 --- /dev/null +++ b/libretroshare/src/jsonapi/method-wrapper-template.cpp.tmpl @@ -0,0 +1,50 @@ +/******************************************************************************* + * RetroShare JSON API * + * * + * Copyright (C) 2018-2019 Gioacchino Mazzurco * + * * + * This program is free software: you can redistribute it and/or modify * + * it under the terms of the GNU Affero 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 Affero General Public License for more details. * + * * + * You should have received a copy of the GNU Affero General Public License * + * along with this program. If not, see . * + * * + *******************************************************************************/ + +registerHandler( "$%apiPath%$", + [](const std::shared_ptr session) +{ + size_t reqSize = session->get_request()->get_header("Content-Length", 0); + session->fetch( reqSize, []( + const std::shared_ptr session, + const rb::Bytes& body ) + { + INITIALIZE_API_CALL_JSON_CONTEXT; + + if( !checkRsServicePtrReady( + $%instanceName%$, "$%instanceName%$", cAns, session ) ) + return; + +$%paramsDeclaration%$ + + // deserialize input parameters from JSON +$%inputParamsDeserialization%$ + + // call retroshare C++ API +$%functionCall%$ + + // serialize out parameters and return value to JSON +$%outputParamsSerialization%$ + + // return them to the API caller + DEFAULT_API_CALL_JSON_RETURN(rb::OK); + } ); +}, $%requiresAuth%$ ); + From 24e862ae25ef2063de35a180f019f5908bf3cc55 Mon Sep 17 00:00:00 2001 From: csoler Date: Mon, 13 Dec 2021 20:28:07 +0100 Subject: [PATCH 066/113] 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 7455013fc274ef45677809e0cfedcf1188f8be64 Mon Sep 17 00:00:00 2001 From: csoler Date: Mon, 13 Dec 2021 20:58:53 +0100 Subject: [PATCH 067/113] fixed std::cerr => RsErr() --- libretroshare/src/pgp/openpgpsdkhandler.cc | 190 ++++++++++----------- libretroshare/src/pgp/pgphandler.cc | 64 +++---- 2 files changed, 127 insertions(+), 127 deletions(-) diff --git a/libretroshare/src/pgp/openpgpsdkhandler.cc b/libretroshare/src/pgp/openpgpsdkhandler.cc index 316b428af..5a4a02d49 100644 --- a/libretroshare/src/pgp/openpgpsdkhandler.cc +++ b/libretroshare/src/pgp/openpgpsdkhandler.cc @@ -142,7 +142,7 @@ OpenPGPSDKHandler::OpenPGPSDKHandler(const std::string& pubring, const std::stri throw std::runtime_error("OpenPGPSDKHandler::readKeyRing(): cannot read pubring. File corrupted.") ; } else - std::cerr << "pubring file \"" << pubring << "\" not found. Creating a void keyring." << std::endl; + RsErr() << "pubring file \"" << pubring << "\" not found. Creating a void keyring." ; const ops_keydata_t *keydata ; int i=0 ; @@ -161,7 +161,7 @@ OpenPGPSDKHandler::OpenPGPSDKHandler(const std::string& pubring, const std::stri ++i ; } _pubring_last_update_time = time(NULL) ; - std::cerr << "Pubring read successfully." << std::endl; + RsErr() << "Pubring read successfully." ; if(secring_exist) { @@ -169,7 +169,7 @@ OpenPGPSDKHandler::OpenPGPSDKHandler(const std::string& pubring, const std::stri throw std::runtime_error("OpenPGPSDKHandler::readKeyRing(): cannot read secring. File corrupted.") ; } else - std::cerr << "secring file \"" << secring << "\" not found. Creating a void keyring." << std::endl; + RsErr() << "secring file \"" << secring << "\" not found. Creating a void keyring." ; i=0 ; while( (keydata = ops_keyring_get_key_by_index(_secring,i)) != NULL ) @@ -179,7 +179,7 @@ OpenPGPSDKHandler::OpenPGPSDKHandler(const std::string& pubring, const std::stri } _secring_last_update_time = time(NULL) ; - std::cerr << "Secring read successfully." << std::endl; + RsErr() << "Secring read successfully." ; locked_readPrivateTrustDatabase() ; _trustdb_last_update_time = time(NULL) ; @@ -255,7 +255,7 @@ bool OpenPGPSDKHandler::validateAndUpdateSignatures(PGPCertificateInfo& cert,con static ops_boolean_t already = 0 ; if(!already) { - std::cerr << "(WW) Error in OpenPGPSDKHandler::validateAndUpdateSignatures(). Validation failed for at least some signatures." << std::endl; + RsErr() << "(WW) Error in OpenPGPSDKHandler::validateAndUpdateSignatures(). Validation failed for at least some signatures." ; already = 1 ; } } @@ -286,7 +286,7 @@ OpenPGPSDKHandler::~OpenPGPSDKHandler() { RsStackMutex mtx(pgphandlerMtx) ; // lock access to PGP memory structures. #ifdef DEBUG_PGPHANDLER - std::cerr << "Freeing OpenPGPSDKHandler. Deleting keyrings." << std::endl; + RsErr() << "Freeing OpenPGPSDKHandler. Deleting keyrings." ; #endif // no need to free the the _map_ elements. They will be freed by the following calls: @@ -300,7 +300,7 @@ OpenPGPSDKHandler::~OpenPGPSDKHandler() void OpenPGPSDKHandler::printOPSKeys() const { - std::cerr << "Public keyring list from OPS:" << std::endl; + RsErr() << "Public keyring list from OPS:" ; ops_keyring_list(_pubring) ; } @@ -331,7 +331,7 @@ bool OpenPGPSDKHandler::availableGPGCertificatesWithPrivateKeys(std::listkey_id)) ; #ifdef DEBUG_PGPHANDLER else - std::cerr << "Skipping keypair " << RsPgpId(keydata->key_id).toStdString() << ", unsupported algorithm: " << keydata->key.pkey.algorithm << std::endl; + RsErr() << "Skipping keypair " << RsPgpId(keydata->key_id).toStdString() << ", unsupported algorithm: " << keydata->key.pkey.algorithm ; #endif } @@ -416,7 +416,7 @@ bool OpenPGPSDKHandler::GeneratePGPCertificate(const std::string& name, const st initCertificateInfo(_secret_keyring_map[ pgpId ],&tmp_secring->keys[0],_secring->nkeys-1) ; #ifdef DEBUG_PGPHANDLER - std::cerr << "Added new secret key with id " << pgpId.toStdString() << " to secret keyring." << std::endl; + RsErr() << "Added new secret key with id " << pgpId.toStdString() << " to secret keyring." ; #endif ops_keyring_free(tmp_secring) ; free(tmp_secring) ; @@ -479,7 +479,7 @@ bool OpenPGPSDKHandler::GeneratePGPCertificate(const std::string& name, const st locked_syncPublicKeyring() ; #ifdef DEBUG_PGPHANDLER - std::cerr << "Added new public key with id " << pgpId.toStdString() << " to public keyring." << std::endl; + RsErr() << "Added new public key with id " << pgpId.toStdString() << " to public keyring." ; #endif // 9 - Update some flags. @@ -509,7 +509,7 @@ std::string OpenPGPSDKHandler::makeRadixEncodedPGPKey(const ops_keydata_t *key,b else { ops_create_info_delete(cinfo); - std::cerr << "Unhandled key type " << key->type << std::endl; + RsErr() << "Unhandled key type " << key->type ; return "ERROR: Cannot write key. Unhandled key type. " ; } @@ -569,7 +569,7 @@ std::string OpenPGPSDKHandler::SaveCertificateToString(const RsPgpId& id,bool in if(key == NULL) { - std::cerr << "Cannot output key " << id.toStdString() << ": not found in keyring." << std::endl; + RsErr() << "Cannot output key " << id.toStdString() << ": not found in keyring." ; return "" ; } @@ -584,7 +584,7 @@ bool OpenPGPSDKHandler::exportPublicKey( const RsPgpId& id, unsigned char*& mem_ { RsErr() << __PRETTY_FUNCTION__ << " should not be used with " << "armoured=true, because there's a bug in the armoured export" - << " of OPS" << std::endl; + << " of OPS" ; print_stacktrace(); return false; } @@ -595,7 +595,7 @@ bool OpenPGPSDKHandler::exportPublicKey( const RsPgpId& id, unsigned char*& mem_ if(!key) { RsErr() << __PRETTY_FUNCTION__ << " key id: " << id - << " not found in keyring." << std::endl; + << " not found in keyring." ; return false; } @@ -608,7 +608,7 @@ bool OpenPGPSDKHandler::exportPublicKey( const RsPgpId& id, unsigned char*& mem_ { RsErr() << __PRETTY_FUNCTION__ << " This key id " << id << " cannot be processed by RetroShare because DSA certificates" - << " support is not implemented yet." << std::endl; + << " support is not implemented yet." ; return false; } @@ -638,21 +638,21 @@ bool OpenPGPSDKHandler::exportGPGKeyPair(const std::string& filename,const RsPgp if(pubkey == NULL) { - std::cerr << "Cannot output key " << exported_key_id.toStdString() << ": not found in public keyring." << std::endl; + RsErr() << "Cannot output key " << exported_key_id.toStdString() << ": not found in public keyring." ; return false ; } const ops_keydata_t *seckey = locked_getSecretKey(exported_key_id) ; if(seckey == NULL) { - std::cerr << "Cannot output key " << exported_key_id.toStdString() << ": not found in secret keyring." << std::endl; + RsErr() << "Cannot output key " << exported_key_id.toStdString() << ": not found in secret keyring." ; return false ; } FILE *f = RsDirUtil::rs_fopen(filename.c_str(),"w") ; if(f == NULL) { - std::cerr << "Cannot output key " << exported_key_id.toStdString() << ": file " << filename << " cannot be written. Please check for permissions, quotas, disk space." << std::endl; + RsErr() << "Cannot output key " << exported_key_id.toStdString() << ": file " << filename << " cannot be written. Please check for permissions, quotas, disk space." ; return false ; } @@ -704,7 +704,7 @@ bool OpenPGPSDKHandler::getGPGDetailsFromBinaryBlock(const unsigned char *mem_bl ops_memory_release(mem) ; free(mem) ; - std::cerr << "Could not read key. Format error?" << std::endl; + RsErr() << "Could not read key. Format error?" ; //error_string = std::string("Could not read key. Format error?") ; return false ; } @@ -714,12 +714,12 @@ bool OpenPGPSDKHandler::getGPGDetailsFromBinaryBlock(const unsigned char *mem_bl if(tmp_keyring->nkeys != 1) { - std::cerr << "No or incomplete/invalid key in supplied pgp block." << std::endl; + RsErr() << "No or incomplete/invalid key in supplied pgp block." ; return false ; } if(tmp_keyring->keys[0].uids == NULL) { - std::cerr << "No uid in supplied key." << std::endl; + RsErr() << "No uid in supplied key." ; return false ; } @@ -737,14 +737,14 @@ bool OpenPGPSDKHandler::getGPGDetailsFromBinaryBlock(const unsigned char *mem_bl } if(res == ops_false) - std::cerr << "(WW) Error in OpenPGPSDKHandler::validateAndUpdateSignatures(). Validation failed for at least some signatures." << std::endl; + RsErr() << "(WW) Error in OpenPGPSDKHandler::validateAndUpdateSignatures(). Validation failed for at least some signatures." ; // also add self-signature if any (there should be!). // res = ops_validate_key_signatures(result,&tmp_keyring->keys[0],tmp_keyring,cb_get_passphrase) ; if(res == ops_false) - std::cerr << "(WW) Error in OpenPGPSDKHandler::validateAndUpdateSignatures(). Validation failed for at least some signatures." << std::endl; + RsErr() << "(WW) Error in OpenPGPSDKHandler::validateAndUpdateSignatures(). Validation failed for at least some signatures." ; // Parse signers. // @@ -846,7 +846,7 @@ bool OpenPGPSDKHandler::checkAndImportKeyPair(ops_keyring_t *tmp_keyring, RsPgpI else { import_error = "Unrecognised key type in key file for key #0. Giving up." ; - std::cerr << "Unrecognised key type " << tmp_keyring->keys[0].type << " in key file for key #0. Giving up." << std::endl; + RsErr() << "Unrecognised key type " << tmp_keyring->keys[0].type << " in key file for key #0. Giving up." ; return false ; } if(tmp_keyring->keys[1].type == OPS_PTAG_CT_PUBLIC_KEY) @@ -856,7 +856,7 @@ bool OpenPGPSDKHandler::checkAndImportKeyPair(ops_keyring_t *tmp_keyring, RsPgpI else { import_error = "Unrecognised key type in key file for key #1. Giving up." ; - std::cerr << "Unrecognised key type " << tmp_keyring->keys[1].type << " in key file for key #1. Giving up." << std::endl; + RsErr() << "Unrecognised key type " << tmp_keyring->keys[1].type << " in key file for key #1. Giving up." ; return false ; } @@ -1003,7 +1003,7 @@ bool OpenPGPSDKHandler::LoadCertificate(const unsigned char *data,uint32_t data_ { RsStackMutex mtx(pgphandlerMtx) ; // lock access to PGP memory structures. #ifdef DEBUG_PGPHANDLER - std::cerr << "Reading new key from string: " << std::endl; + RsErr() << "Reading new key from string: " ; #endif ops_keyring_t *tmp_keyring = allocateOPSKeyring(); @@ -1017,7 +1017,7 @@ bool OpenPGPSDKHandler::LoadCertificate(const unsigned char *data,uint32_t data_ ops_memory_release(mem) ; free(mem) ; - std::cerr << "Could not read key. Format error?" << std::endl; + RsErr() << "Could not read key. Format error?" ; error_string = std::string("Could not read key. Format error?") ; return false ; } @@ -1029,7 +1029,7 @@ bool OpenPGPSDKHandler::LoadCertificate(const unsigned char *data,uint32_t data_ // if(tmp_keyring->nkeys != 1) { - std::cerr << "Loaded certificate contains more than one PGP key. This is not allowed." << std::endl; + RsErr() << "Loaded certificate contains more than one PGP key. This is not allowed." ; error_string = "Loaded certificate contains more than one PGP key. This is not allowed." ; return false ; } @@ -1041,7 +1041,7 @@ bool OpenPGPSDKHandler::LoadCertificate(const unsigned char *data,uint32_t data_ if(keydata->key.pkey.version != 4) { error_string = "Public key is not version 4. Rejected!" ; - std::cerr << "Received a key with unhandled version number (" << keydata->key.pkey.version << ")" << std::endl; + RsErr() << "Received a key with unhandled version number (" << keydata->key.pkey.version << ")" ; return false ; } @@ -1066,14 +1066,14 @@ bool OpenPGPSDKHandler::LoadCertificate(const unsigned char *data,uint32_t data_ if(!found) { error_string = "This key is not self-signed. This is required by Retroshare." ; - std::cerr << "This key is not self-signed. This is required by Retroshare." << std::endl; + RsErr() << "This key is not self-signed. This is required by Retroshare." ; ops_validate_result_free(result); return false ; } ops_validate_result_free(result); #ifdef DEBUG_PGPHANDLER - std::cerr << " Key read correctly: " << std::endl; + RsErr() << " Key read correctly: " ; ops_keyring_list(tmp_keyring) ; #endif @@ -1084,11 +1084,11 @@ bool OpenPGPSDKHandler::LoadCertificate(const unsigned char *data,uint32_t data_ { _pubring_changed = true ; #ifdef DEBUG_PGPHANDLER - std::cerr << " Added the key in the main public keyring." << std::endl; + RsErr() << " Added the key in the main public keyring." ; #endif } else - std::cerr << "Key already in public keyring." << std::endl; + RsErr() << "Key already in public keyring." ; if(tmp_keyring->nkeys > 0) id = RsPgpId(tmp_keyring->keys[0].key_id) ; @@ -1109,8 +1109,8 @@ bool OpenPGPSDKHandler::locked_addOrMergeKey(ops_keyring_t *keyring,std::mapkey_id) ; #ifdef DEBUG_PGPHANDLER - std::cerr << "AddOrMergeKey():" << std::endl; - std::cerr << " id: " << id.toStdString() << std::endl; + RsErr() << "AddOrMergeKey():" ; + RsErr() << " id: " << id.toStdString() ; #endif // See if the key is already in the keyring @@ -1125,7 +1125,7 @@ bool OpenPGPSDKHandler::locked_addOrMergeKey(ops_keyring_t *keyring,std::mapsecond._key_index)) == NULL) { #ifdef DEBUG_PGPHANDLER - std::cerr << " Key is new. Adding it to keyring" << std::endl; + RsErr() << " Key is new. Adding it to keyring" ; #endif addNewKeyToOPSKeyring(keyring,*keydata) ; // the key is new. initCertificateInfo(kmap[id],keydata,keyring->nkeys-1) ; @@ -1138,12 +1138,12 @@ bool OpenPGPSDKHandler::locked_addOrMergeKey(ops_keyring_t *keyring,std::mapfingerprint.fingerprint, RsPgpFingerprint::SIZE_IN_BYTES )) { - std::cerr << "(EE) attempt to merge key with identical id, but different fingerprint!" << std::endl; + RsErr() << "(EE) attempt to merge key with identical id, but different fingerprint!" ; return false ; } #ifdef DEBUG_PGPHANDLER - std::cerr << " Key exists. Merging signatures." << std::endl; + RsErr() << " Key exists. Merging signatures." ; #endif ret = mergeKeySignatures(const_cast(existing_key),keydata) ; @@ -1168,13 +1168,13 @@ bool OpenPGPSDKHandler::encryptTextToFile(const RsPgpId& key_id,const std::strin if(public_key == NULL) { - std::cerr << "Cannot get public key of id " << key_id.toStdString() << std::endl; + RsErr() << "Cannot get public key of id " << key_id.toStdString() ; return false ; } if(public_key->type != OPS_PTAG_CT_PUBLIC_KEY) { - std::cerr << "OpenPGPSDKHandler::encryptTextToFile(): ERROR: supplied id did not return a public key!" << std::endl; + RsErr() << "OpenPGPSDKHandler::encryptTextToFile(): ERROR: supplied id did not return a public key!" ; return false ; } @@ -1185,13 +1185,13 @@ bool OpenPGPSDKHandler::encryptTextToFile(const RsPgpId& key_id,const std::strin if (fd < 0) { - std::cerr << "OpenPGPSDKHandler::encryptTextToFile(): ERROR: Cannot write to " << outfile_tmp << std::endl; + RsErr() << "OpenPGPSDKHandler::encryptTextToFile(): ERROR: Cannot write to " << outfile_tmp ; return false ; } if(!ops_encrypt_stream(info, public_key, NULL, ops_false, ops_true)) { - std::cerr << "OpenPGPSDKHandler::encryptTextToFile(): ERROR: encryption failed." << std::endl; + RsErr() << "OpenPGPSDKHandler::encryptTextToFile(): ERROR: encryption failed." ; return false ; } @@ -1200,7 +1200,7 @@ bool OpenPGPSDKHandler::encryptTextToFile(const RsPgpId& key_id,const std::strin if(!RsDirUtil::renameFile(outfile_tmp,outfile)) { - std::cerr << "OpenPGPSDKHandler::encryptTextToFile(): ERROR: Cannot rename " + outfile_tmp + " to " + outfile + ". Disk error?" << std::endl; + RsErr() << "OpenPGPSDKHandler::encryptTextToFile(): ERROR: Cannot rename " + outfile_tmp + " to " + outfile + ". Disk error?" ; return false ; } @@ -1215,18 +1215,18 @@ bool OpenPGPSDKHandler::encryptDataBin(const RsPgpId& key_id,const void *data, c if(public_key == NULL) { - std::cerr << "Cannot get public key of id " << key_id.toStdString() << std::endl; + RsErr() << "Cannot get public key of id " << key_id.toStdString() ; return false ; } if(public_key->type != OPS_PTAG_CT_PUBLIC_KEY) { - std::cerr << "OpenPGPSDKHandler::encryptTextToFile(): ERROR: supplied id did not return a public key!" << std::endl; + RsErr() << "OpenPGPSDKHandler::encryptTextToFile(): ERROR: supplied id did not return a public key!" ; return false ; } if(public_key->key.pkey.algorithm != OPS_PKA_RSA) { - std::cerr << "OpenPGPSDKHandler::encryptTextToFile(): ERROR: supplied key id " << key_id.toStdString() << " is not an RSA key (DSA for instance, is not supported)!" << std::endl; + RsErr() << "OpenPGPSDKHandler::encryptTextToFile(): ERROR: supplied key id " << key_id.toStdString() << " is not an RSA key (DSA for instance, is not supported)!" ; return false ; } ops_create_info_t *info; @@ -1236,7 +1236,7 @@ bool OpenPGPSDKHandler::encryptDataBin(const RsPgpId& key_id,const void *data, c if(!ops_encrypt_stream(info, public_key, NULL, ops_false, ops_false)) { - std::cerr << "Encryption failed." << std::endl; + RsErr() << "Encryption failed." ; res = false ; } @@ -1257,7 +1257,7 @@ bool OpenPGPSDKHandler::encryptDataBin(const RsPgpId& key_id,const void *data, c } else { - std::cerr << "Not enough room to fit encrypted data. Size given=" << *encrypted_data_len << ", required=" << tlen << std::endl; + RsErr() << "Not enough room to fit encrypted data. Size given=" << *encrypted_data_len << ", required=" << tlen ; res = false ; } @@ -1275,7 +1275,7 @@ bool OpenPGPSDKHandler::decryptDataBin(const RsPgpId& /*key_id*/,const void *enc if(*data_len < (unsigned int)out_length) { - std::cerr << "Not enough room to store decrypted data! Please give more."<< std::endl; + RsErr() << "Not enough room to store decrypted data! Please give more."; return false ; } @@ -1297,7 +1297,7 @@ bool OpenPGPSDKHandler::decryptTextFromFile(const RsPgpId&,std::string& text,con if (f == NULL) { - std::cerr << "Cannot open file " << inputfile << " for read." << std::endl; + RsErr() << "Cannot open file " << inputfile << " for read." ; return false; } @@ -1308,8 +1308,8 @@ bool OpenPGPSDKHandler::decryptTextFromFile(const RsPgpId&,std::string& text,con fclose(f) ; #ifdef DEBUG_PGPHANDLER - std::cerr << "OpenPGPSDKHandler::decryptTextFromFile: read a file of length " << std::dec << buf.length() << std::endl; - std::cerr << "buf=\"" << buf << "\"" << std::endl; + RsErr() << "OpenPGPSDKHandler::decryptTextFromFile: read a file of length " << std::dec << buf.length() ; + RsErr() << "buf=\"" << buf << "\"" ; #endif int out_length ; @@ -1329,7 +1329,7 @@ bool OpenPGPSDKHandler::SignDataBin(const RsPgpId& id,const void *data, const ui if(!key) { - std::cerr << "Cannot sign: no secret key with id " << id.toStdString() << std::endl; + RsErr() << "Cannot sign: no secret key with id " << id.toStdString() ; return false ; } @@ -1357,18 +1357,18 @@ ops_secret_key_t *secret_key = NULL ; if(cancelled) { - std::cerr << "Key entering cancelled" << std::endl; + RsErr() << "Key entering cancelled" ; return false ; } if(secret_key) break ; - std::cerr << "Key decryption went wrong. Wrong passwd?" << std::endl; + RsErr() << "Key decryption went wrong. Wrong passwd?" ; last_passwd_was_wrong = true ; } if(!secret_key) { - std::cerr << "Could not obtain secret key. Signature cancelled." << std::endl; + RsErr() << "Could not obtain secret key. Signature cancelled." ; return false ; } @@ -1396,7 +1396,7 @@ ops_secret_key_t *secret_key = NULL ; } else { - std::cerr << "(EE) memory chunk is not large enough for signature packet. Requred size: " << slen << " bytes." << std::endl; + RsErr() << "(EE) memory chunk is not large enough for signature packet. Requred size: " << slen << " bytes." ; res = false ; } @@ -1406,13 +1406,13 @@ ops_secret_key_t *secret_key = NULL ; free(secret_key) ; #ifdef DEBUG_PGPHANDLER - std::cerr << "Signed with fingerprint " << fp.toStdString() << ", length " << std::dec << *signlen << ", literal data length = " << len << std::endl; - std::cerr << "Signature body: " << std::endl; + RsErr() << "Signed with fingerprint " << fp.toStdString() << ", length " << std::dec << *signlen << ", literal data length = " << len ; + RsErr() << "Signature body: " ; hexdump( (unsigned char *)data, len) ; - std::cerr << std::endl; - std::cerr << "Data: " << std::endl; + RsErr() ; + RsErr() << "Data: " ; hexdump( (unsigned char *)sign,*signlen) ; - std::cerr << std::endl; + RsErr() ; #endif return res ; } @@ -1425,7 +1425,7 @@ bool OpenPGPSDKHandler::privateSignCertificate(const RsPgpId& ownId,const RsPgpI if(key_to_sign == NULL) { - std::cerr << "Cannot sign: no public key with id " << id_of_key_to_sign.toStdString() << std::endl; + RsErr() << "Cannot sign: no public key with id " << id_of_key_to_sign.toStdString() ; return false ; } @@ -1435,14 +1435,14 @@ bool OpenPGPSDKHandler::privateSignCertificate(const RsPgpId& ownId,const RsPgpI if(!skey) { - std::cerr << "Cannot sign: no secret key with id " << ownId.toStdString() << std::endl; + RsErr() << "Cannot sign: no secret key with id " << ownId.toStdString() ; return false ; } const ops_keydata_t *pkey = locked_getPublicKey(ownId,true) ; if(!pkey) { - std::cerr << "Cannot sign: no public key with id " << ownId.toStdString() << std::endl; + RsErr() << "Cannot sign: no public key with id " << ownId.toStdString() ; return false ; } @@ -1453,12 +1453,12 @@ bool OpenPGPSDKHandler::privateSignCertificate(const RsPgpId& ownId,const RsPgpI if(cancelled) { - std::cerr << "Key cancelled by used." << std::endl; + RsErr() << "Key cancelled by used." ; return false ; } if(!secret_key) { - std::cerr << "Key decryption went wrong. Wrong passwd?" << std::endl; + RsErr() << "Key decryption went wrong. Wrong passwd?" ; return false ; } @@ -1466,7 +1466,7 @@ bool OpenPGPSDKHandler::privateSignCertificate(const RsPgpId& ownId,const RsPgpI if(!ops_sign_key(key_to_sign,pkey->key_id,secret_key)) { - std::cerr << "Key signature went wrong. Wrong passwd?" << std::endl; + RsErr() << "Key signature went wrong. Wrong passwd?" ; return false ; } @@ -1511,7 +1511,7 @@ bool OpenPGPSDKHandler::VerifySignBin(const void *literal_data, uint32_t literal if(key == NULL) { - std::cerr << "No key returned by fingerprint " << key_fingerprint.toStdString() << ", and ID " << id.toStdString() << ", signature verification failed!" << std::endl; + RsErr() << "No key returned by fingerprint " << key_fingerprint.toStdString() << ", and ID " << id.toStdString() << ", signature verification failed!" ; return false ; } @@ -1522,18 +1522,18 @@ bool OpenPGPSDKHandler::VerifySignBin(const void *literal_data, uint32_t literal if(key_fingerprint != PGPFingerprintType(fp.fingerprint)) { - std::cerr << "Key fingerprint does not match " << key_fingerprint.toStdString() << ", for ID " << id.toStdString() << ", signature verification failed!" << std::endl; + RsErr() << "Key fingerprint does not match " << key_fingerprint.toStdString() << ", for ID " << id.toStdString() << ", signature verification failed!" ; return false ; } #ifdef DEBUG_PGPHANDLER - std::cerr << "Verifying signature from fingerprint " << key_fingerprint.toStdString() << ", length " << std::dec << sign_len << ", literal data length = " << literal_data_length << std::endl; - std::cerr << "Signature body: " << std::endl; + RsErr() << "Verifying signature from fingerprint " << key_fingerprint.toStdString() << ", length " << std::dec << sign_len << ", literal data length = " << literal_data_length ; + RsErr() << "Signature body: " ; hexdump( (unsigned char *)sign,sign_len) ; - std::cerr << std::endl; - std::cerr << "Signed data: " << std::endl; + RsErr() ; + RsErr() << "Signed data: " ; hexdump( (unsigned char *)literal_data, literal_data_length) ; - std::cerr << std::endl; + RsErr() ; #endif return ops_validate_detached_signature(literal_data,literal_data_length,sign,sign_len,key) ; @@ -1563,7 +1563,7 @@ bool OpenPGPSDKHandler::mergeKeySignatures(ops_keydata_t *dst,const ops_keydata_ // First sort all signatures into lists to see which is new, which is not new #ifdef DEBUG_PGPHANDLER - std::cerr << "Merging signatures for key " << RsPgpId(dst->key_id).toStdString() << std::endl; + RsErr() << "Merging signatures for key " << RsPgpId(dst->key_id).toStdString() ; #endif std::set dst_packets ; @@ -1584,14 +1584,14 @@ bool OpenPGPSDKHandler::mergeKeySignatures(ops_keydata_t *dst,const ops_keydata_ to_add.insert(src->packets[i]) ; #ifdef DEBUG_PGPHANDLER else - std::cerr << " Packet with tag 0x" << std::hex << (int)(src->packets[i].raw[0]) << std::dec << " not merged, because it is not a signature." << std::endl; + RsErr() << " Packet with tag 0x" << std::hex << (int)(src->packets[i].raw[0]) << std::dec << " not merged, because it is not a signature." ; #endif } for(std::set::const_iterator it(to_add.begin());it!=to_add.end();++it) { #ifdef DEBUG_PGPHANDLER - std::cerr << " Adding packet with tag 0x" << std::hex << (int)(*it).raw[0] << std::dec << std::endl; + RsErr() << " Adding packet with tag 0x" << std::hex << (int)(*it).raw[0] << std::dec ; #endif ops_add_packet_to_keydata(dst,&*it) ; } @@ -1604,7 +1604,7 @@ bool OpenPGPSDKHandler::syncDatabase() RsStackFileLock flck(_pgp_lock_filename) ; // lock access to PGP directory. #ifdef DEBUG_PGPHANDLER - std::cerr << "Sync-ing keyrings." << std::endl; + RsErr() << "Sync-ing keyrings." ; #endif locked_syncPublicKeyring() ; //locked_syncSecretKeyring() ; @@ -1614,7 +1614,7 @@ bool OpenPGPSDKHandler::syncDatabase() locked_syncTrustDatabase() ; #ifdef DEBUG_PGPHANDLER - std::cerr << "Done. " << std::endl; + RsErr() << "Done. " ; #endif return true ; } @@ -1629,11 +1629,11 @@ bool OpenPGPSDKHandler::locked_syncPublicKeyring() #else if(-1 == stat64(_pubring_path.c_str(), &buf)) #endif - std::cerr << "OpenPGPSDKHandler::syncDatabase(): can't stat file " << _pubring_path << ". Can't sync public keyring." << std::endl; + RsErr() << "OpenPGPSDKHandler::syncDatabase(): can't stat file " << _pubring_path << ". Can't sync public keyring." ; if(_pubring_last_update_time < buf.st_mtime) { - std::cerr << "Detected change on disk of public keyring. Merging!" << std::endl ; + RsErr() << "Detected change on disk of public keyring. Merging!" << std::endl ; locked_mergeKeyringFromDisk(_pubring,_public_keyring_map,_pubring_path) ; _pubring_last_update_time = buf.st_mtime ; @@ -1644,19 +1644,19 @@ bool OpenPGPSDKHandler::locked_syncPublicKeyring() { std::string tmp_keyring_file = _pubring_path + ".tmp" ; - std::cerr << "Local changes in public keyring. Writing to disk..." << std::endl; + RsErr() << "Local changes in public keyring. Writing to disk..." ; if(!ops_write_keyring_to_file(_pubring,ops_false,tmp_keyring_file.c_str(),ops_true)) { - std::cerr << "Cannot write public keyring tmp file. Disk full? Disk quota exceeded?" << std::endl; + RsErr() << "Cannot write public keyring tmp file. Disk full? Disk quota exceeded?" ; return false ; } if(!RsDirUtil::renameFile(tmp_keyring_file,_pubring_path)) { - std::cerr << "Cannot rename tmp pubring file " << tmp_keyring_file << " into actual pubring file " << _pubring_path << ". Check writing permissions?!?" << std::endl; + RsErr() << "Cannot rename tmp pubring file " << tmp_keyring_file << " into actual pubring file " << _pubring_path << ". Check writing permissions?!?" ; return false ; } - std::cerr << "Done." << std::endl; + RsErr() << "Done." ; _pubring_last_update_time = time(NULL) ; // should we get this value from the disk instead?? _pubring_changed = false ; } @@ -1668,7 +1668,7 @@ void OpenPGPSDKHandler::locked_mergeKeyringFromDisk(ops_keyring_t *keyring, const std::string& keyring_file) { #ifdef DEBUG_PGPHANDLER - std::cerr << "Merging keyring " << keyring_file << " from disk to memory." << std::endl; + RsErr() << "Merging keyring " << keyring_file << " from disk to memory." ; #endif // 1 - load keyring into a temporary keyring list. @@ -1676,7 +1676,7 @@ void OpenPGPSDKHandler::locked_mergeKeyringFromDisk(ops_keyring_t *keyring, if(ops_false == ops_keyring_read_from_file(tmp_keyring, false, keyring_file.c_str())) { - std::cerr << "OpenPGPSDKHandler::locked_mergeKeyringFromDisk(): cannot read keyring. File corrupted?" ; + RsErr() << "OpenPGPSDKHandler::locked_mergeKeyringFromDisk(): cannot read keyring. File corrupted?" ; ops_keyring_free(tmp_keyring) ; return ; } @@ -1702,7 +1702,7 @@ bool OpenPGPSDKHandler::removeKeysFromPGPKeyring(const std::set& keys_t for(std::set::const_iterator it(keys_to_remove.begin());it!=keys_to_remove.end();++it) if(locked_getSecretKey(*it) != NULL) { - std::cerr << "(EE) OpenPGPSDKHandler:: can't remove key " << (*it).toStdString() << " since its shared by a secret key! Operation cancelled." << std::endl; + RsErr() << "(EE) OpenPGPSDKHandler:: can't remove key " << (*it).toStdString() << " since its shared by a secret key! Operation cancelled." ; error_code = PGP_KEYRING_REMOVAL_ERROR_CANT_REMOVE_SECRET_KEYS ; return false ; } @@ -1723,7 +1723,7 @@ bool OpenPGPSDKHandler::removeKeysFromPGPKeyring(const std::set& keys_t if(mktemp(template_name) == NULL) #endif { - std::cerr << "OpenPGPSDKHandler::removeKeysFromPGPKeyring(): cannot create keyring backup file. Giving up." << std::endl; + RsErr() << "OpenPGPSDKHandler::removeKeysFromPGPKeyring(): cannot create keyring backup file. Giving up." ; error_code = PGP_KEYRING_REMOVAL_ERROR_CANNOT_CREATE_BACKUP ; return false ; } @@ -1733,13 +1733,13 @@ bool OpenPGPSDKHandler::removeKeysFromPGPKeyring(const std::set& keys_t if(!ops_write_keyring_to_file(_pubring,ops_false,template_name,ops_true)) { - std::cerr << "OpenPGPSDKHandler::removeKeysFromPGPKeyring(): cannot write keyring backup file. Giving up." << std::endl; + RsErr() << "OpenPGPSDKHandler::removeKeysFromPGPKeyring(): cannot write keyring backup file. Giving up." ; error_code = PGP_KEYRING_REMOVAL_ERROR_CANNOT_WRITE_BACKUP ; return false ; } backup_file = std::string(template_name,_pubring_path.length()+7) ; - std::cerr << "Keyring was backed up to file " << backup_file << std::endl; + RsErr() << "Keyring was backed up to file " << backup_file ; // Remove keys from the keyring, and update the keyring map. // @@ -1747,7 +1747,7 @@ bool OpenPGPSDKHandler::removeKeysFromPGPKeyring(const std::set& keys_t { if(locked_getSecretKey(*it) != NULL) { - std::cerr << "(EE) OpenPGPSDKHandler:: can't remove key " << (*it).toStdString() << " since its shared by a secret key!" << std::endl; + RsErr() << "(EE) OpenPGPSDKHandler:: can't remove key " << (*it).toStdString() << " since its shared by a secret key!" ; continue ; } @@ -1755,13 +1755,13 @@ bool OpenPGPSDKHandler::removeKeysFromPGPKeyring(const std::set& keys_t if(res == _public_keyring_map.end()) { - std::cerr << "(EE) OpenPGPSDKHandler:: can't remove key " << (*it).toStdString() << " from keyring: key not found." << std::endl; + RsErr() << "(EE) OpenPGPSDKHandler:: can't remove key " << (*it).toStdString() << " from keyring: key not found." ; continue ; } if(res->second._key_index >= (unsigned int)_pubring->nkeys || RsPgpId(_pubring->keys[res->second._key_index].key_id) != *it) { - std::cerr << "(EE) OpenPGPSDKHandler:: can't remove key " << (*it).toStdString() << ". Inconsistency found." << std::endl; + RsErr() << "(EE) OpenPGPSDKHandler:: can't remove key " << (*it).toStdString() << ". Inconsistency found." ; error_code = PGP_KEYRING_REMOVAL_ERROR_DATA_INCONSISTENCY ; return false ; } diff --git a/libretroshare/src/pgp/pgphandler.cc b/libretroshare/src/pgp/pgphandler.cc index 3a5eaf837..850338868 100644 --- a/libretroshare/src/pgp/pgphandler.cc +++ b/libretroshare/src/pgp/pgphandler.cc @@ -67,33 +67,33 @@ PGPHandler::~PGPHandler() bool PGPHandler::printKeys() const { #ifdef DEBUG_PGPHANDLER - std::cerr << "Printing details of all " << std::dec << _public_keyring_map.size() << " keys: " << std::endl; + RsErr() << "Printing details of all " << std::dec << _public_keyring_map.size() << " keys: " ; #endif for(std::map::const_iterator it(_public_keyring_map.begin()); it != _public_keyring_map.end(); ++it) { - std::cerr << "PGP Key: " << it->first.toStdString() << std::endl; + RsErr() << "PGP Key: " << it->first.toStdString() ; - std::cerr << "\tName : " << it->second._name << std::endl; - std::cerr << "\tEmail : " << it->second._email << std::endl; - std::cerr << "\tOwnSign : " << (it->second._flags & PGPCertificateInfo::PGP_CERTIFICATE_FLAG_HAS_OWN_SIGNATURE) << std::endl; - std::cerr << "\tAccept Connect: " << (it->second._flags & PGPCertificateInfo::PGP_CERTIFICATE_FLAG_ACCEPT_CONNEXION) << std::endl; - std::cerr << "\ttrustLvl : " << it->second._trustLvl << std::endl; - std::cerr << "\tvalidLvl : " << it->second._validLvl << std::endl; - std::cerr << "\tUse time stamp: " << it->second._time_stamp << std::endl; - std::cerr << "\tfingerprint : " << it->second._fpr.toStdString() << std::endl; - std::cerr << "\tSigners : " << it->second.signers.size() << std::endl; + RsErr() << "\tName : " << it->second._name ; + RsErr() << "\tEmail : " << it->second._email ; + RsErr() << "\tOwnSign : " << (it->second._flags & PGPCertificateInfo::PGP_CERTIFICATE_FLAG_HAS_OWN_SIGNATURE) ; + RsErr() << "\tAccept Connect: " << (it->second._flags & PGPCertificateInfo::PGP_CERTIFICATE_FLAG_ACCEPT_CONNEXION) ; + RsErr() << "\ttrustLvl : " << it->second._trustLvl ; + RsErr() << "\tvalidLvl : " << it->second._validLvl ; + RsErr() << "\tUse time stamp: " << it->second._time_stamp ; + RsErr() << "\tfingerprint : " << it->second._fpr.toStdString() ; + RsErr() << "\tSigners : " << it->second.signers.size() ; std::set::const_iterator sit; for(sit = it->second.signers.begin(); sit != it->second.signers.end(); ++sit) { - std::cerr << "\t\tSigner ID:" << (*sit).toStdString() << ", Name: " ; + RsErr() << "\t\tSigner ID:" << (*sit).toStdString() << ", Name: " ; const PGPCertificateInfo *info = PGPHandler::getCertificateInfo(*sit) ; if(info != NULL) - std::cerr << info->_name ; + RsErr() << info->_name ; - std::cerr << std::endl ; + RsErr() << std::endl ; } } return true ; @@ -117,7 +117,7 @@ void PGPHandler::updateOwnSignatureFlag(const RsPgpId& own_id) if(_public_keyring_map.find(own_id)==_public_keyring_map.end()) { - std::cerr << __func__ << ": key with id=" << own_id.toStdString() << " not in keyring." << std::endl; + RsErr() << __func__ << ": key with id=" << own_id.toStdString() << " not in keyring." ; // return now, because the following operation would add an entry to _public_keyring_map return; } @@ -135,7 +135,7 @@ void PGPHandler::updateOwnSignatureFlag(const RsPgpId& cert_id,const RsPgpId& ow if(it == _public_keyring_map.end()) { - std::cerr << "updateOwnSignatureFlag: Cannot get certificate for string " << cert_id.toStdString() << ". This is probably a bug." << std::endl; + RsErr() << "updateOwnSignatureFlag: Cannot get certificate for string " << cert_id.toStdString() << ". This is probably a bug." ; return ; } @@ -234,7 +234,7 @@ bool PGPHandler::privateTrustCertificate(const RsPgpId& id,int trustlvl) { if(trustlvl < 0 || trustlvl >= 6 || trustlvl == 1) { - std::cerr << "Invalid trust level " << trustlvl << " passed to privateTrustCertificate." << std::endl; + RsErr() << "Invalid trust level " << trustlvl << " passed to privateTrustCertificate." ; return false ; } @@ -242,7 +242,7 @@ bool PGPHandler::privateTrustCertificate(const RsPgpId& id,int trustlvl) if(it == _public_keyring_map.end()) { - std::cerr << "(EE) Key id " << id.toStdString() << " not in the keyring. Can't setup trust level." << std::endl; + RsErr() << "(EE) Key id " << id.toStdString() << " not in the keyring. Can't setup trust level." ; return false ; } @@ -266,12 +266,12 @@ void PGPHandler::locked_readPrivateTrustDatabase() { FILE *fdb = RsDirUtil::rs_fopen(_trustdb_path.c_str(),"rb") ; #ifdef DEBUG_PGPHANDLER - std::cerr << "PGPHandler: Reading private trust database." << std::endl; + RsErr() << "PGPHandler: Reading private trust database." ; #endif if(fdb == NULL) { - std::cerr << " private trust database not found. No trust info loaded." << std::endl ; + RsErr() << " private trust database not found. No trust info loaded." << std::endl ; return ; } std::map::iterator it ; @@ -284,12 +284,12 @@ void PGPHandler::locked_readPrivateTrustDatabase() if(it == _public_keyring_map.end()) { - std::cerr << " (WW) Trust packet found for unknown key id " << RsPgpId(trustpacket.user_id).toStdString() << std::endl; + RsErr() << " (WW) Trust packet found for unknown key id " << RsPgpId(trustpacket.user_id).toStdString() ; continue ; } if(trustpacket.trust_level > 6) { - std::cerr << " (WW) Trust packet found with unexpected trust level " << trustpacket.trust_level << std::endl; + RsErr() << " (WW) Trust packet found with unexpected trust level " << trustpacket.trust_level ; continue ; } @@ -302,19 +302,19 @@ void PGPHandler::locked_readPrivateTrustDatabase() fclose(fdb) ; - std::cerr << "PGPHandler: Successfully read " << std::hex << n_packets << std::dec << " trust packets." << std::endl; + RsErr() << "PGPHandler: Successfully read " << std::hex << n_packets << std::dec << " trust packets." ; } bool PGPHandler::locked_writePrivateTrustDatabase() { FILE *fdb = RsDirUtil::rs_fopen((_trustdb_path+".tmp").c_str(),"wb") ; #ifdef DEBUG_PGPHANDLER - std::cerr << "PGPHandler: Reading private trust database." << std::endl; + RsErr() << "PGPHandler: Reading private trust database." ; #endif if(fdb == NULL) { - std::cerr << " (EE) Can't open private trust database file " << _trustdb_path << " for write. Giving up!" << std::endl ; + RsErr() << " (EE) Can't open private trust database file " << _trustdb_path << " for write. Giving up!" << std::endl ; return false; } PrivateTrustPacket trustpacket ; @@ -332,7 +332,7 @@ bool PGPHandler::locked_writePrivateTrustDatabase() if(fwrite((void*)&trustpacket,sizeof(PrivateTrustPacket),1,fdb) != 1) { - std::cerr << " (EE) Cannot write to trust database " << _trustdb_path << ". Disc full, or quota exceeded ? Leaving database untouched." << std::endl; + RsErr() << " (EE) Cannot write to trust database " << _trustdb_path << ". Disc full, or quota exceeded ? Leaving database untouched." ; fclose(fdb) ; return false; } @@ -342,7 +342,7 @@ bool PGPHandler::locked_writePrivateTrustDatabase() if(!RsDirUtil::renameFile(_trustdb_path+".tmp",_trustdb_path)) { - std::cerr << " (EE) Cannot move temp file " << _trustdb_path+".tmp" << ". Bad write permissions?" << std::endl; + RsErr() << " (EE) Cannot move temp file " << _trustdb_path+".tmp" << ". Bad write permissions?" ; return false ; } else @@ -360,13 +360,13 @@ bool PGPHandler::locked_syncTrustDatabase() if(-1 == stat64(_trustdb_path.c_str(), &buf)) #endif { - std::cerr << "PGPHandler::syncDatabase(): can't stat file " << _trustdb_path << ". Will force write it." << std::endl; + RsErr() << "PGPHandler::syncDatabase(): can't stat file " << _trustdb_path << ". Will force write it." ; _trustdb_changed = true ; // we force write of trust database if it does not exist. } if(_trustdb_last_update_time < buf.st_mtime) { - std::cerr << "Detected change on disk of trust database. " << std::endl ; + RsErr() << "Detected change on disk of trust database. " << std::endl ; locked_readPrivateTrustDatabase(); _trustdb_last_update_time = time(NULL) ; @@ -374,12 +374,12 @@ bool PGPHandler::locked_syncTrustDatabase() if(_trustdb_changed) { - std::cerr << "Local changes in trust database. Writing to disk..." << std::endl; + RsErr() << "Local changes in trust database. Writing to disk..." ; if(!locked_writePrivateTrustDatabase()) - std::cerr << "Cannot write trust database. Disk full? Disk quota exceeded?" << std::endl; + RsErr() << "Cannot write trust database. Disk full? Disk quota exceeded?" ; else { - std::cerr << "Done." << std::endl; + RsErr() << "Done." ; _trustdb_last_update_time = time(NULL) ; _trustdb_changed = false ; } From d9368507a9fcc8fac9970097d0be4c99490f1a5c Mon Sep 17 00:00:00 2001 From: csoler Date: Wed, 15 Dec 2021 22:15:52 +0100 Subject: [PATCH 068/113] 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 069/113] 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 070/113] 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 071/113] 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 072/113] 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 073/113] 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 e137c1703986992256d12e952af66f1cf4858351 Mon Sep 17 00:00:00 2001 From: Phenom Date: Thu, 28 Oct 2021 18:13:25 +0200 Subject: [PATCH 074/113] Fix NotifyQt::askForPassword QInputDialog is not created in GUI Thread. --- libretroshare/src/pgp/openpgpsdkhandler.cc | 69 +++++++++++++--------- retroshare-gui/src/gui/MainWindow.cpp | 17 ++++++ retroshare-gui/src/gui/MainWindow.h | 39 +++++++++++- retroshare-gui/src/gui/notifyqt.cpp | 65 ++++++++++++-------- 4 files changed, 134 insertions(+), 56 deletions(-) diff --git a/libretroshare/src/pgp/openpgpsdkhandler.cc b/libretroshare/src/pgp/openpgpsdkhandler.cc index 5a4a02d49..4b587563d 100644 --- a/libretroshare/src/pgp/openpgpsdkhandler.cc +++ b/libretroshare/src/pgp/openpgpsdkhandler.cc @@ -1322,15 +1322,19 @@ bool OpenPGPSDKHandler::decryptTextFromFile(const RsPgpId&,std::string& text,con bool OpenPGPSDKHandler::SignDataBin(const RsPgpId& id,const void *data, const uint32_t len, unsigned char *sign, unsigned int *signlen,bool use_raw_signature, std::string reason /* = "" */) { - RsStackMutex mtx(pgphandlerMtx) ; // lock access to PGP memory structures. // need to find the key and to decrypt it. - - const ops_keydata_t *key = locked_getSecretKey(id) ; - - if(!key) + ops_keydata_t *key = nullptr; { - RsErr() << "Cannot sign: no secret key with id " << id.toStdString() ; - return false ; + RS_STACK_MUTEX(pgphandlerMtx); // lock access to PGP memory structures. + const ops_keydata_t *test_key = locked_getSecretKey(id); + if(!test_key) + { + RsErr("Cannot sign: no secret key with id ", id.toStdString() ); + return false ; + } + // Copy key as it may take time for user to respond. + key = ops_keydata_new(); + ops_keydata_copy(key, test_key); } std::string uid_hint ; @@ -1345,35 +1349,42 @@ bool OpenPGPSDKHandler::SignDataBin(const RsPgpId& id,const void *data, const ui PGPFingerprintType fp(f.fingerprint) ; #endif - bool last_passwd_was_wrong = false ; -ops_secret_key_t *secret_key = NULL ; + bool last_passwd_was_wrong = false ; + ops_secret_key_t *secret_key = nullptr ; - for(int i=0;i<3;++i) - { - bool cancelled =false; - std::string passphrase = _passphrase_callback(NULL,reason.c_str(),uid_hint.c_str(),"Please enter passwd for encrypting your key : ",last_passwd_was_wrong,&cancelled) ;//TODO reason + for(int i=0;i<3;++i) + { + bool cancelled =false; + // Need to be outside of mutex to not block GUI. + std::string passphrase = _passphrase_callback(NULL,reason.c_str(),uid_hint.c_str(),"Please enter password for encrypting your key : ",last_passwd_was_wrong,&cancelled) ;//TODO reason - secret_key = ops_decrypt_secret_key_from_data(key,passphrase.c_str()) ; + secret_key = ops_decrypt_secret_key_from_data(key,passphrase.c_str()) ; - if(cancelled) - { - RsErr() << "Key entering cancelled" ; - return false ; - } - if(secret_key) - break ; + if(cancelled) + { + RsErr() << "Key entering cancelled" ; + ops_keydata_free(key); + return false ; + } + if(secret_key) + break ; - RsErr() << "Key decryption went wrong. Wrong passwd?" ; - last_passwd_was_wrong = true ; - } - if(!secret_key) - { - RsErr() << "Could not obtain secret key. Signature cancelled." ; - return false ; - } + RsErr() << "Key decryption went wrong. Wrong password?" ; + last_passwd_was_wrong = true ; + } + // No more need of key, free it. + ops_keydata_free(key); + + if(!secret_key) + { + RsErr() << "Could not obtain secret key. Signature cancelled." ; + return false ; + } // then do the signature. + RS_STACK_MUTEX(pgphandlerMtx); // lock access to PGP memory structures. + ops_boolean_t not_raw = !use_raw_signature ; #ifdef V07_NON_BACKWARD_COMPATIBLE_CHANGE_002 ops_memory_t *memres = ops_sign_buf(data,len,OPS_SIG_BINARY,OPS_HASH_SHA256,secret_key,ops_false,ops_false,not_raw,not_raw) ; diff --git a/retroshare-gui/src/gui/MainWindow.cpp b/retroshare-gui/src/gui/MainWindow.cpp index bf5dc6230..207fc5130 100644 --- a/retroshare-gui/src/gui/MainWindow.cpp +++ b/retroshare-gui/src/gui/MainWindow.cpp @@ -21,6 +21,7 @@ #include #include #include +#include #include #include #include @@ -1689,3 +1690,19 @@ void MainWindow::setCompactStatusMode(bool compact) ratesstatus->setCompactMode(compact); //opModeStatus: TODO Show only ??? } + +Gui_InputDialogReturn MainWindow::guiInputDialog(const QString& windowTitle, const QString& labelText, QLineEdit::EchoMode textEchoMode, bool modal) +{ + + QInputDialog dialog(this); + dialog.setWindowTitle(windowTitle); + dialog.setLabelText(labelText); + dialog.setTextEchoMode(textEchoMode); + dialog.setModal(modal); + + Gui_InputDialogReturn ret; + ret.execReturn = dialog.exec(); + ret.textValue = dialog.textValue(); + + return ret; +} diff --git a/retroshare-gui/src/gui/MainWindow.h b/retroshare-gui/src/gui/MainWindow.h index e34fda42a..b4f3cccd5 100644 --- a/retroshare-gui/src/gui/MainWindow.h +++ b/retroshare-gui/src/gui/MainWindow.h @@ -21,6 +21,7 @@ #ifndef _MainWindow_H #define _MainWindow_H +#include #include #include @@ -74,6 +75,14 @@ class MessengerWindow; class ApplicationWindow; #endif + +struct Gui_InputDialogReturn +{ + int execReturn; + QString textValue; +}; +Q_DECLARE_METATYPE(Gui_InputDialogReturn); + class MainWindow : public RWindow { Q_OBJECT @@ -192,7 +201,7 @@ public: } static bool hiddenmode; - + public slots: void receiveNewArgs(QStringList args); void displayErrorMessage(int,int,const QString&) ; @@ -210,9 +219,35 @@ public slots: void showBandwidthGraph(); void toggleStatusToolTip(bool toggle); + + /** + * @brief Create a QInputDialog. This must be called in MainWindow thread because Widgets must be created in the GUI thread. + * Here an exemple how to call it: + * + * bool sameThread = QThread::currentThread() == qApp->thread(); + * Gui_InputDialogReturn ret; + * qRegisterMetaType("Gui_InputDialogReturn"); + * QMetaObject::invokeMethod( MainWindow::getInstance() + * , "guiInputDialog" + * , sameThread ? Qt::DirectConnection : Qt::BlockingQueuedConnection + * , Q_RETURN_ARG(Gui_InputDialogReturn, ret) + * , Q_ARG(QString, windowTitle) + * , Q_ARG(QString, labelText) + * , Q_ARG(QLineEdit::EchoMode, textEchoMode) + * , Q_ARG(bool, modal) + * ); + * + * @param windowTitle: the window title (caption). + * @param labelText: label's text which describes what needs to be input. + * @param textEchoMode: the echo mode for the text value. + * @param modal: pop up the dialog as modal or modeless. + * @return Gui_InputDialogReturn ( Accepted(1)|Rejected(0), text value for the input dialog) + */ + Gui_InputDialogReturn guiInputDialog(const QString& windowTitle, const QString& labelText, QLineEdit::EchoMode textEchoMode, bool modal); + protected: /** Default Constructor */ - MainWindow(QWidget *parent = 0, Qt::WindowFlags flags = 0); + MainWindow(QWidget *parent = nullptr, Qt::WindowFlags flags = Qt::WindowFlags()); void closeEvent(QCloseEvent *); diff --git a/retroshare-gui/src/gui/notifyqt.cpp b/retroshare-gui/src/gui/notifyqt.cpp index 7bb1b6cf2..d0fcea506 100644 --- a/retroshare-gui/src/gui/notifyqt.cpp +++ b/retroshare-gui/src/gui/notifyqt.cpp @@ -21,12 +21,6 @@ #include "gui/common/FilesDefs.h" #include -#include -#include -#include -//#include -#include - #include "notifyqt.h" #include #include @@ -55,6 +49,13 @@ #include "retroshare/rsplugin.h" +#include +#include +#include +//#include +#include +#include + /***** * #define NOTIFY_DEBUG ****/ @@ -223,37 +224,51 @@ bool NotifyQt::askForPassword(const std::string& title, const std::string& key_d { RsAutoUpdatePage::lockAllEvents() ; - QInputDialog dialog; + QString windowTitle; if (title == "") { - dialog.setWindowTitle(tr("Passphrase required")); + windowTitle = tr("Passphrase required"); } else if (title == "AuthSSLimpl::SignX509ReqWithGPG()") { - dialog.setWindowTitle(tr("You need to sign your node's certificate.")); + windowTitle = tr("You need to sign your node's certificate."); } else if (title == "p3IdService::service_CreateGroup()") { - dialog.setWindowTitle(tr("You need to sign your forum/chatrooms identity.")); + windowTitle = tr("You need to sign your forum/chatrooms identity."); } else { - dialog.setWindowTitle(QString::fromStdString(title)); + windowTitle = QString::fromStdString(title); } - dialog.setLabelText((prev_is_bad ? QString("%1

").arg(tr("Wrong password !")) : QString()) + QString("%1
Profile: %2\n").arg(tr("Please enter your Retroshare passphrase"), QString::fromUtf8(key_details.c_str()))); - dialog.setTextEchoMode(QLineEdit::Password); - dialog.setModal(true); + QString labelText = ( prev_is_bad ? QString("%1

").arg(tr("Wrong password !")) : QString() ) + + QString("%1
Profile: %2\n") + .arg( tr("Please enter your Retroshare passphrase") + , QString::fromUtf8(key_details.c_str()) ); + QLineEdit::EchoMode textEchoMode = QLineEdit::Password; + bool modal = true; - int ret = dialog.exec(); + bool sameThread = QThread::currentThread() == qApp->thread(); + Gui_InputDialogReturn ret; + qRegisterMetaType("Gui_InputDialogReturn"); + QMetaObject::invokeMethod( MainWindow::getInstance() + , "guiInputDialog" + , sameThread ? Qt::DirectConnection : Qt::BlockingQueuedConnection + , Q_RETURN_ARG(Gui_InputDialogReturn, ret) + , Q_ARG(QString, windowTitle) + , Q_ARG(QString, labelText) + , Q_ARG(QLineEdit::EchoMode, textEchoMode) + , Q_ARG(bool, modal) + ); - cancelled = false ; + cancelled = false ; RsAutoUpdatePage::unlockAllEvents() ; - if (ret == QDialog::Rejected) { - password.clear() ; - cancelled = true ; - return true ; - } + if (ret.execReturn == QDialog::Rejected) { + password.clear() ; + cancelled = true ; + return true ; + } - if (ret == QDialog::Accepted) { - password = dialog.textValue().toUtf8().constData(); - return true; - } + if (ret.execReturn == QDialog::Accepted) { + password = ret.textValue.toUtf8().constData(); + return true; + } return false; } From 40b965cab1d43e5362e458d07755c2662e4c4bd2 Mon Sep 17 00:00:00 2001 From: csoler Date: Sat, 18 Dec 2021 21:30:58 +0100 Subject: [PATCH 075/113] 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 076/113] 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 077/113] 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 078/113] 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 079/113] 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 080/113] 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 081/113] 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 082/113] 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 083/113] 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 084/113] 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 085/113] 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 086/113] 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 087/113] 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 088/113] 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 089/113] 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 090/113] 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 091/113] 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: Fri, 24 Dec 2021 15:00:48 +0100 Subject: [PATCH 092/113] Fix RSElidedItemDelegate to use spacing in size hint. --- retroshare-gui/src/gui/ChatLobbyWidget.cpp | 37 ++-- retroshare-gui/src/gui/ChatLobbyWidget.ui | 10 +- retroshare-gui/src/gui/Identity/IdDialog.cpp | 190 +++++++----------- retroshare-gui/src/gui/Identity/IdDialog.ui | 10 + retroshare-gui/src/gui/common/ElidedLabel.cpp | 9 +- retroshare-gui/src/gui/common/FriendList.cpp | 8 +- .../src/gui/common/GroupTreeWidget.cpp | 46 +++-- .../src/gui/common/GroupTreeWidget.ui | 5 + .../src/gui/common/NewFriendList.cpp | 41 ++-- .../src/gui/common/RSElidedItemDelegate.cpp | 41 ++-- .../src/gui/common/RSTreeWidget.cpp | 9 +- 11 files changed, 216 insertions(+), 190 deletions(-) diff --git a/retroshare-gui/src/gui/ChatLobbyWidget.cpp b/retroshare-gui/src/gui/ChatLobbyWidget.cpp index d369c9bcf..13fdc4329 100644 --- a/retroshare-gui/src/gui/ChatLobbyWidget.cpp +++ b/retroshare-gui/src/gui/ChatLobbyWidget.cpp @@ -59,6 +59,10 @@ #define COLUMN_COUNT 3 #define COLUMN_DATA 0 +#define COLUMN_NAME_NB_CHAR 30 +#define COLUMN_USER_COUNT_NB_CHAR 4 +#define COLUMN_TOPIC_NB_CHAR 25 + #define ROLE_SORT Qt::UserRole #define ROLE_ID Qt::UserRole + 1 #define ROLE_SUBSCRIBED Qt::UserRole + 2 @@ -88,6 +92,13 @@ ChatLobbyWidget::ChatLobbyWidget(QWidget *parent, Qt::WindowFlags flags) { ui.setupUi(this); + int H = QFontMetricsF(ui.lobbyTreeWidget->font()).height(); +#if QT_VERSION < QT_VERSION_CHECK(5,11,0) + int W = QFontMetricsF(ui.lobbyTreeWidget->font()).width("_"); +#else + int W = QFontMetricsF(ui.lobbyTreeWidget->font()).horizontalAdvance("_"); +#endif + m_bProcessSettings = false; myChatLobbyUserNotify = NULL; myInviteYesButton = NULL; @@ -108,6 +119,10 @@ ChatLobbyWidget::ChatLobbyWidget(QWidget *parent, Qt::WindowFlags flags) compareRole = new RSTreeWidgetItemCompareRole; compareRole->setRole(COLUMN_NAME, ROLE_SORT); + RSElidedItemDelegate *itemDelegate = new RSElidedItemDelegate(this); + itemDelegate->setSpacing(QSize(W/2, H/4)); + ui.lobbyTreeWidget->setItemDelegate(itemDelegate); + ui.lobbyTreeWidget->setColumnCount(COLUMN_COUNT); ui.lobbyTreeWidget->sortItems(COLUMN_NAME, Qt::AscendingOrder); @@ -159,14 +174,11 @@ ChatLobbyWidget::ChatLobbyWidget(QWidget *parent, Qt::WindowFlags flags) ui.lobbyTreeWidget->setColumnHidden(COLUMN_USER_COUNT,true) ; ui.lobbyTreeWidget->setColumnHidden(COLUMN_TOPIC,true) ; ui.lobbyTreeWidget->setSortingEnabled(true) ; - ui.lobbyTreeWidget->setItemDelegateForColumn(COLUMN_NAME, new RSElidedItemDelegate()); - float fact = QFontMetricsF(font()).height()/14.0f; - ui.lobbyTreeWidget->adjustSize(); - ui.lobbyTreeWidget->setColumnWidth(COLUMN_NAME,100*fact); - ui.lobbyTreeWidget->setColumnWidth(COLUMN_USER_COUNT, 50*fact); - ui.lobbyTreeWidget->setColumnWidth(COLUMN_TOPIC, 50*fact); + ui.lobbyTreeWidget->setColumnWidth(COLUMN_NAME,COLUMN_NAME_NB_CHAR*W); + ui.lobbyTreeWidget->setColumnWidth(COLUMN_USER_COUNT, COLUMN_USER_COUNT_NB_CHAR*W); + ui.lobbyTreeWidget->setColumnWidth(COLUMN_TOPIC, COLUMN_TOPIC_NB_CHAR*W); /** Setup the actions for the header context menu */ showUserCountAct= new QAction(headerItem->text(COLUMN_USER_COUNT),this); @@ -181,7 +193,7 @@ ChatLobbyWidget::ChatLobbyWidget(QWidget *parent, Qt::WindowFlags flags) ui.splitter->setStretchFactor(1, 1); QList sizes; - sizes << 200*fact << width(); // Qt calculates the right sizes + sizes << ui.lobbyTreeWidget->columnWidth(COLUMN_NAME) << width(); // Qt calculates the right sizes ui.splitter->setSizes(sizes); lobbyChanged(); @@ -194,7 +206,6 @@ ChatLobbyWidget::ChatLobbyWidget(QWidget *parent, Qt::WindowFlags flags) // load settings processSettings(true); - int S = QFontMetricsF(font()).height(); QString help_str = tr("\

  Chat Rooms

\

Chat rooms work pretty much like IRC. \ @@ -212,11 +223,11 @@ ChatLobbyWidget::ChatLobbyWidget(QWidget *parent, Qt::WindowFlags flags) Note: For the chat rooms to work properly, your computer needs be on time. So check your system clock!\

\ " - ).arg(QString::number(2*S), QString::number(S)) ; + ).arg(QString::number(4*W), QString::number(2*W)) ; - registerHelpButton(ui.helpButton,help_str,"ChatLobbyDialog") ; - - ui.lobbyTreeWidget->setIconSize(QSize(S*1.5,S*1.5)); + registerHelpButton(ui.helpButton,help_str,"ChatLobbyDialog") ; + + ui.lobbyTreeWidget->setIconSize(QSize(H*1.5,H*1.5)); } ChatLobbyWidget::~ChatLobbyWidget() @@ -232,7 +243,7 @@ ChatLobbyWidget::~ChatLobbyWidget() UserNotify *ChatLobbyWidget::createUserNotify(QObject *parent) { myChatLobbyUserNotify = new ChatLobbyUserNotify(parent); - connect(myChatLobbyUserNotify, SIGNAL(countChanged(ChatLobbyId, uint)), this, SLOT(updateNotify(ChatLobbyId, uint))); + connect(myChatLobbyUserNotify, SIGNAL(countChanged(ChatLobbyId,uint)), this, SLOT(updateNotify(ChatLobbyId,uint))); return myChatLobbyUserNotify; } diff --git a/retroshare-gui/src/gui/ChatLobbyWidget.ui b/retroshare-gui/src/gui/ChatLobbyWidget.ui index 5a679189e..8f8e8f29d 100644 --- a/retroshare-gui/src/gui/ChatLobbyWidget.ui +++ b/retroshare-gui/src/gui/ChatLobbyWidget.ui @@ -102,7 +102,7 @@ Qt::NoFocus
- + :/icons/help_64.png:/icons/help_64.png @@ -191,6 +191,11 @@
+ + + 11 + + 16 @@ -459,7 +464,7 @@ LineEditClear QLineEdit -
gui/common/LineEditClear.h
+
gui/common/LineEditClear.h
RSTreeWidget @@ -468,7 +473,6 @@ - diff --git a/retroshare-gui/src/gui/Identity/IdDialog.cpp b/retroshare-gui/src/gui/Identity/IdDialog.cpp index 2585a286c..a7536b048 100644 --- a/retroshare-gui/src/gui/Identity/IdDialog.cpp +++ b/retroshare-gui/src/gui/Identity/IdDialog.cpp @@ -169,15 +169,18 @@ IdDialog::IdDialog(QWidget *parent) //connect(mCirclesBroadcastBase, SIGNAL(fillDisplay(bool)), this, SLOT(updateCirclesDisplay(bool))); ownItem = new QTreeWidgetItem(); - ownItem->setText(0, tr("My own identities")); + ownItem->setText(RSID_COL_NICKNAME, tr("My own identities")); + ownItem->setFont(RSID_COL_NICKNAME, ui->idTreeWidget->font()); ownItem->setData(RSID_COL_VOTES, Qt::DecorationRole,0xff); // this is in order to prevent displaying a reputaiton icon next to these items. allItem = new QTreeWidgetItem(); - allItem->setText(0, tr("All")); + allItem->setText(RSID_COL_NICKNAME, tr("All")); + allItem->setFont(RSID_COL_NICKNAME, ui->idTreeWidget->font()); allItem->setData(RSID_COL_VOTES, Qt::DecorationRole,0xff); contactsItem = new QTreeWidgetItem(); - contactsItem->setText(0, tr("My contacts")); + contactsItem->setText(RSID_COL_NICKNAME, tr("My contacts")); + contactsItem->setFont(RSID_COL_NICKNAME, ui->idTreeWidget->font()); contactsItem->setData(RSID_COL_VOTES, Qt::DecorationRole,0xff); @@ -366,6 +369,7 @@ IdDialog::IdDialog(QWidget *parent) ui->idTreeWidget->setColumnWidth(RSID_COL_IDTYPE, 18 * fontWidth); ui->idTreeWidget->setColumnWidth(RSID_COL_VOTES, 2 * fontWidth); + ui->idTreeWidget->setItemDelegate(new RSElidedItemDelegate()); ui->idTreeWidget->setItemDelegateForColumn( RSID_COL_NICKNAME, new GxsIdTreeItemDelegate()); @@ -648,15 +652,16 @@ void IdDialog::loadCircles(const std::list& groupInfo) if(!mExternalOtherCircleItem) { mExternalOtherCircleItem = new QTreeWidgetItem(); - mExternalOtherCircleItem->setText(0, tr("Other circles")); - + mExternalOtherCircleItem->setText(CIRCLEGROUP_CIRCLE_COL_GROUPNAME, tr("Other circles")); + mExternalOtherCircleItem->setFont(CIRCLEGROUP_CIRCLE_COL_GROUPNAME, ui->treeWidget_membership->font()); ui->treeWidget_membership->addTopLevelItem(mExternalOtherCircleItem); } if(!mExternalBelongingCircleItem ) { mExternalBelongingCircleItem = new QTreeWidgetItem(); - mExternalBelongingCircleItem->setText(0, tr("Circles I belong to")); + mExternalBelongingCircleItem->setText(CIRCLEGROUP_CIRCLE_COL_GROUPNAME, tr("Circles I belong to")); + mExternalBelongingCircleItem->setFont(CIRCLEGROUP_CIRCLE_COL_GROUPNAME, ui->treeWidget_membership->font()); ui->treeWidget_membership->addTopLevelItem(mExternalBelongingCircleItem); } #endif @@ -732,14 +737,11 @@ void IdDialog::loadCircles(const std::list& groupInfo) item->setToolTip(CIRCLEGROUP_CIRCLE_COL_GROUPNAME,tooltip); - if (am_I_admin) - { - QFont font = item->font(CIRCLEGROUP_CIRCLE_COL_GROUPNAME) ; - font.setBold(true) ; - item->setFont(CIRCLEGROUP_CIRCLE_COL_GROUPNAME,font) ; - item->setFont(CIRCLEGROUP_CIRCLE_COL_GROUPID,font) ; - item->setFont(CIRCLEGROUP_CIRCLE_COL_GROUPFLAGS,font) ; - } + QFont font = ui->treeWidget_membership->font() ; + font.setBold(am_I_admin) ; + item->setFont(CIRCLEGROUP_CIRCLE_COL_GROUPNAME,font) ; + item->setFont(CIRCLEGROUP_CIRCLE_COL_GROUPID,font) ; + item->setFont(CIRCLEGROUP_CIRCLE_COL_GROUPFLAGS,font) ; // now determine for this circle wether we have pending invites // we add a sub-item to the circle (to show the invite system info) in the following two cases: @@ -854,12 +856,10 @@ void IdDialog::loadCircles(const std::list& groupInfo) subitem->setData(CIRCLEGROUP_CIRCLE_COL_GROUPFLAGS, Qt::UserRole, QVariant(it->second)) ; subitem->setData(CIRCLEGROUP_CIRCLE_COL_GROUPID, Qt::UserRole, QString::fromStdString(it->first.toStdString())) ; - //subitem->setIcon(RSID_COL_NICKNAME, QIcon(pixmap)); - - new_sub_items.push_back(subitem); + new_sub_items.push_back(subitem); } - else - subitem = item->child(subitem_index); + else + subitem = item->child(subitem_index); if(invited && !subscrb) { @@ -878,15 +878,12 @@ void IdDialog::loadCircles(const std::list& groupInfo) if(invited && subscrb) subitem->setText(CIRCLEGROUP_CIRCLE_COL_GROUPID, tr("Member")) ; - if (is_own_id) - { - QFont font = subitem->font(CIRCLEGROUP_CIRCLE_COL_GROUPNAME) ; - font.setBold(true) ; - subitem->setFont(CIRCLEGROUP_CIRCLE_COL_GROUPNAME,font) ; - subitem->setFont(CIRCLEGROUP_CIRCLE_COL_GROUPID,font) ; - subitem->setFont(CIRCLEGROUP_CIRCLE_COL_GROUPFLAGS,font) ; - } - } + QFont font = ui->treeWidget_membership->font() ; + font.setBold(is_own_id) ; + subitem->setFont(CIRCLEGROUP_CIRCLE_COL_GROUPNAME,font) ; + subitem->setFont(CIRCLEGROUP_CIRCLE_COL_GROUPID,font) ; + subitem->setFont(CIRCLEGROUP_CIRCLE_COL_GROUPFLAGS,font) ; + } // add all items item->addChildren(new_sub_items); @@ -1389,73 +1386,42 @@ bool IdDialog::fillIdListItem(const RsGxsIdGroup& data, QTreeWidgetItem *&item, uint32_t item_flags = 0; /* do filtering */ - bool ok = false; if (data.mMeta.mGroupFlags & RSGXSID_GROUPFLAG_REALID_kept_for_compatibility) - { - if (isLinkedToOwnNode && (accept & RSID_FILTER_YOURSELF)) - { - ok = true; - item_flags |= RSID_FILTER_YOURSELF ; - } + { + if (isLinkedToOwnNode && (accept & RSID_FILTER_YOURSELF)) + item_flags |= RSID_FILTER_YOURSELF ; - if (data.mPgpKnown && (accept & RSID_FILTER_FRIENDS)) - { - ok = true; - item_flags |= RSID_FILTER_FRIENDS ; - } + if (data.mPgpKnown && (accept & RSID_FILTER_FRIENDS)) + item_flags |= RSID_FILTER_FRIENDS ; - if (accept & RSID_FILTER_OTHERS) - { - ok = true; - item_flags |= RSID_FILTER_OTHERS ; - } - } - else if (accept & RSID_FILTER_PSEUDONYMS) - { - ok = true; - item_flags |= RSID_FILTER_PSEUDONYMS ; - } + if (accept & RSID_FILTER_OTHERS) + item_flags |= RSID_FILTER_OTHERS ; + } + else if (accept & RSID_FILTER_PSEUDONYMS) + item_flags |= RSID_FILTER_PSEUDONYMS ; - if (isOwnId && (accept & RSID_FILTER_OWNED_BY_YOU)) - { - ok = true; - item_flags |= RSID_FILTER_OWNED_BY_YOU ; - } + if (isOwnId && (accept & RSID_FILTER_OWNED_BY_YOU)) + item_flags |= RSID_FILTER_OWNED_BY_YOU ; if (isBanned && (accept & RSID_FILTER_BANNED)) - { - ok = true; item_flags |= RSID_FILTER_BANNED ; - } - if (!ok) + if (item_flags == 0) return false; if (!item) - { - item = new TreeWidgetItem(); - } - + item = new TreeWidgetItem(); + item->setText(RSID_COL_NICKNAME, QString::fromUtf8(data.mMeta.mGroupName.c_str()).left(RSID_MAXIMUM_NICKNAME_SIZE)); item->setData(RSID_COL_NICKNAME, Qt::UserRole, QString::fromStdString(data.mMeta.mGroupId.toStdString())); item->setText(RSID_COL_KEYID, QString::fromStdString(data.mMeta.mGroupId.toStdString())); - if(isBanned) - { - //TODO (Phenom): Add qproperty for these text colors in stylesheets - item->setData(RSID_COL_NICKNAME, Qt::ForegroundRole, QColor(Qt::red)); - item->setData(RSID_COL_KEYID , Qt::ForegroundRole, QColor(Qt::red)); - item->setData(RSID_COL_IDTYPE , Qt::ForegroundRole, QColor(Qt::red)); - item->setData(RSID_COL_VOTES , Qt::ForegroundRole, QColor(Qt::red)); - } - else - { - item->setData(RSID_COL_NICKNAME, Qt::ForegroundRole, QVariant()); - item->setData(RSID_COL_KEYID , Qt::ForegroundRole, QVariant()); - item->setData(RSID_COL_IDTYPE , Qt::ForegroundRole, QVariant()); - item->setData(RSID_COL_VOTES , Qt::ForegroundRole, QVariant()); - } + //TODO (Phenom): Add qproperty for these text colors in stylesheets + item->setData(RSID_COL_NICKNAME, Qt::ForegroundRole, isBanned ? QColor(Qt::red) : QVariant() ); + item->setData(RSID_COL_KEYID , Qt::ForegroundRole, isBanned ? QColor(Qt::red) : QVariant() ); + item->setData(RSID_COL_IDTYPE , Qt::ForegroundRole, isBanned ? QColor(Qt::red) : QVariant() ); + item->setData(RSID_COL_VOTES , Qt::ForegroundRole, isBanned ? QColor(Qt::red) : QVariant() ); item->setData(RSID_COL_KEYID, Qt::UserRole,QVariant(item_flags)) ; item->setTextAlignment(RSID_COL_VOTES, Qt::AlignRight | Qt::AlignVCenter); @@ -1466,16 +1432,9 @@ bool IdDialog::fillIdListItem(const RsGxsIdGroup& data, QTreeWidgetItem *&item, RSID_COL_VOTES,SortRole, static_cast(idd.mReputation.mOverallReputationLevel)); - if(isOwnId) - { - QFont font = item->font(RSID_COL_NICKNAME) ; - - font.setBold(true) ; - item->setFont(RSID_COL_NICKNAME,font) ; - item->setFont(RSID_COL_IDTYPE,font) ; - item->setFont(RSID_COL_KEYID,font) ; - - QString tooltip = tr("This identity is owned by you"); + if(isOwnId) + { + QString tooltip = tr("This identity is owned by you"); if(idd.mFlags & RS_IDENTITY_FLAGS_IS_DEPRECATED) { @@ -1487,10 +1446,16 @@ bool IdDialog::fillIdListItem(const RsGxsIdGroup& data, QTreeWidgetItem *&item, tooltip += tr("\nThis identity has a unsecure fingerprint (It's probably quite old).\nYou should get rid of it now and use a new one.\nThese identities will soon be not supported anymore.") ; } - item->setToolTip(RSID_COL_NICKNAME, tooltip) ; - item->setToolTip(RSID_COL_KEYID, tooltip) ; - item->setToolTip(RSID_COL_IDTYPE, tooltip) ; - } + item->setToolTip(RSID_COL_NICKNAME, tooltip) ; + item->setToolTip(RSID_COL_KEYID, tooltip) ; + item->setToolTip(RSID_COL_IDTYPE, tooltip) ; + } + QFont font = ui->idTreeWidget->font() ; + font.setBold(isOwnId) ; + item->setFont(RSID_COL_NICKNAME,font) ; + item->setFont(RSID_COL_IDTYPE,font) ; + item->setFont(RSID_COL_KEYID,font) ; + //QPixmap pixmap ; // @@ -1501,8 +1466,6 @@ bool IdDialog::fillIdListItem(const RsGxsIdGroup& data, QTreeWidgetItem *&item, // Icon Place Holder item->setIcon(RSID_COL_NICKNAME,FilesDefs::getIconFromQtResourcePath(":/icons/png/anonymous.png")); - QString tooltip; - if (data.mMeta.mGroupFlags & RSGXSID_GROUPFLAG_REALID_kept_for_compatibility) { if (data.mPgpKnown) @@ -1513,25 +1476,25 @@ bool IdDialog::fillIdListItem(const RsGxsIdGroup& data, QTreeWidgetItem *&item, item->setToolTip(RSID_COL_IDTYPE,"Verified signature from node "+QString::fromStdString(data.mPgpId.toStdString())) ; - tooltip += tr("Node name:")+" " + QString::fromUtf8(details.name.c_str()) + "\n"; - tooltip += tr("Node Id :")+" " + QString::fromStdString(data.mPgpId.toStdString()) ; + QString tooltip = tr("Node name:")+" " + QString::fromUtf8(details.name.c_str()) + "\n"; + tooltip += tr("Node Id :")+" " + QString::fromStdString(data.mPgpId.toStdString()) ; item->setToolTip(RSID_COL_KEYID,tooltip) ; } else { - QString txt = tr("[Unknown node]"); + QString txt = tr("[Unknown node]"); item->setText(RSID_COL_IDTYPE, txt); - - if(!data.mPgpId.isNull()) - { - item->setToolTip(RSID_COL_IDTYPE,tr("Unverified signature from node ")+QString::fromStdString(data.mPgpId.toStdString())) ; - item->setToolTip(RSID_COL_KEYID,tr("Unverified signature from node ")+QString::fromStdString(data.mPgpId.toStdString())) ; - } - else - { - item->setToolTip(RSID_COL_IDTYPE,tr("Unchecked signature")) ; - item->setToolTip(RSID_COL_KEYID,tr("Unchecked signature")) ; - } + + if(!data.mPgpId.isNull()) + { + item->setToolTip(RSID_COL_IDTYPE,tr("Unverified signature from node ")+QString::fromStdString(data.mPgpId.toStdString())) ; + item->setToolTip(RSID_COL_KEYID,tr("Unverified signature from node ")+QString::fromStdString(data.mPgpId.toStdString())) ; + } + else + { + item->setToolTip(RSID_COL_IDTYPE,tr("Unchecked signature")) ; + item->setToolTip(RSID_COL_KEYID,tr("Unchecked signature")) ; + } } } else @@ -2224,8 +2187,9 @@ void IdDialog::IdListCustomPopupMenu( QPoint ) if(!one_item_owned_by_you) { - QWidget *widget = new QWidget(contextMenu); - widget->setStyleSheet( ".QWidget{background-color: qlineargradient(x1:0, y1:0, x2:0, y2:1,stop:0 #FEFEFE, stop:1 #E8E8E8); border: 1px solid #CCCCCC;}"); + QFrame *widget = new QFrame(contextMenu); + widget->setObjectName("gradFrame"); //Use qss + //widget->setStyleSheet( ".QWidget{background-color: qlineargradient(x1:0, y1:0, x2:0, y2:1,stop:0 #FEFEFE, stop:1 #E8E8E8); border: 1px solid #CCCCCC;}"); // create menu header QHBoxLayout *hbox = new QHBoxLayout(widget); @@ -2233,12 +2197,14 @@ void IdDialog::IdListCustomPopupMenu( QPoint ) hbox->setSpacing(6); QLabel *iconLabel = new QLabel(widget); - QPixmap pix = FilesDefs::getPixmapFromQtResourcePath(":/images/user/friends24.png").scaledToHeight(QFontMetricsF(iconLabel->font()).height()*1.5); + iconLabel->setObjectName("trans_Icon"); + QPixmap pix = FilesDefs::getPixmapFromQtResourcePath(":/images/user/friends24.png").scaledToHeight(QFontMetricsF(iconLabel->font()).height()*1.5); iconLabel->setPixmap(pix); iconLabel->setMaximumSize(iconLabel->frameSize().height() + pix.height(), pix.width()); hbox->addWidget(iconLabel); QLabel *textLabel = new QLabel("" + ui->titleBarLabel->text() + "", widget); + textLabel->setObjectName("trans_Text"); hbox->addWidget(textLabel); QSpacerItem *spacerItem = new QSpacerItem(40, 20, QSizePolicy::Expanding, QSizePolicy::Minimum); diff --git a/retroshare-gui/src/gui/Identity/IdDialog.ui b/retroshare-gui/src/gui/Identity/IdDialog.ui index 7b16da166..8e40da52b 100644 --- a/retroshare-gui/src/gui/Identity/IdDialog.ui +++ b/retroshare-gui/src/gui/Identity/IdDialog.ui @@ -218,6 +218,11 @@ 0
+ + + 11 + + Qt::CustomContextMenu @@ -1046,6 +1051,11 @@ border-image: url(:/images/closepressed.png)
+ + + 11 + + Qt::CustomContextMenu diff --git a/retroshare-gui/src/gui/common/ElidedLabel.cpp b/retroshare-gui/src/gui/common/ElidedLabel.cpp index c444c8113..e44927df3 100644 --- a/retroshare-gui/src/gui/common/ElidedLabel.cpp +++ b/retroshare-gui/src/gui/common/ElidedLabel.cpp @@ -126,7 +126,11 @@ bool ElidedLabel::paintElidedLine( QPainter* painter, QString plainText to.setWrapMode(wordWrap ? QTextOption::WrapAtWordBoundaryOrAnywhere : QTextOption::NoWrap); textLayout.setTextOption(to); - if (painter) painter->save(); + if (painter) + { + painter->save(); + painter->setFont(useFont); + } textLayout.beginLayout(); forever { //Get new line for text. @@ -220,10 +224,7 @@ bool ElidedLabel::paintElidedLine( QPainter* painter, QString plainText if(width+iTransX+cr.left() <= cr.right()) if (painter) - { - painter->setFont(useFont); painter->drawText(QPoint(iTransX + cr.left(), y + fontMetrics.ascent() + cr.top()), elidedLastLine); - } //Draw button to get ToolTip #if QT_VERSION < QT_VERSION_CHECK(5,11,0) diff --git a/retroshare-gui/src/gui/common/FriendList.cpp b/retroshare-gui/src/gui/common/FriendList.cpp index 531a87f63..303b34356 100644 --- a/retroshare-gui/src/gui/common/FriendList.cpp +++ b/retroshare-gui/src/gui/common/FriendList.cpp @@ -55,6 +55,7 @@ #include "gui/chat/ChatUserNotify.h" #include "gui/connect/ConnectProgressDialog.h" #include "gui/common/ElidedLabel.h" +#include "gui/common/FilesDefs.h" #include "FriendList.h" #include "ui_FriendList.h" @@ -297,8 +298,9 @@ void FriendList::peerTreeWidgetCustomPopupMenu() QMenu *contextMenu = new QMenu(this); - QWidget *widget = new QWidget(contextMenu); - widget->setStyleSheet( ".QWidget{background-color: qlineargradient(x1:0, y1:0, x2:0, y2:1,stop:0 #FEFEFE, stop:1 #E8E8E8); border: 1px solid #CCCCCC;}"); + QFrame *widget = new QFrame(contextMenu); + widget->setObjectName("gradFrame"); //Use qss + //widget->setStyleSheet( ".QWidget{background-color: qlineargradient(x1:0, y1:0, x2:0, y2:1,stop:0 #FEFEFE, stop:1 #E8E8E8); border: 1px solid #CCCCCC;}"); // create menu header QHBoxLayout *hbox = new QHBoxLayout(widget); @@ -306,12 +308,14 @@ void FriendList::peerTreeWidgetCustomPopupMenu() hbox->setSpacing(6); QLabel *iconLabel = new QLabel(widget); + iconLabel->setObjectName("trans_Icon"); QPixmap pix = FilesDefs::getPixmapFromQtResourcePath(":/images/user/friends24.png").scaledToHeight(QFontMetricsF(iconLabel->font()).height()*1.5); iconLabel->setPixmap(pix); iconLabel->setMaximumSize(iconLabel->frameSize().height() + pix.height(), pix.width()); hbox->addWidget(iconLabel); QLabel *textLabel = new QLabel("RetroShare", widget); + textLabel->setObjectName("trans_Text"); hbox->addWidget(textLabel); QSpacerItem *spacerItem = new QSpacerItem(40, 20, QSizePolicy::Expanding, QSizePolicy::Minimum); diff --git a/retroshare-gui/src/gui/common/GroupTreeWidget.cpp b/retroshare-gui/src/gui/common/GroupTreeWidget.cpp index 685c54169..0597a652c 100644 --- a/retroshare-gui/src/gui/common/GroupTreeWidget.cpp +++ b/retroshare-gui/src/gui/common/GroupTreeWidget.cpp @@ -60,16 +60,25 @@ GroupTreeWidget::GroupTreeWidget(QWidget *parent) : connect(ui->filterLineEdit, SIGNAL(filterChanged(int)), this, SLOT(filterChanged())); connect(ui->treeWidget, SIGNAL(customContextMenuRequested(QPoint)), this, SLOT(customContextMenuRequested(QPoint))); - connect(ui->treeWidget, SIGNAL(currentItemChanged(QTreeWidgetItem*, QTreeWidgetItem*)), this, SLOT(currentItemChanged(QTreeWidgetItem*, QTreeWidgetItem*))); + connect(ui->treeWidget, SIGNAL(currentItemChanged(QTreeWidgetItem*,QTreeWidgetItem*)), this, SLOT(currentItemChanged(QTreeWidgetItem*,QTreeWidgetItem*))); connect(ui->treeWidget, SIGNAL(itemActivated(QTreeWidgetItem*,int)), this, SLOT(itemActivated(QTreeWidgetItem*,int))); if (!style()->styleHint(QStyle::SH_ItemView_ActivateItemOnSingleClick, NULL, this)) { // need signal itemClicked too connect(ui->treeWidget, SIGNAL(itemClicked(QTreeWidgetItem*,int)), this, SLOT(itemActivated(QTreeWidgetItem*,int))); } + int H = QFontMetricsF(ui->treeWidget->font()).height() ; +#if QT_VERSION < QT_VERSION_CHECK(5,11,0) + int W = QFontMetricsF(ui->treeWidget->font()).width("_") ; + int D = QFontMetricsF(ui->treeWidget->font()).width("9999-99-99[]") ; +#else + int W = QFontMetricsF(ui->treeWidget->font()).horizontalAdvance("_") ; + int D = QFontMetricsF(ui->treeWidget->font()).horizontalAdvance("9999-99-99[]") ; +#endif + /* Add own item delegate */ RSElidedItemDelegate *itemDelegate = new RSElidedItemDelegate(this); - itemDelegate->setSpacing(QSize(0, 2)); + itemDelegate->setSpacing(QSize(W/2, H/4)); ui->treeWidget->setItemDelegate(itemDelegate); /* Set compare role for each column */ @@ -87,10 +96,6 @@ GroupTreeWidget::GroupTreeWidget(QWidget *parent) : ui->treeWidget->enableColumnCustomize(true); ui->treeWidget->setColumnCustomizable(GTW_COLUMN_NAME, false); - int S = QFontMetricsF(font()).height() ; - int W = QFontMetricsF(font()).width("_") ; - int D = QFontMetricsF(font()).width("9999-99-99[]") ; - QTreeWidgetItem *headerItem = ui->treeWidget->headerItem(); headerItem->setText(GTW_COLUMN_NAME, tr("Name")); headerItem->setText(GTW_COLUMN_UNREAD, ""); @@ -143,7 +148,7 @@ GroupTreeWidget::GroupTreeWidget(QWidget *parent) : connect(ui->distantSearchLineEdit,SIGNAL(returnPressed()),this,SLOT(distantSearch())) ; - ui->treeWidget->setIconSize(QSize(S*1.8,S*1.8)); + ui->treeWidget->setIconSize(QSize(H*1.8,H*1.8)); } GroupTreeWidget::~GroupTreeWidget() @@ -205,9 +210,9 @@ void GroupTreeWidget::updateColors() int color = item->data(GTW_COLUMN_DATA, ROLE_COLOR).toInt(); if (color >= 0) { - item->setData(GTW_COLUMN_NAME, Qt::TextColorRole, mTextColor[color]); + item->setData(GTW_COLUMN_NAME, Qt::ForegroundRole, mTextColor[color]); } else { - item->setData(GTW_COLUMN_NAME, Qt::TextColorRole, QVariant()); + item->setData(GTW_COLUMN_NAME, Qt::ForegroundRole, QVariant()); } } @@ -246,7 +251,6 @@ void GroupTreeWidget::itemActivated(QTreeWidgetItem *item, int column) QTreeWidgetItem *GroupTreeWidget::addCategoryItem(const QString &name, const QIcon &icon, bool expand, int sortOrder /*= -1*/) { - QFont font; RSTreeWidgetItem *item = new RSTreeWidgetItem(); ui->treeWidget->addTopLevelItem(item); // To get StyleSheet for Items @@ -255,15 +259,16 @@ QTreeWidgetItem *GroupTreeWidget::addCategoryItem(const QString &name, const QIc item->setText(GTW_COLUMN_NAME, name); item->setData(GTW_COLUMN_DATA, ROLE_NAME, name); - font = item->font(GTW_COLUMN_NAME); - font.setBold(true); - item->setFont(GTW_COLUMN_NAME, font); + QFont itFont = item->font(GTW_COLUMN_NAME); + itFont.setBold(true); + itFont.setPointSize(ui->treeWidget->font().pointSize()); //use treeWidget font size defined in ui. + item->setFont(GTW_COLUMN_NAME, itFont); item->setIcon(GTW_COLUMN_NAME, icon); - int S = QFontMetricsF(font).height(); + //int S = QFontMetricsF(itFont).height(); - item->setSizeHint(GTW_COLUMN_NAME, QSize(S*1.9, S*1.9)); - item->setData(GTW_COLUMN_NAME, Qt::TextColorRole, textColorCategory()); + //item->setSizeHint(GTW_COLUMN_NAME, QSize(S*1.9, S*1.9)); //size hint is calculated by item delegate. Use itemDelegate->setSpacing() in constructor. + item->setData(GTW_COLUMN_NAME, Qt::ForegroundRole, textColorCategory()); item->setData(GTW_COLUMN_DATA, ROLE_COLOR, GROUPTREEWIDGET_COLOR_CATEGORY); item->setExpanded(expand); @@ -385,6 +390,7 @@ void GroupTreeWidget::fillGroupItems(QTreeWidgetItem *categoryItem, const QList< if (item == NULL) { item = new RSTreeWidgetItem(compareRole); item->setData(GTW_COLUMN_DATA, ROLE_ID, itemInfo.id); + item->setFont(GTW_COLUMN_DATA, ui->treeWidget->font()); //static_cast(item)->setNoDataAsLast(true); //Uncomment this to sort data with QVariant() always at end. categoryItem->addChild(item); } @@ -506,18 +512,18 @@ void GroupTreeWidget::setUnreadCount(QTreeWidgetItem *item, int unreadCount) return; } - QFont font = item->font(GTW_COLUMN_NAME); + QFont itFont = item->font(GTW_COLUMN_NAME); if (unreadCount) { item->setText(GTW_COLUMN_UNREAD, QString::number(unreadCount)); - font.setBold(true); + itFont.setBold(true); } else { item->setText(GTW_COLUMN_UNREAD, ""); - font.setBold(false); + itFont.setBold(false); } item->setData(GTW_COLUMN_UNREAD, ROLE_SORT, unreadCount); - item->setFont(GTW_COLUMN_NAME, font); + item->setFont(GTW_COLUMN_NAME, itFont); } QTreeWidgetItem *GroupTreeWidget::getItemFromId(const QString &id) diff --git a/retroshare-gui/src/gui/common/GroupTreeWidget.ui b/retroshare-gui/src/gui/common/GroupTreeWidget.ui index f925cf8ed..d3e0a14a5 100644 --- a/retroshare-gui/src/gui/common/GroupTreeWidget.ui +++ b/retroshare-gui/src/gui/common/GroupTreeWidget.ui @@ -70,6 +70,11 @@ 0 + + + 11 + + Qt::CustomContextMenu diff --git a/retroshare-gui/src/gui/common/NewFriendList.cpp b/retroshare-gui/src/gui/common/NewFriendList.cpp index d151c6430..37b1511f8 100644 --- a/retroshare-gui/src/gui/common/NewFriendList.cpp +++ b/retroshare-gui/src/gui/common/NewFriendList.cpp @@ -184,6 +184,13 @@ NewFriendList::NewFriendList(QWidget */*parent*/) : /* RsAutoUpdatePage(5000,par { ui->setupUi(this); + int H = QFontMetricsF(ui->peerTreeWidget->font()).height(); +#if QT_VERSION < QT_VERSION_CHECK(5,11,0) + int W = QFontMetricsF(ui->peerTreeWidget->font()).width("_"); +#else + int W = QFontMetricsF(ui->peerTreeWidget->font()).horizontalAdvance("_"); +#endif + ui->filterLineEdit->setPlaceholderText(tr("Search")) ; ui->filterLineEdit->showFilterIcon(); @@ -205,7 +212,9 @@ NewFriendList::NewFriendList(QWidget */*parent*/) : /* RsAutoUpdatePage(5000,par mProxyModel->setFilterRegExp(QRegExp(RsFriendListModel::FilterString)); ui->peerTreeWidget->setModel(mProxyModel); - ui->peerTreeWidget->setItemDelegate(new RSElidedItemDelegate()); + RSElidedItemDelegate *itemDelegate = new RSElidedItemDelegate(this); + itemDelegate->setSpacing(QSize(W/2, H/4)); + ui->peerTreeWidget->setItemDelegate(itemDelegate); ui->peerTreeWidget->setWordWrap(false); /* Add filter actions */ @@ -228,17 +237,13 @@ NewFriendList::NewFriendList(QWidget */*parent*/) : /* RsAutoUpdatePage(5000,par QShortcut *Shortcut = new QShortcut(QKeySequence(Qt::Key_Delete), ui->peerTreeWidget, 0, 0, Qt::WidgetShortcut); connect(Shortcut, SIGNAL(activated()), this, SLOT(removeItem()),Qt::QueuedConnection); - QFontMetricsF fontMetrics(ui->peerTreeWidget->font()); + /* Set initial column width */ + ui->peerTreeWidget->setColumnWidth(RsFriendListModel::COLUMN_THREAD_NAME , 22 * W); + ui->peerTreeWidget->setColumnWidth(RsFriendListModel::COLUMN_THREAD_IP , 15 * W); + ui->peerTreeWidget->setColumnWidth(RsFriendListModel::COLUMN_THREAD_ID , 32 * W); + ui->peerTreeWidget->setColumnWidth(RsFriendListModel::COLUMN_THREAD_LAST_CONTACT, 12 * W); - /* Set initial column width */ - int fontWidth = fontMetrics.width("W"); - ui->peerTreeWidget->setColumnWidth(RsFriendListModel::COLUMN_THREAD_NAME , 22 * fontWidth); - ui->peerTreeWidget->setColumnWidth(RsFriendListModel::COLUMN_THREAD_IP , 15 * fontWidth); - ui->peerTreeWidget->setColumnWidth(RsFriendListModel::COLUMN_THREAD_ID , 32 * fontWidth); - ui->peerTreeWidget->setColumnWidth(RsFriendListModel::COLUMN_THREAD_LAST_CONTACT, 12 * fontWidth); - - int avatarHeight = fontMetrics.height() * 2; - ui->peerTreeWidget->setIconSize(QSize(avatarHeight, avatarHeight)); + ui->peerTreeWidget->setIconSize(QSize(H*2, H*2)); mModel->checkInternalData(true); @@ -301,8 +306,9 @@ void NewFriendList::headerContextMenuRequested(QPoint /*p*/) { QMenu displayMenu(tr("Show Items"), this); - QWidget *widget = new QWidget(&displayMenu); - widget->setStyleSheet( ".QWidget{background-color: qlineargradient(x1:0, y1:0, x2:0, y2:1,stop:0 #FEFEFE, stop:1 #E8E8E8); border: 1px solid #CCCCCC;}"); + QFrame *widget = new QFrame(&displayMenu); + widget->setObjectName("gradFrame"); //Use qss + //widget->setStyleSheet( ".QWidget{background-color: qlineargradient(x1:0, y1:0, x2:0, y2:1,stop:0 #FEFEFE, stop:1 #E8E8E8); border: 1px solid #CCCCCC;}"); // create menu header QHBoxLayout *hbox = new QHBoxLayout(widget); @@ -310,12 +316,14 @@ void NewFriendList::headerContextMenuRequested(QPoint /*p*/) hbox->setSpacing(6); QLabel *iconLabel = new QLabel(widget); + iconLabel->setObjectName("trans_Icon"); QPixmap pix = FilesDefs::getPixmapFromQtResourcePath(":/images/user/friends24.png").scaledToHeight(QFontMetricsF(iconLabel->font()).height()*1.5); iconLabel->setPixmap(pix); iconLabel->setMaximumSize(iconLabel->frameSize().height() + pix.height(), pix.width()); hbox->addWidget(iconLabel); QLabel *textLabel = new QLabel("Show/hide...", widget); + textLabel->setObjectName("trans_Text"); hbox->addWidget(textLabel); QSpacerItem *spacerItem = new QSpacerItem(40, 20, QSizePolicy::Expanding, QSizePolicy::Minimum); @@ -564,8 +572,9 @@ void NewFriendList::peerTreeWidgetCustomPopupMenu() QMenu contextMenu(this); - QWidget *widget = new QWidget(&contextMenu); - widget->setStyleSheet( ".QWidget{background-color: qlineargradient(x1:0, y1:0, x2:0, y2:1,stop:0 #FEFEFE, stop:1 #E8E8E8); border: 1px solid #CCCCCC;}"); + QFrame *widget = new QFrame(); + widget->setObjectName("gradFrame"); //Use qss + //widget->setStyleSheet( ".QWidget{background-color: qlineargradient(x1:0, y1:0, x2:0, y2:1,stop:0 #FEFEFE, stop:1 #E8E8E8); border: 1px solid #CCCCCC;}"); // create menu header QHBoxLayout *hbox = new QHBoxLayout(widget); @@ -573,12 +582,14 @@ void NewFriendList::peerTreeWidgetCustomPopupMenu() hbox->setSpacing(6); QLabel *iconLabel = new QLabel(widget); + iconLabel->setObjectName("trans_Icon"); QPixmap pix = FilesDefs::getPixmapFromQtResourcePath(":/images/user/friends24.png").scaledToHeight(QFontMetricsF(iconLabel->font()).height()*1.5); iconLabel->setPixmap(pix); iconLabel->setMaximumSize(iconLabel->frameSize().height() + pix.height(), pix.width()); hbox->addWidget(iconLabel); QLabel *textLabel = new QLabel("Friend list", widget); + textLabel->setObjectName("trans_Text"); hbox->addWidget(textLabel); QSpacerItem *spacerItem = new QSpacerItem(40, 20, QSizePolicy::Expanding, QSizePolicy::Minimum); diff --git a/retroshare-gui/src/gui/common/RSElidedItemDelegate.cpp b/retroshare-gui/src/gui/common/RSElidedItemDelegate.cpp index eb017a033..80f37befc 100644 --- a/retroshare-gui/src/gui/common/RSElidedItemDelegate.cpp +++ b/retroshare-gui/src/gui/common/RSElidedItemDelegate.cpp @@ -51,7 +51,7 @@ QTreeView::item:hover, QTreeWidget::item:hover, QListWidget::item:hover{ color: #0000EF; background-color: #FEDCBA; } -QQTreeView::item:selected:hover, TreeWidget::item:selected:hover, QListWidget::item:selected:hover{ +QTreeView::item:selected:hover, QTreeWidget::item:selected:hover, QListWidget::item:selected:hover{ color: #ABCDEF; background-color: #FE0000; } @@ -88,7 +88,12 @@ QSize RSElidedItemDelegate::sizeHint(const QStyleOptionViewItem &option, const Q QSize contSize = ownStyle->sizeFromContents( QStyle::CT_ItemViewItem,&ownOption ,QSize( checkRect.width()+iconRect.width()+textRect.width() - ,qMax(checkRect.height(),qMax(iconRect.height(),textRect.height()))),widget); + , qMax(checkRect.height(),qMax(iconRect.height(),textRect.height())) + ), widget ) ; + + contSize += QSize( 2*spacing().width() + , qMax(checkRect.height(),iconRect.height()) > textRect.height() + ? 0 : 2*spacing().height() ); return contSize; } @@ -97,7 +102,7 @@ inline QColor getImagePixelColor(QImage img, int x, int y) { #if QT_VERSION >= QT_VERSION_CHECK(5,6,0) #ifdef DEBUG_EID_PAINT -// RsDbg() << " RSEID: Found Color " << img.pixelColor(x,y).name(QColor::HexArgb).toStdString() << " at " << x << "," << y << std::endl; + //RsDbg(" RSEID: Found Color ", img.pixelColor(x,y).name(QColor::HexArgb).toStdString(), " at ", x, ",", y); #endif return img.pixelColor(x,y); #else @@ -109,7 +114,7 @@ void RSElidedItemDelegate::paint(QPainter *painter, const QStyleOptionViewItem & { if(!index.isValid()) { - RsErr() << __PRETTY_FUNCTION__ << " attempt to draw an invalid index." << std::endl; + RS_ERR(" attempt to draw an invalid index."); return ; } painter->save(); @@ -120,7 +125,7 @@ void RSElidedItemDelegate::paint(QPainter *painter, const QStyleOptionViewItem & ownOption.icon = option.icon; #ifdef DEBUG_EID_PAINT - RsDbg() << __PRETTY_FUNCTION__ << std::endl << " RSEID: Enter for item with text:" << ownOption.text.toStdString() << std::endl; + RS_DBG("\n RSEID: Enter for item with text:", ownOption.text.toStdString()); #endif const QWidget* widget = option.widget; @@ -139,16 +144,16 @@ void RSElidedItemDelegate::paint(QPainter *painter, const QStyleOptionViewItem & ownOption.fontMetrics = QFontMetrics(font); #ifdef DEBUG_EID_PAINT QFontInfo info(font); - RsDbg() << " RSEID: Found font in model:" << info.family().toStdString() << std::endl; + RsDbg(" RSEID: Found font in model:", info.family().toStdString()); #endif } // Get Text color from model if one exists QColor textColor; - if (index.data(Qt::TextColorRole).isValid()) { + if (index.data(Qt::ForegroundRole).isValid()) { //textColor = QColor(index.data(Qt::TextColorRole).toString());//Needs to pass from string else loose RBG format. - textColor = index.data(Qt::TextColorRole).value(); + textColor = index.data(Qt::ForegroundRole).value(); #ifdef DEBUG_EID_PAINT - RsDbg() << " RSEID: Found text color in model:" << textColor.name().toStdString() << std::endl; + RsDbg(" RSEID: Found text color in model:", textColor.name().toStdString()); #endif } // Get Brush from model if one exists @@ -157,7 +162,7 @@ void RSElidedItemDelegate::paint(QPainter *painter, const QStyleOptionViewItem & if (index.data(Qt::BackgroundRole).isValid()) { bgBrush = index.data(Qt::BackgroundRole).value(); #ifdef DEBUG_EID_PAINT - RsDbg() << " RSEID: Found bg brush in model:" << bgBrush.color().name().toStdString() << std::endl; + RsDbg(" RSEID: Found bg brush in model:", bgBrush.color().name().toStdString()); #endif } @@ -165,10 +170,10 @@ void RSElidedItemDelegate::paint(QPainter *painter, const QStyleOptionViewItem & if ( (bgBrush.color().spec()==QColor::Invalid) || (textColor.spec()!=QColor::Invalid) ) { #ifdef DEBUG_EID_PAINT - RsDbg() << " RSEID:" - << ((bgBrush.color().spec()==QColor::Invalid) ? " Brush not defined" : "") - << ((textColor.spec()==QColor::Invalid) ? " Text Color not defined" : "") - << " so get it from base image." << std::endl; + RsDbg( " RSEID:" + , ((bgBrush.color().spec()==QColor::Invalid) ? " Brush not defined" : "") + , ((textColor.spec()==QColor::Invalid) ? " Text Color not defined" : "") + , " so get it from base image."); #endif // QPalette is not updated by StyleSheet all occurs in internal class. (QRenderRule) // https://code.woboq.org/qt5/qtbase/src/widgets/styles/qstylesheetstyle.cpp.html#4138 @@ -179,7 +184,7 @@ void RSElidedItemDelegate::paint(QPainter *painter, const QStyleOptionViewItem & if (moSize.width() <= 20) moSize.setWidth(20); #ifdef DEBUG_EID_PAINT - RsDbg() << " RSEID: for item size = " << moSize.width() << "x" << moSize.height() << std::endl; + RsDbg(" RSEID: for item size = ", moSize.width(), "x", moSize.height()); #endif QImage moImg(moSize,QImage::Format_ARGB32); @@ -268,14 +273,14 @@ void RSElidedItemDelegate::paint(QPainter *painter, const QStyleOptionViewItem & { bgBrush = QBrush(moBGColor); #ifdef DEBUG_EID_PAINT - RsDbg() << " RSEID: bg brush setted to " << moBGColor.name(QColor::HexArgb).toStdString() << std::endl; + RsDbg(" RSEID: bg brush setted to ", moBGColor.name(QColor::HexArgb).toStdString()); #endif } if (textColor.spec()==QColor::Invalid) { textColor = moColor; #ifdef DEBUG_EID_PAINT - RsDbg() << " RSEID: text color setted to " << moColor.name(QColor::HexArgb).toStdString() << std::endl; + RsDbg(" RSEID: text color setted to ", moColor.name(QColor::HexArgb).toStdString()); #endif } } @@ -389,7 +394,7 @@ void RSElidedItemDelegate::paint(QPainter *painter, const QStyleOptionViewItem & } painter->restore(); #ifdef DEBUG_EID_PAINT - RsDbg() << " RSEID: Finished" << std::endl; + RsDbg(" RSEID: Finished"); #endif } diff --git a/retroshare-gui/src/gui/common/RSTreeWidget.cpp b/retroshare-gui/src/gui/common/RSTreeWidget.cpp index 09ef481f6..9c91c5f2e 100644 --- a/retroshare-gui/src/gui/common/RSTreeWidget.cpp +++ b/retroshare-gui/src/gui/common/RSTreeWidget.cpp @@ -253,8 +253,9 @@ QMenu *RSTreeWidget::createStandardContextMenu(QMenu *contextMenu) } if(!mContextMenuActions.isEmpty() || !mContextMenuMenus.isEmpty() || mEnableColumnCustomize) { - QWidget *widget = new QWidget(contextMenu); - widget->setStyleSheet( ".QWidget{background-color: qlineargradient(x1:0, y1:0, x2:0, y2:1,stop:0 #FEFEFE, stop:1 #E8E8E8); border: 1px solid #CCCCCC;}"); + QFrame *widget = new QFrame(contextMenu); + widget->setObjectName("gradFrame"); //Use qss + //widget->setStyleSheet( ".QWidget{background-color: qlineargradient(x1:0, y1:0, x2:0, y2:1,stop:0 #FEFEFE, stop:1 #E8E8E8); border: 1px solid #CCCCCC;}"); // create menu header QHBoxLayout *hbox = new QHBoxLayout(widget); @@ -262,12 +263,14 @@ QMenu *RSTreeWidget::createStandardContextMenu(QMenu *contextMenu) hbox->setSpacing(6); QLabel *iconLabel = new QLabel(widget); - QPixmap pix = FilesDefs::getPixmapFromQtResourcePath(":/images/settings.png").scaledToHeight(QFontMetricsF(iconLabel->font()).height()*1.5); + iconLabel->setObjectName("trans_Icon"); + QPixmap pix = FilesDefs::getPixmapFromQtResourcePath(":/images/settings.png").scaledToHeight(QFontMetricsF(iconLabel->font()).height()*1.5); iconLabel->setPixmap(pix); iconLabel->setMaximumSize(iconLabel->frameSize().height() + pix.height(), pix.width()); hbox->addWidget(iconLabel); QLabel *textLabel = new QLabel("" + tr("Tree View Options") + "", widget); + textLabel->setObjectName("trans_Text"); hbox->addWidget(textLabel); QSpacerItem *spacerItem = new QSpacerItem(40, 20, QSizePolicy::Expanding, QSizePolicy::Minimum); From 153a5bddcf4929ca5dbe0448edbd8150965f4664 Mon Sep 17 00:00:00 2001 From: defnax Date: Sun, 26 Dec 2021 16:17:36 +0100 Subject: [PATCH 093/113] Fixing wire layout spacing * Fixing wire layout spacing * Added splitter for wiki group --- .../src/gui/TheWire/PulseAddDialog.ui | 9 +++ .../src/gui/TheWire/PulseMessage.ui | 5 +- retroshare-gui/src/gui/TheWire/PulseReply.ui | 28 ++++++++- retroshare-gui/src/gui/WikiPoos/WikiDialog.ui | 63 ++++++++++++------- 4 files changed, 78 insertions(+), 27 deletions(-) diff --git a/retroshare-gui/src/gui/TheWire/PulseAddDialog.ui b/retroshare-gui/src/gui/TheWire/PulseAddDialog.ui index 940d8f895..a731ec3b0 100644 --- a/retroshare-gui/src/gui/TheWire/PulseAddDialog.ui +++ b/retroshare-gui/src/gui/TheWire/PulseAddDialog.ui @@ -35,6 +35,9 @@ + + 0 + 0 @@ -232,9 +235,15 @@ + + 0 + 0 + + 0 + diff --git a/retroshare-gui/src/gui/TheWire/PulseMessage.ui b/retroshare-gui/src/gui/TheWire/PulseMessage.ui index 8af226cea..09b64f780 100644 --- a/retroshare-gui/src/gui/TheWire/PulseMessage.ui +++ b/retroshare-gui/src/gui/TheWire/PulseMessage.ui @@ -14,6 +14,9 @@ Form + + 0 + @@ -53,7 +56,7 @@ MS Sans Serif - 10 + 11 diff --git a/retroshare-gui/src/gui/TheWire/PulseReply.ui b/retroshare-gui/src/gui/TheWire/PulseReply.ui index 3af469f63..3f85dc164 100644 --- a/retroshare-gui/src/gui/TheWire/PulseReply.ui +++ b/retroshare-gui/src/gui/TheWire/PulseReply.ui @@ -52,6 +52,9 @@ 0 + + 1 + @@ -149,6 +152,9 @@ + + 9 + 0 @@ -440,10 +446,22 @@ 0 - 40 + 0 + + 6 + + + 0 + + + 0 + + + 0 + @@ -611,13 +629,19 @@ 0 - 40 + 0 + + 6 + 0 + + 0 + 0 diff --git a/retroshare-gui/src/gui/WikiPoos/WikiDialog.ui b/retroshare-gui/src/gui/WikiPoos/WikiDialog.ui index 7a86e6488..056e0a859 100644 --- a/retroshare-gui/src/gui/WikiPoos/WikiDialog.ui +++ b/retroshare-gui/src/gui/WikiPoos/WikiDialog.ui @@ -50,7 +50,7 @@ 510 - + 0 @@ -63,33 +63,48 @@ 0 - - - - - 0 - 150 - + + + + Qt::Vertical - - - - - - - Page Name + + + + 0 + 0 + - - - - Page Id + + + 0 + 150 + - - - - Orig Id + + + + + 0 + 0 + - + + + Page Name + + + + + Page Id + + + + + Orig Id + + + From ffc42db3aa74463609a6aa07332f2427ae61cc2e Mon Sep 17 00:00:00 2001 From: thunder2 Date: Mon, 27 Dec 2021 16:38:29 +0100 Subject: [PATCH 094/113] 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 095/113] 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 096/113] 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 097/113] 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 098/113] 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 099/113] 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 100/113] 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 101/113] 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 102/113] 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 0ffb31be855ea165ed64de10109dd96b4ee441a7 Mon Sep 17 00:00:00 2001 From: thunder2 Date: Wed, 29 Dec 2021 13:56:31 +0100 Subject: [PATCH 103/113] Added missing initialization and check of members in VOIPConfigPanel to fix crash at shutdown with enabled plugin VOIP --- plugins/VOIP/gui/VOIPConfigPanel.cpp | 22 ++++++++++++++++------ 1 file changed, 16 insertions(+), 6 deletions(-) diff --git a/plugins/VOIP/gui/VOIPConfigPanel.cpp b/plugins/VOIP/gui/VOIPConfigPanel.cpp index a46169dcb..a9912af8b 100644 --- a/plugins/VOIP/gui/VOIPConfigPanel.cpp +++ b/plugins/VOIP/gui/VOIPConfigPanel.cpp @@ -92,6 +92,9 @@ VOIPConfigPanel::VOIPConfigPanel(QWidget * parent, Qt::WindowFlags flags) inputAudioProcessor = NULL; inputAudioDevice = NULL; + graph_source = nullptr; + videoInput = nullptr; + videoProcessor = nullptr; qtTick = NULL; ui.qcbTransmit->addItem(tr("Continuous"), RsVOIP::AudioTransmitContinous); @@ -209,11 +212,16 @@ VOIPConfigPanel::~VOIPConfigPanel() void VOIPConfigPanel::clearPipeline() { - delete qtTick; + if (qtTick) { + delete qtTick; + qtTick = nullptr; + } - graph_source->stop() ; - graph_source->setVideoInput(NULL) ; - graph_source=nullptr; // is deleted by setSource below. This is a bad design. + if (graph_source) { + graph_source->stop() ; + graph_source->setVideoInput(NULL) ; + graph_source=nullptr; // is deleted by setSource below. This is a bad design. + } ui.voipBwGraph->setSource(nullptr); @@ -225,8 +233,10 @@ void VOIPConfigPanel::clearPipeline() videoInput = nullptr; } - delete videoProcessor; - videoProcessor = nullptr; + if (videoProcessor) { + delete videoProcessor; + videoProcessor = nullptr; + } if (inputAudioDevice) { inputAudioDevice->stop(); From 72eb21bbca8600bc2bf4428878c52e60884bfd48 Mon Sep 17 00:00:00 2001 From: thunder2 Date: Wed, 29 Dec 2021 17:56:11 +0100 Subject: [PATCH 104/113] 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 105/113] 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 c01f98feb9a7771713fe9200d88dcb3422e77b38 Mon Sep 17 00:00:00 2001 From: thunder2 Date: Thu, 30 Dec 2021 13:13:38 +0100 Subject: [PATCH 106/113] Added unregisterEventsHandler to destructor of MessagesDialog --- retroshare-gui/src/gui/msgs/MessagesDialog.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/retroshare-gui/src/gui/msgs/MessagesDialog.cpp b/retroshare-gui/src/gui/msgs/MessagesDialog.cpp index ffc108a53..e50c15998 100644 --- a/retroshare-gui/src/gui/msgs/MessagesDialog.cpp +++ b/retroshare-gui/src/gui/msgs/MessagesDialog.cpp @@ -356,6 +356,8 @@ MessagesDialog::~MessagesDialog() { // save settings processSettings(false); + + rsEvents->unregisterEventsHandler(mEventHandlerId); } UserNotify *MessagesDialog::createUserNotify(QObject *parent) From 5d9ce662e9a55247828caa0a7d4584ddfb93e9f5 Mon Sep 17 00:00:00 2001 From: thunder2 Date: Thu, 30 Dec 2021 13:53:10 +0100 Subject: [PATCH 107/113] Added update of message model when messages changed --- libretroshare/src/services/p3msgservice.cc | 1 + retroshare-gui/src/gui/msgs/MessagesDialog.cpp | 1 + 2 files changed, 2 insertions(+) diff --git a/libretroshare/src/services/p3msgservice.cc b/libretroshare/src/services/p3msgservice.cc index 5974d7bf3..921f9d867 100644 --- a/libretroshare/src/services/p3msgservice.cc +++ b/libretroshare/src/services/p3msgservice.cc @@ -1422,6 +1422,7 @@ bool p3MsgService::MessageToDraft(MessageInfo &info, const std::string &msgParen auto pEvent = std::make_shared(); pEvent->mMailStatusEventCode = RsMailStatusEventCode::MESSAGE_SENT; + pEvent->mChangedMsgIds.insert(std::to_string(msg->msgId)); rsEvents->postEvent(pEvent); return true; diff --git a/retroshare-gui/src/gui/msgs/MessagesDialog.cpp b/retroshare-gui/src/gui/msgs/MessagesDialog.cpp index e50c15998..a1b4b9d37 100644 --- a/retroshare-gui/src/gui/msgs/MessagesDialog.cpp +++ b/retroshare-gui/src/gui/msgs/MessagesDialog.cpp @@ -310,6 +310,7 @@ void MessagesDialog::handleEvent_main_thread(std::shared_ptr even case RsMailStatusEventCode::MESSAGE_SENT: case RsMailStatusEventCode::MESSAGE_REMOVED: case RsMailStatusEventCode::NEW_MESSAGE: + mMessageModel->updateMessages(); updateMessageSummaryList(); break; default: From fb1e0bc81c75b21216f9fb7fa5d2f0a796406ba7 Mon Sep 17 00:00:00 2001 From: csoler Date: Thu, 30 Dec 2021 19:51:20 +0100 Subject: [PATCH 108/113] 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 8f21c158c67a1d027b1c33aeeabaa05520d822b1 Mon Sep 17 00:00:00 2001 From: thunder2 Date: Thu, 30 Dec 2021 18:46:10 +0100 Subject: [PATCH 109/113] Don't add own sent mail to activity page as incoming mail --- libretroshare/src/retroshare/rsmsgs.h | 2 ++ libretroshare/src/services/p3msgservice.cc | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/libretroshare/src/retroshare/rsmsgs.h b/libretroshare/src/retroshare/rsmsgs.h index 6264af47a..fdbdd6acf 100644 --- a/libretroshare/src/retroshare/rsmsgs.h +++ b/libretroshare/src/retroshare/rsmsgs.h @@ -308,6 +308,8 @@ enum class RsMailStatusEventCode: uint8_t /// An error occurred attempting to sign the message SIGNATURE_FAILED = 0x04, + + MESSAGE_CHANGED = 0x05, }; struct RsMailStatusEvent : RsEvent diff --git a/libretroshare/src/services/p3msgservice.cc b/libretroshare/src/services/p3msgservice.cc index 921f9d867..a031cde91 100644 --- a/libretroshare/src/services/p3msgservice.cc +++ b/libretroshare/src/services/p3msgservice.cc @@ -2119,7 +2119,7 @@ void p3MsgService::notifyDataStatus( const GRouterMsgPropagationId& id, if(rsEvents) { auto pEvent = std::make_shared(); - pEvent->mMailStatusEventCode = RsMailStatusEventCode::NEW_MESSAGE; + pEvent->mMailStatusEventCode = RsMailStatusEventCode::MESSAGE_CHANGED; pEvent->mChangedMsgIds.insert(std::to_string(msg_id)); rsEvents->postEvent(pEvent); } From ae0c993b6b615735494cc9b5e4df5b2900147d41 Mon Sep 17 00:00:00 2001 From: thunder2 Date: Thu, 30 Dec 2021 20:47:10 +0100 Subject: [PATCH 110/113] Save and restore current index of mail list --- retroshare-gui/src/gui/msgs/MessagesDialog.cpp | 13 +++++++++++++ retroshare-gui/src/gui/msgs/MessagesDialog.h | 1 + 2 files changed, 14 insertions(+) diff --git a/retroshare-gui/src/gui/msgs/MessagesDialog.cpp b/retroshare-gui/src/gui/msgs/MessagesDialog.cpp index a1b4b9d37..261402c99 100644 --- a/retroshare-gui/src/gui/msgs/MessagesDialog.cpp +++ b/retroshare-gui/src/gui/msgs/MessagesDialog.cpp @@ -325,6 +325,12 @@ void MessagesDialog::preModelUpdate() mTmpSavedSelectedIds.clear(); getSelectedMessages(mTmpSavedSelectedIds); + mTmpSavedCurrentId.clear(); + const QModelIndex& m = ui.messageTreeWidget->currentIndex(); + if (m.isValid()) { + mTmpSavedCurrentId = m.sibling(m.row(), RsMessageModel::COLUMN_THREAD_MSGID).data(RsMessageModel::MsgIdRole).toString(); + } + std::cerr << "Pre-change: saving selection for " << mTmpSavedSelectedIds.size() << " indexes" << std::endl; } @@ -342,6 +348,13 @@ void MessagesDialog::postModelUpdate() } ui.messageTreeWidget->selectionModel()->select(sel,QItemSelectionModel::SelectCurrent); + + if (!mTmpSavedCurrentId.isEmpty()) { + QModelIndex index = mMessageProxyModel->mapFromSource(mMessageModel->getIndexOfMessage(mTmpSavedCurrentId.toStdString())); + if (index.isValid()) { + ui.messageTreeWidget->selectionModel()->setCurrentIndex(index, QItemSelectionModel::Select); + } + } } void MessagesDialog::sortColumn(int col,Qt::SortOrder so) diff --git a/retroshare-gui/src/gui/msgs/MessagesDialog.h b/retroshare-gui/src/gui/msgs/MessagesDialog.h index 497c7a06d..75a53ad4b 100644 --- a/retroshare-gui/src/gui/msgs/MessagesDialog.h +++ b/retroshare-gui/src/gui/msgs/MessagesDialog.h @@ -159,6 +159,7 @@ private: Ui::MessagesDialog ui; QList mTmpSavedSelectedIds; + QString mTmpSavedCurrentId; QModelIndex lastSelectedIndex; RsEventsHandlerId_t mEventHandlerId; From 281076d6b7262bffc408aa9ccc5c49740b2a8187 Mon Sep 17 00:00:00 2001 From: csoler Date: Thu, 30 Dec 2021 22:14:34 +0100 Subject: [PATCH 111/113] 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) { From f59ede23e1de5955bc6d3f12a7134313c36540b6 Mon Sep 17 00:00:00 2001 From: thunder2 Date: Fri, 31 Dec 2021 01:38:13 +0100 Subject: [PATCH 112/113] Removed old RsNotify code (NOTIFY_LIST_MESSAGELIST) from message service --- libretroshare/src/retroshare/rsnotify.h | 1 - libretroshare/src/services/p3msgservice.cc | 70 +++++++---------- retroshare-gui/src/gui/feeds/MsgItem.cpp | 76 +++++++++++++------ retroshare-gui/src/gui/feeds/MsgItem.h | 5 +- .../src/gui/msgs/MessageUserNotify.cpp | 33 +++++++- .../src/gui/msgs/MessageUserNotify.h | 7 ++ retroshare-gui/src/gui/msgs/MessageWidget.cpp | 62 ++++++++++----- retroshare-gui/src/gui/msgs/MessageWidget.h | 5 +- .../src/gui/msgs/MessagesDialog.cpp | 5 +- retroshare-gui/src/gui/notifyqt.cpp | 9 --- retroshare-gui/src/gui/notifyqt.h | 1 - 11 files changed, 173 insertions(+), 101 deletions(-) diff --git a/libretroshare/src/retroshare/rsnotify.h b/libretroshare/src/retroshare/rsnotify.h index e8c9de614..5d16f5c85 100644 --- a/libretroshare/src/retroshare/rsnotify.h +++ b/libretroshare/src/retroshare/rsnotify.h @@ -128,7 +128,6 @@ const uint32_t RS_MESSAGE_CONNECT_ATTEMPT = 0x0001; const int NOTIFY_LIST_NEIGHBOURS = 1; const int NOTIFY_LIST_FRIENDS = 2; const int NOTIFY_LIST_SEARCHLIST = 4; -const int NOTIFY_LIST_MESSAGELIST = 5; const int NOTIFY_LIST_CHANNELLIST = 6; const int NOTIFY_LIST_TRANSFERLIST = 7; const int NOTIFY_LIST_CONFIG = 8; diff --git a/libretroshare/src/services/p3msgservice.cc b/libretroshare/src/services/p3msgservice.cc index a031cde91..4dfe57f60 100644 --- a/libretroshare/src/services/p3msgservice.cc +++ b/libretroshare/src/services/p3msgservice.cc @@ -220,8 +220,6 @@ void p3MsgService::processIncomingMsg(RsMsgItem *mi) for(std::list::const_iterator it(mi->attachment.items.begin());it!=mi->attachment.items.end();++it) rsFiles->FileRequest((*it).name,(*it).hash,(*it).filesize,std::string(),RS_FILE_REQ_ANONYMOUS_ROUTING,srcIds) ; } - - RsServer::notify()->notifyListChange(NOTIFY_LIST_MESSAGELIST,NOTIFY_TYPE_ADD); } bool p3MsgService::checkAndRebuildPartialMessage(RsMsgItem *ci) @@ -283,16 +281,11 @@ int p3MsgService::incomingMsgs() void p3MsgService::handleIncomingItem(RsMsgItem *mi) { - bool changed = false ; - // only returns true when a msg is complete. if(checkAndRebuildPartialMessage(mi)) { processIncomingMsg(mi); - changed = true ; } - if(changed) - RsServer::notify()->notifyListChange(NOTIFY_LIST_MESSAGELIST,NOTIFY_TYPE_MOD); } void p3MsgService::statusChange(const std::list &plist) @@ -350,7 +343,6 @@ void p3MsgService::checkSizeAndSendMessage(RsMsgItem *msg) int p3MsgService::checkOutgoingMessages() { - bool changed = false; std::list output_queue; auto pEvent = std::make_shared(); @@ -400,7 +392,6 @@ int p3MsgService::checkOutgoingMessages() { (mit->second)->msgFlags &= ~RS_MSG_FLAGS_PENDING; toErase.push_back(mit->first); - changed = true; } else { @@ -442,9 +433,6 @@ int p3MsgService::checkOutgoingMessages() else checkSizeAndSendMessage(*it); - if(changed) - RsServer::notify()->notifyListChange(NOTIFY_LIST_MESSAGELIST,NOTIFY_TYPE_MOD); - if(rsEvents && !pEvent->mChangedMsgIds.empty()) rsEvents->postEvent(pEvent); @@ -954,8 +942,6 @@ bool p3MsgService::removeMsgId(const std::string &mid) setMessageTag(mid, 0, false); setMsgParentId(msgId, 0); - - RsServer::notify()->notifyListChange(NOTIFY_LIST_MESSAGELIST,NOTIFY_TYPE_MOD); } if(rsEvents && !pEvent->mChangedMsgIds.empty()) @@ -968,7 +954,6 @@ bool p3MsgService::markMsgIdRead(const std::string &mid, bool unreadByUser) { std::map::iterator mit; uint32_t msgId = atoi(mid.c_str()); - bool changed = false; { RsStackMutex stack(mMsgMtx); /********** STACK LOCKED MTX ******/ @@ -992,18 +977,18 @@ bool p3MsgService::markMsgIdRead(const std::string &mid, bool unreadByUser) if (mi->msgFlags != msgFlags) { - changed = true; IndicateConfigChanged(); /**** INDICATE MSG CONFIG CHANGED! *****/ + + auto pEvent = std::make_shared(); + pEvent->mMailStatusEventCode = RsMailStatusEventCode::MESSAGE_CHANGED; + pEvent->mChangedMsgIds.insert(mid); + rsEvents->postEvent(pEvent); } } else { return false; } } /* UNLOCKED */ - if (changed) { - RsServer::notify()->notifyListChange(NOTIFY_LIST_MESSAGELIST,NOTIFY_TYPE_MOD); - } - return true; } @@ -1012,8 +997,6 @@ bool p3MsgService::setMsgFlag(const std::string &mid, uint32_t flag, uint32_t std::map::iterator mit; uint32_t msgId = atoi(mid.c_str()); - bool changed = false; - { RsStackMutex stack(mMsgMtx); /********** STACK LOCKED MTX ******/ @@ -1033,15 +1016,15 @@ bool p3MsgService::setMsgFlag(const std::string &mid, uint32_t flag, uint32_t mit->second->msgFlags |= flag; if (mit->second->msgFlags != oldFlag) { - changed = true; IndicateConfigChanged(); /**** INDICATE MSG CONFIG CHANGED! *****/ + + auto pEvent = std::make_shared(); + pEvent->mMailStatusEventCode = RsMailStatusEventCode::MESSAGE_CHANGED; + pEvent->mChangedMsgIds.insert(mid); + rsEvents->postEvent(pEvent); } } /* UNLOCKED */ - if (changed) { - RsServer::notify()->notifyListChange(NOTIFY_LIST_MESSAGELIST,NOTIFY_TYPE_MOD); - } - return true; } @@ -1137,7 +1120,10 @@ uint32_t p3MsgService::sendMessage(RsMsgItem* item) IndicateConfigChanged(); /**** INDICATE MSG CONFIG CHANGED! *****/ - RsServer::notify()->notifyListChange(NOTIFY_LIST_MESSAGELIST, NOTIFY_TYPE_ADD); // deprecated + auto pEvent = std::make_shared(); + pEvent->mMailStatusEventCode = RsMailStatusEventCode::MESSAGE_SENT; + pEvent->mChangedMsgIds.insert(std::to_string(item->msgId)); + rsEvents->postEvent(pEvent); return item->msgId; } @@ -1175,8 +1161,11 @@ uint32_t p3MsgService::sendDistantMessage(RsMsgItem *item, const RsGxsId& from) IndicateConfigChanged(); /**** INDICATE MSG CONFIG CHANGED! *****/ - RsServer::notify()->notifyListChange( NOTIFY_LIST_MESSAGELIST, - NOTIFY_TYPE_ADD ); + auto pEvent = std::make_shared(); + pEvent->mMailStatusEventCode = RsMailStatusEventCode::MESSAGE_SENT; + pEvent->mChangedMsgIds.insert(std::to_string(item->msgId)); + rsEvents->postEvent(pEvent); + return item->msgId; } @@ -1210,8 +1199,6 @@ bool p3MsgService::MessageSend(MessageInfo &info) // Update info for caller info.msgId = std::to_string(msg->msgId); info .msgflags = msg->msgFlags; - - RsServer::notify()->notifyListChange(NOTIFY_LIST_MESSAGELIST,NOTIFY_TYPE_ADD);// deprecated. Should be removed. Oct. 28, 2020 } auto pEvent = std::make_shared(); @@ -1418,8 +1405,6 @@ bool p3MsgService::MessageToDraft(MessageInfo &info, const std::string &msgParen IndicateConfigChanged(); /**** INDICATE MSG CONFIG CHANGED! *****/ - // RsServer::notify()->notifyListChange(NOTIFY_LIST_MESSAGELIST,NOTIFY_TYPE_MOD); - auto pEvent = std::make_shared(); pEvent->mMailStatusEventCode = RsMailStatusEventCode::MESSAGE_SENT; pEvent->mChangedMsgIds.insert(std::to_string(msg->msgId)); @@ -1688,8 +1673,9 @@ bool p3MsgService::MessageToTrash(const std::string &mid, bool bTrash) std::map::iterator mit; uint32_t msgId = atoi(mid.c_str()); - bool bChanged = false; bool bFound = false; + auto pEvent = std::make_shared(); + pEvent->mMailStatusEventCode = RsMailStatusEventCode::MESSAGE_CHANGED; { RsStackMutex stack(mMsgMtx); /********** STACK LOCKED MTX ******/ @@ -1712,23 +1698,25 @@ bool p3MsgService::MessageToTrash(const std::string &mid, bool bTrash) if (bTrash) { if ((mi->msgFlags & RS_MSG_FLAGS_TRASH) == 0) { mi->msgFlags |= RS_MSG_FLAGS_TRASH; - bChanged = true; + pEvent->mChangedMsgIds.insert(std::to_string(mi->msgId)); } } else { if (mi->msgFlags & RS_MSG_FLAGS_TRASH) { mi->msgFlags &= ~RS_MSG_FLAGS_TRASH; - bChanged = true; + pEvent->mChangedMsgIds.insert(std::to_string(mi->msgId)); } } } } - if (bChanged) { + if (!pEvent->mChangedMsgIds.empty()) { IndicateConfigChanged(); /**** INDICATE MSG CONFIG CHANGED! *****/ checkOutgoingMessages(); - RsServer::notify()->notifyListChange(NOTIFY_LIST_MESSAGELIST,NOTIFY_TYPE_MOD); + if(rsEvents) { + rsEvents->postEvent(pEvent); + } } return bFound; @@ -2112,8 +2100,6 @@ void p3MsgService::notifyDataStatus( const GRouterMsgPropagationId& id, msgOutgoing.erase(it2); #endif - RsServer::notify()->notifyListChange( NOTIFY_LIST_MESSAGELIST, - NOTIFY_TYPE_ADD ); IndicateConfigChanged(); if(rsEvents) @@ -2268,8 +2254,6 @@ bool p3MsgService::notifyGxsTransSendStatus( RsGxsTransId mailId, } } - RsServer::notify()->notifyListChange( NOTIFY_LIST_MESSAGELIST, - NOTIFY_TYPE_ADD ); IndicateConfigChanged(); } else if( status >= GxsTransSendStatus::FAILED_RECEIPT_SIGNATURE ) diff --git a/retroshare-gui/src/gui/feeds/MsgItem.cpp b/retroshare-gui/src/gui/feeds/MsgItem.cpp index 66ae5f49b..6a47c9c22 100644 --- a/retroshare-gui/src/gui/feeds/MsgItem.cpp +++ b/retroshare-gui/src/gui/feeds/MsgItem.cpp @@ -31,6 +31,7 @@ #include "gui/common/AvatarDefs.h" #include "gui/common/FilesDefs.h" #include "gui/notifyqt.h" +#include "util/qtthreadsutils.h" #include #include @@ -59,12 +60,13 @@ MsgItem::MsgItem(FeedHolder *parent, uint32_t feedId, const std::string &msgId, //connect( gotoButton, SIGNAL( clicked( void ) ), this, SLOT( gotoHome ( void ) ) ); /* specific ones */ - connect(NotifyQt::getInstance(), SIGNAL(messagesChanged()), this, SLOT(checkMessageReadStatus())); connect( playButton, SIGNAL( clicked( void ) ), this, SLOT( playMedia ( void ) ) ); connect( deleteButton, SIGNAL( clicked( void ) ), this, SLOT( deleteMsg ( void ) ) ); connect( replyButton, SIGNAL( clicked( void ) ), this, SLOT( replyMsg ( void ) ) ); connect( sendinviteButton, SIGNAL( clicked( void ) ), this, SLOT( sendInvite ( void ) ) ); + mEventHandlerId = 0; + rsEvents->registerEventsHandler( [this](std::shared_ptr event) { RsQThreadUtils::postToObject( [this,event]() { handleEvent_main_thread(event); }); }, mEventHandlerId, RsEventType::MAIL_STATUS ); expandFrame->hide(); info_Frame_Invite->hide(); @@ -73,6 +75,57 @@ MsgItem::MsgItem(FeedHolder *parent, uint32_t feedId, const std::string &msgId, updateItem(); } +MsgItem::~MsgItem() +{ + rsEvents->unregisterEventsHandler(mEventHandlerId); +} + +void MsgItem::handleEvent_main_thread(std::shared_ptr event) +{ + if(event->mType != RsEventType::MAIL_STATUS) { + return; + } + + const RsMailStatusEvent *fe = dynamic_cast(event.get()); + if (!fe) { + return; + } + + switch (fe->mMailStatusEventCode) { + case RsMailStatusEventCode::MESSAGE_CHANGED: + if (fe->mChangedMsgIds.find(mMsgId) != fe->mChangedMsgIds.end()) { + MessageInfo msgInfo; + + if (!rsMail->getMessage(mMsgId, msgInfo)) { + removeItem(); + break; + } + + if (!mCloseOnRead) { + break; + } + + if (msgInfo.msgflags & RS_MSG_NEW) { + /* Message status is still "new" */ + break; + } + + removeItem(); + } + break; + case RsMailStatusEventCode::MESSAGE_REMOVED: + if (fe->mChangedMsgIds.find(mMsgId) != fe->mChangedMsgIds.end()) { + removeItem(); + } + break; + case RsMailStatusEventCode::MESSAGE_SENT: + case RsMailStatusEventCode::NEW_MESSAGE: + case RsMailStatusEventCode::MESSAGE_RECEIVED_ACK: + case RsMailStatusEventCode::SIGNATURE_FAILED: + break; + } +} + void MsgItem::updateItemStatic() { /* fill in */ @@ -246,7 +299,6 @@ void MsgItem::doExpand(bool open) mCloseOnRead = false; rsMail->MessageRead(mMsgId, false); - mCloseOnRead = true; } else { @@ -332,26 +384,6 @@ void MsgItem::toggle() expand(expandFrame->isHidden()); } -void MsgItem::checkMessageReadStatus() -{ - if (!mCloseOnRead) { - return; - } - - MessageInfo msgInfo; - if (!rsMail->getMessage(mMsgId, msgInfo)) { - std::cerr << "MsgItem::checkMessageReadStatus() Couldn't find Msg" << std::endl; - return; - } - - if (msgInfo.msgflags & RS_MSG_NEW) { - /* Message status is still "new" */ - return; - } - - removeItem(); -} - void MsgItem::sendInvite() { MessageInfo mi; diff --git a/retroshare-gui/src/gui/feeds/MsgItem.h b/retroshare-gui/src/gui/feeds/MsgItem.h index 32824ca23..2cb8645ba 100644 --- a/retroshare-gui/src/gui/feeds/MsgItem.h +++ b/retroshare-gui/src/gui/feeds/MsgItem.h @@ -24,6 +24,7 @@ #include "ui_MsgItem.h" #include "FeedItem.h" #include +#include class FeedHolder; class SubFileItem; @@ -35,6 +36,7 @@ class MsgItem : public FeedItem, private Ui::MsgItem public: /** Default Constructor */ MsgItem(FeedHolder *parent, uint32_t feedId, const std::string &msgId, bool isHome); + virtual ~MsgItem(); void updateItemStatic(); @@ -46,6 +48,7 @@ protected: private: void fillExpandFrame(); + void handleEvent_main_thread(std::shared_ptr event); private slots: /* default stuff */ @@ -56,7 +59,6 @@ private slots: void deleteMsg(); void replyMsg(); void sendInvite(); - void checkMessageReadStatus(); void updateItem(); @@ -66,6 +68,7 @@ private: bool mIsHome; bool mCloseOnRead; + RsEventsHandlerId_t mEventHandlerId; std::list mFileItems; }; diff --git a/retroshare-gui/src/gui/msgs/MessageUserNotify.cpp b/retroshare-gui/src/gui/msgs/MessageUserNotify.cpp index 071f794ff..e97ff96c0 100644 --- a/retroshare-gui/src/gui/msgs/MessageUserNotify.cpp +++ b/retroshare-gui/src/gui/msgs/MessageUserNotify.cpp @@ -22,13 +22,20 @@ #include "MessageUserNotify.h" #include "gui/notifyqt.h" #include "gui/MainWindow.h" +#include "util/qtthreadsutils.h" #include "gui/msgs/MessageInterface.h" MessageUserNotify::MessageUserNotify(QObject *parent) : UserNotify(parent) { - connect(NotifyQt::getInstance(), SIGNAL(messagesChanged()), this, SLOT(updateIcon())); + mEventHandlerId = 0; + rsEvents->registerEventsHandler( [this](std::shared_ptr event) { RsQThreadUtils::postToObject( [this,event]() { handleEvent_main_thread(event); }); }, mEventHandlerId, RsEventType::MAIL_STATUS ); +} + +MessageUserNotify::~MessageUserNotify() +{ + rsEvents->unregisterEventsHandler(mEventHandlerId); } bool MessageUserNotify::hasSetting(QString *name, QString *group) @@ -72,3 +79,27 @@ void MessageUserNotify::iconClicked() { MainWindow::showWindow(MainWindow::Messages); } + +void MessageUserNotify::handleEvent_main_thread(std::shared_ptr event) +{ + if(event->mType != RsEventType::MAIL_STATUS) { + return; + } + + const RsMailStatusEvent *fe = dynamic_cast(event.get()); + if (!fe) { + return; + } + + switch (fe->mMailStatusEventCode) { + case RsMailStatusEventCode::NEW_MESSAGE: + case RsMailStatusEventCode::MESSAGE_CHANGED: + case RsMailStatusEventCode::MESSAGE_REMOVED: + updateIcon(); + break; + case RsMailStatusEventCode::MESSAGE_SENT: + case RsMailStatusEventCode::MESSAGE_RECEIVED_ACK: + case RsMailStatusEventCode::SIGNATURE_FAILED: + break; + } +} diff --git a/retroshare-gui/src/gui/msgs/MessageUserNotify.h b/retroshare-gui/src/gui/msgs/MessageUserNotify.h index 58b30e8fc..f9b7458ab 100644 --- a/retroshare-gui/src/gui/msgs/MessageUserNotify.h +++ b/retroshare-gui/src/gui/msgs/MessageUserNotify.h @@ -21,6 +21,7 @@ #ifndef MESSAGEUSERNOTIFY_H #define MESSAGEUSERNOTIFY_H +#include #include "gui/common/UserNotify.h" class MessageUserNotify : public UserNotify @@ -29,6 +30,7 @@ class MessageUserNotify : public UserNotify public: MessageUserNotify(QObject *parent = 0); + virtual ~MessageUserNotify(); virtual bool hasSetting(QString *name, QString *group) override; @@ -41,6 +43,11 @@ private: virtual QString getNotifyMessage(bool plural) override; virtual void iconClicked() override; + + void handleEvent_main_thread(std::shared_ptr event); + +private: + RsEventsHandlerId_t mEventHandlerId; }; #endif // MESSAGEUSERNOTIFY_H diff --git a/retroshare-gui/src/gui/msgs/MessageWidget.cpp b/retroshare-gui/src/gui/msgs/MessageWidget.cpp index e614eeca0..39e157036 100644 --- a/retroshare-gui/src/gui/msgs/MessageWidget.cpp +++ b/retroshare-gui/src/gui/msgs/MessageWidget.cpp @@ -46,6 +46,7 @@ #include "util/HandleRichText.h" #include "util/DateTime.h" #include "util/QtVersion.h" +#include "util/qtthreadsutils.h" #include #include @@ -160,7 +161,6 @@ MessageWidget::MessageWidget(bool controlled, QWidget *parent, Qt::WindowFlags f connect(viewsource, SIGNAL(triggered()), this, SLOT(viewSource())); connect(NotifyQt::getInstance(), SIGNAL(messagesTagsChanged()), this, SLOT(messagesTagsChanged())); - connect(NotifyQt::getInstance(), SIGNAL(messagesChanged()), this, SLOT(messagesChanged())); ui.imageBlockWidget->addButtonAction(tr("Load images always for this message"), this, SLOT(loadImagesAlways()), true); ui.msgText->setImageBlockWidget(ui.imageBlockWidget); @@ -211,6 +211,9 @@ MessageWidget::MessageWidget(bool controlled, QWidget *parent, Qt::WindowFlags f ui.dateText-> setText(""); ui.info_Frame_Invite->hide(); + + mEventHandlerId = 0; + rsEvents->registerEventsHandler( [this](std::shared_ptr event) { RsQThreadUtils::postToObject( [this,event]() { handleEvent_main_thread(event); }); }, mEventHandlerId, RsEventType::MAIL_STATUS ); } MessageWidget::~MessageWidget() @@ -218,6 +221,44 @@ MessageWidget::~MessageWidget() if (isControlled == false) { processSettings("MessageWidget", false); } + + rsEvents->unregisterEventsHandler(mEventHandlerId); +} + +void MessageWidget::handleEvent_main_thread(std::shared_ptr event) +{ + if(event->mType != RsEventType::MAIL_STATUS) { + return; + } + + const RsMailStatusEvent *fe = dynamic_cast(event.get()); + if (!fe) { + return; + } + + switch (fe->mMailStatusEventCode) { + case RsMailStatusEventCode::MESSAGE_REMOVED: + if (fe->mChangedMsgIds.find(currMsgId) != fe->mChangedMsgIds.end()) { + if (isControlled) { + /* processed by MessagesDialog */ + return; + } + + /* messages was removed */ + if (isWindow) { + window()->close(); + } else { + deleteLater(); + } + } + break; + case RsMailStatusEventCode::MESSAGE_SENT: + case RsMailStatusEventCode::MESSAGE_CHANGED: + case RsMailStatusEventCode::NEW_MESSAGE: + case RsMailStatusEventCode::MESSAGE_RECEIVED_ACK: + case RsMailStatusEventCode::SIGNATURE_FAILED: + break; + } } void MessageWidget::connectAction(enumActionType actionType, QToolButton* button) @@ -407,25 +448,6 @@ void MessageWidget::messagesTagsChanged() showTagLabels(); } -void MessageWidget::messagesChanged() -{ - if (isControlled) { - /* processed by MessagesDialog */ - return; - } - - /* test Message */ - MessageInfo msgInfo; - if (rsMail->getMessage(currMsgId, msgInfo) == false) { - /* messages was removed */ - if (isWindow) { - window()->close(); - } else { - deleteLater(); - } - } -} - void MessageWidget::clearTagLabels() { /* clear all tags */ diff --git a/retroshare-gui/src/gui/msgs/MessageWidget.h b/retroshare-gui/src/gui/msgs/MessageWidget.h index 5acf627f6..12438e55c 100644 --- a/retroshare-gui/src/gui/msgs/MessageWidget.h +++ b/retroshare-gui/src/gui/msgs/MessageWidget.h @@ -22,6 +22,7 @@ #define _MESSAGEWIDGET_H #include +#include #include "ui_MessageWidget.h" class QToolButton; @@ -75,7 +76,6 @@ private slots: void msgfilelistWidgetCostumPopupMenu(QPoint); void messagesTagsChanged(); - void messagesChanged(); void togglefileview(bool noUpdate = false); void getcurrentrecommended(); @@ -93,11 +93,14 @@ private: void showTagLabels(); void setToolbarButtonStyle(Qt::ToolButtonStyle style); + void handleEvent_main_thread(std::shared_ptr event); + bool isControlled; bool isWindow; std::string currMsgId; unsigned int currMsgFlags; bool expandFiles; + RsEventsHandlerId_t mEventHandlerId; QList tagLabels; diff --git a/retroshare-gui/src/gui/msgs/MessagesDialog.cpp b/retroshare-gui/src/gui/msgs/MessagesDialog.cpp index 261402c99..ac829de8d 100644 --- a/retroshare-gui/src/gui/msgs/MessagesDialog.cpp +++ b/retroshare-gui/src/gui/msgs/MessagesDialog.cpp @@ -268,7 +268,6 @@ MessagesDialog::MessagesDialog(QWidget *parent) registerHelpButton(ui.helpButton,help_str,"MessagesDialog") ; - connect(NotifyQt::getInstance(), SIGNAL(messagesChanged()), mMessageModel, SLOT(updateMessages())); connect(NotifyQt::getInstance(), SIGNAL(messagesTagsChanged()), this, SLOT(messagesTagsChanged())); connect(ui.filterLineEdit, SIGNAL(textChanged(QString)), this, SLOT(filterChanged(QString))); @@ -310,10 +309,12 @@ void MessagesDialog::handleEvent_main_thread(std::shared_ptr even case RsMailStatusEventCode::MESSAGE_SENT: case RsMailStatusEventCode::MESSAGE_REMOVED: case RsMailStatusEventCode::NEW_MESSAGE: + case RsMailStatusEventCode::MESSAGE_CHANGED: mMessageModel->updateMessages(); updateMessageSummaryList(); break; - default: + case RsMailStatusEventCode::MESSAGE_RECEIVED_ACK: + case RsMailStatusEventCode::SIGNATURE_FAILED: break; } } diff --git a/retroshare-gui/src/gui/notifyqt.cpp b/retroshare-gui/src/gui/notifyqt.cpp index d0fcea506..7211c10bc 100644 --- a/retroshare-gui/src/gui/notifyqt.cpp +++ b/retroshare-gui/src/gui/notifyqt.cpp @@ -563,12 +563,6 @@ void NotifyQt::notifyListChange(int list, int type) break; case NOTIFY_LIST_SEARCHLIST: break; - case NOTIFY_LIST_MESSAGELIST: -#ifdef NOTIFY_DEBUG - std::cerr << "received msg changed" << std::endl ; -#endif - emit messagesChanged() ; - break; case NOTIFY_LIST_MESSAGE_TAGS: #ifdef NOTIFY_DEBUG std::cerr << "received msg tags changed" << std::endl ; @@ -663,8 +657,6 @@ void NotifyQt::notifyListPreChange(int list, int /*type*/) break; case NOTIFY_LIST_SEARCHLIST: break; - case NOTIFY_LIST_MESSAGELIST: - break; case NOTIFY_LIST_CHANNELLIST: break; case NOTIFY_LIST_TRANSFERLIST: @@ -697,7 +689,6 @@ void NotifyQt::UpdateGUI() // the gui is running, then they get updated by callbacks. if(!already_updated) { - emit messagesChanged() ; emit neighboursChanged(); emit configChanged(); diff --git a/retroshare-gui/src/gui/notifyqt.h b/retroshare-gui/src/gui/notifyqt.h index 069ae8056..a72493a3a 100644 --- a/retroshare-gui/src/gui/notifyqt.h +++ b/retroshare-gui/src/gui/notifyqt.h @@ -109,7 +109,6 @@ class NotifyQt: public QObject, public NotifyClient void lobbyListChanged() const ; void chatLobbyEvent(qulonglong,int,const RsGxsId&,const QString&) ; void neighboursChanged() const ; - void messagesChanged() const ; void messagesTagsChanged() const; void configChanged() const ; void logInfoChanged(const QString&) const ; From 3eb910a25f4912c3fe596f62d14e480af594b7a2 Mon Sep 17 00:00:00 2001 From: thunder2 Date: Thu, 30 Dec 2021 23:55:26 +0100 Subject: [PATCH 113/113] Removed old RsNotify code (NOTIFY_LIST_MESSAGE_TAGS) from message service --- libretroshare/src/retroshare/rsevents.h | 3 ++ libretroshare/src/retroshare/rsmsgs.h | 27 +++++++++++ libretroshare/src/retroshare/rsnotify.h | 1 - libretroshare/src/services/p3msgservice.cc | 46 +++++++++++++------ retroshare-gui/src/gui/feeds/MsgItem.cpp | 1 + .../src/gui/msgs/MessageUserNotify.cpp | 1 + retroshare-gui/src/gui/msgs/MessageWidget.cpp | 5 +- .../src/gui/msgs/MessagesDialog.cpp | 35 ++++++++++---- retroshare-gui/src/gui/msgs/MessagesDialog.h | 3 +- retroshare-gui/src/gui/msgs/TagsMenu.cpp | 30 +++++++++++- retroshare-gui/src/gui/msgs/TagsMenu.h | 10 +++- retroshare-gui/src/gui/notifyqt.cpp | 6 --- retroshare-gui/src/gui/notifyqt.h | 1 - .../src/gui/settings/MessagePage.cpp | 26 +++++++++++ retroshare-gui/src/gui/settings/MessagePage.h | 2 + 15 files changed, 160 insertions(+), 37 deletions(-) diff --git a/libretroshare/src/retroshare/rsevents.h b/libretroshare/src/retroshare/rsevents.h index 9b9fbf106..86080ffef 100644 --- a/libretroshare/src/retroshare/rsevents.h +++ b/libretroshare/src/retroshare/rsevents.h @@ -103,6 +103,9 @@ enum class RsEventType : uint32_t /// @see rspeers.h NETWORK = 16, + /// @see RsMailTagEvent + MAIL_TAG = 17, + /** Emitted to update library clients about file hashing being completed */ FILE_HASHING_COMPLETED = 20, diff --git a/libretroshare/src/retroshare/rsmsgs.h b/libretroshare/src/retroshare/rsmsgs.h index fdbdd6acf..5e317d4ae 100644 --- a/libretroshare/src/retroshare/rsmsgs.h +++ b/libretroshare/src/retroshare/rsmsgs.h @@ -310,6 +310,7 @@ enum class RsMailStatusEventCode: uint8_t SIGNATURE_FAILED = 0x04, MESSAGE_CHANGED = 0x05, + TAG_CHANGED = 0x06, }; struct RsMailStatusEvent : RsEvent @@ -331,6 +332,32 @@ struct RsMailStatusEvent : RsEvent ~RsMailStatusEvent() override = default; }; +enum class RsMailTagEventCode: uint8_t +{ + TAG_ADDED = 0x00, + TAG_CHANGED = 0x01, + TAG_REMOVED = 0x02, +}; + +struct RsMailTagEvent : RsEvent +{ + RsMailTagEvent() : RsEvent(RsEventType::MAIL_TAG) {} + + RsMailTagEventCode mMailTagEventCode; + std::set mChangedMsgTagIds; + + /// @see RsEvent + void serial_process( RsGenericSerializer::SerializeJob j, + RsGenericSerializer::SerializeContext& ctx) override + { + RsEvent::serial_process(j, ctx); + RS_SERIAL_PROCESS(mChangedMsgTagIds); + RS_SERIAL_PROCESS(mMailTagEventCode); + } + + ~RsMailTagEvent() override = default; +}; + #define RS_CHAT_PUBLIC 0x0001 #define RS_CHAT_PRIVATE 0x0002 #define RS_CHAT_AVATAR_AVAILABLE 0x0004 diff --git a/libretroshare/src/retroshare/rsnotify.h b/libretroshare/src/retroshare/rsnotify.h index 5d16f5c85..aeb701066 100644 --- a/libretroshare/src/retroshare/rsnotify.h +++ b/libretroshare/src/retroshare/rsnotify.h @@ -134,7 +134,6 @@ const int NOTIFY_LIST_CONFIG = 8; const int NOTIFY_LIST_DIRLIST_LOCAL = 9; const int NOTIFY_LIST_DIRLIST_FRIENDS = 10; const int NOTIFY_LIST_FORUMLIST_LOCKED = 11; // use connect with Qt::QueuedConnection -const int NOTIFY_LIST_MESSAGE_TAGS = 12; const int NOTIFY_LIST_PUBLIC_CHAT = 13; const int NOTIFY_LIST_PRIVATE_INCOMING_CHAT = 14; const int NOTIFY_LIST_PRIVATE_OUTGOING_CHAT = 15; diff --git a/libretroshare/src/services/p3msgservice.cc b/libretroshare/src/services/p3msgservice.cc index 4dfe57f60..44ad7e024 100644 --- a/libretroshare/src/services/p3msgservice.cc +++ b/libretroshare/src/services/p3msgservice.cc @@ -1438,7 +1438,7 @@ bool p3MsgService::getMessageTagTypes(MsgTagType& tags) bool p3MsgService::setMessageTagType(uint32_t tagId, std::string& text, uint32_t rgb_color) { - int nNotifyType = 0; + auto ev = std::make_shared(); { RsStackMutex stack(mMsgMtx); /********** STACK LOCKED MTX ******/ @@ -1461,7 +1461,8 @@ bool p3MsgService::setMessageTagType(uint32_t tagId, std::string& text, uint32 mTags.insert(std::pair(tagId, tagType)); - nNotifyType = NOTIFY_TYPE_ADD; + ev->mMailTagEventCode = RsMailTagEventCode::TAG_ADDED; + ev->mChangedMsgTagIds.insert(std::to_string(tagId)); } else { if (mit->second->text != text || mit->second->rgb_color != rgb_color) { /* modify existing tag */ @@ -1475,17 +1476,18 @@ bool p3MsgService::setMessageTagType(uint32_t tagId, std::string& text, uint32 } mit->second->rgb_color = rgb_color; - nNotifyType = NOTIFY_TYPE_MOD; + ev->mMailTagEventCode = RsMailTagEventCode::TAG_CHANGED; + ev->mChangedMsgTagIds.insert(std::to_string(tagId)); } } } /* UNLOCKED */ - if (nNotifyType) { + if (!ev->mChangedMsgTagIds.empty()) { IndicateConfigChanged(); /**** INDICATE MSG CONFIG CHANGED! *****/ - RsServer::notify()->notifyListChange(NOTIFY_LIST_MESSAGE_TAGS, nNotifyType); - + rsEvents->postEvent(ev); + return true; } @@ -1499,6 +1501,9 @@ bool p3MsgService::removeMessageTagType(uint32_t tagId) return false; } + auto msgEvent = std::make_shared(); + msgEvent->mMailStatusEventCode = RsMailStatusEventCode::TAG_CHANGED; + { RsStackMutex stack(mMsgMtx); /********** STACK LOCKED MTX ******/ @@ -1526,7 +1531,10 @@ bool p3MsgService::removeMessageTagType(uint32_t tagId) delete(tag); mMsgTags.erase(mit1++); - continue; + } + + if (msgEvent->mChangedMsgIds.find(std::to_string(mit1->first)) == msgEvent->mChangedMsgIds.end()) { + msgEvent->mChangedMsgIds.insert(std::to_string(mit1->first)); } } ++mit1; @@ -1540,7 +1548,14 @@ bool p3MsgService::removeMessageTagType(uint32_t tagId) IndicateConfigChanged(); /**** INDICATE MSG CONFIG CHANGED! *****/ - RsServer::notify()->notifyListChange(NOTIFY_LIST_MESSAGE_TAGS, NOTIFY_TYPE_DEL); + auto ev = std::make_shared(); + ev->mMailTagEventCode = RsMailTagEventCode::TAG_REMOVED; + ev->mChangedMsgTagIds.insert(std::to_string(tagId)); + rsEvents->postEvent(ev); + + if (!msgEvent->mChangedMsgIds.empty()) { + rsEvents->postEvent(msgEvent); + } return true; } @@ -1581,7 +1596,8 @@ bool p3MsgService::setMessageTag(const std::string &msgId, uint32_t tagId, bool } } - int nNotifyType = 0; + auto ev = std::make_shared(); + ev->mMailStatusEventCode = RsMailStatusEventCode::TAG_CHANGED; { RsStackMutex stack(mMsgMtx); /********** STACK LOCKED MTX ******/ @@ -1600,7 +1616,7 @@ bool p3MsgService::setMessageTag(const std::string &msgId, uint32_t tagId, bool mMsgTags.insert(std::pair(tag->msgId, tag)); - nNotifyType = NOTIFY_TYPE_ADD; + ev->mChangedMsgIds.insert(msgId); } } else { RsMsgTags* tag = mit->second; @@ -1618,18 +1634,18 @@ bool p3MsgService::setMessageTag(const std::string &msgId, uint32_t tagId, bool tag->tagIds.push_back(tagId); /* keep the list sorted */ tag->tagIds.sort(); - nNotifyType = NOTIFY_TYPE_ADD; + ev->mChangedMsgIds.insert(msgId); } } else { if (tagId == 0) { /* remove all */ delete(tag); mMsgTags.erase(mit); - nNotifyType = NOTIFY_TYPE_DEL; + ev->mChangedMsgIds.insert(msgId); } else { if (lit != tag->tagIds.end()) { tag->tagIds.erase(lit); - nNotifyType = NOTIFY_TYPE_DEL; + ev->mChangedMsgIds.insert(msgId); if (tag->tagIds.empty()) { /* remove empty tag */ @@ -1643,10 +1659,10 @@ bool p3MsgService::setMessageTag(const std::string &msgId, uint32_t tagId, bool } /* UNLOCKED */ - if (nNotifyType) { + if (!ev->mChangedMsgIds.empty()) { IndicateConfigChanged(); /**** INDICATE MSG CONFIG CHANGED! *****/ - RsServer::notify()->notifyListChange(NOTIFY_LIST_MESSAGE_TAGS, nNotifyType); + rsEvents->postEvent(ev); return true; } diff --git a/retroshare-gui/src/gui/feeds/MsgItem.cpp b/retroshare-gui/src/gui/feeds/MsgItem.cpp index 6a47c9c22..e0b3d2bf0 100644 --- a/retroshare-gui/src/gui/feeds/MsgItem.cpp +++ b/retroshare-gui/src/gui/feeds/MsgItem.cpp @@ -120,6 +120,7 @@ void MsgItem::handleEvent_main_thread(std::shared_ptr event) break; case RsMailStatusEventCode::MESSAGE_SENT: case RsMailStatusEventCode::NEW_MESSAGE: + case RsMailStatusEventCode::TAG_CHANGED: case RsMailStatusEventCode::MESSAGE_RECEIVED_ACK: case RsMailStatusEventCode::SIGNATURE_FAILED: break; diff --git a/retroshare-gui/src/gui/msgs/MessageUserNotify.cpp b/retroshare-gui/src/gui/msgs/MessageUserNotify.cpp index e97ff96c0..fddf2c8d5 100644 --- a/retroshare-gui/src/gui/msgs/MessageUserNotify.cpp +++ b/retroshare-gui/src/gui/msgs/MessageUserNotify.cpp @@ -98,6 +98,7 @@ void MessageUserNotify::handleEvent_main_thread(std::shared_ptr e updateIcon(); break; case RsMailStatusEventCode::MESSAGE_SENT: + case RsMailStatusEventCode::TAG_CHANGED: case RsMailStatusEventCode::MESSAGE_RECEIVED_ACK: case RsMailStatusEventCode::SIGNATURE_FAILED: break; diff --git a/retroshare-gui/src/gui/msgs/MessageWidget.cpp b/retroshare-gui/src/gui/msgs/MessageWidget.cpp index 39e157036..d05d17446 100644 --- a/retroshare-gui/src/gui/msgs/MessageWidget.cpp +++ b/retroshare-gui/src/gui/msgs/MessageWidget.cpp @@ -160,8 +160,6 @@ MessageWidget::MessageWidget(bool controlled, QWidget *parent, Qt::WindowFlags f viewsource->setShortcut(QKeySequence("CTRL+O")); connect(viewsource, SIGNAL(triggered()), this, SLOT(viewSource())); - connect(NotifyQt::getInstance(), SIGNAL(messagesTagsChanged()), this, SLOT(messagesTagsChanged())); - ui.imageBlockWidget->addButtonAction(tr("Load images always for this message"), this, SLOT(loadImagesAlways()), true); ui.msgText->setImageBlockWidget(ui.imageBlockWidget); @@ -252,6 +250,9 @@ void MessageWidget::handleEvent_main_thread(std::shared_ptr event } } break; + case RsMailStatusEventCode::TAG_CHANGED: + messagesTagsChanged(); + break; case RsMailStatusEventCode::MESSAGE_SENT: case RsMailStatusEventCode::MESSAGE_CHANGED: case RsMailStatusEventCode::NEW_MESSAGE: diff --git a/retroshare-gui/src/gui/msgs/MessagesDialog.cpp b/retroshare-gui/src/gui/msgs/MessagesDialog.cpp index ac829de8d..c5c3c543c 100644 --- a/retroshare-gui/src/gui/msgs/MessagesDialog.cpp +++ b/retroshare-gui/src/gui/msgs/MessagesDialog.cpp @@ -268,8 +268,6 @@ MessagesDialog::MessagesDialog(QWidget *parent) registerHelpButton(ui.helpButton,help_str,"MessagesDialog") ; - connect(NotifyQt::getInstance(), SIGNAL(messagesTagsChanged()), this, SLOT(messagesTagsChanged())); - connect(ui.filterLineEdit, SIGNAL(textChanged(QString)), this, SLOT(filterChanged(QString))); connect(ui.filterLineEdit, SIGNAL(filterChanged(int)), this, SLOT(filterColumnChanged(int))); @@ -293,6 +291,9 @@ MessagesDialog::MessagesDialog(QWidget *parent) mEventHandlerId=0; rsEvents->registerEventsHandler( [this](std::shared_ptr event) { RsQThreadUtils::postToObject( [this,event]() { handleEvent_main_thread(event); }); }, mEventHandlerId, RsEventType::MAIL_STATUS ); + + mTagEventHandlerId = 0; + rsEvents->registerEventsHandler( [this](std::shared_ptr event) { RsQThreadUtils::postToObject( [this,event]() { handleTagEvent_main_thread(event); }); }, mEventHandlerId, RsEventType::MAIL_TAG ); } void MessagesDialog::handleEvent_main_thread(std::shared_ptr event) @@ -310,6 +311,7 @@ void MessagesDialog::handleEvent_main_thread(std::shared_ptr even case RsMailStatusEventCode::MESSAGE_REMOVED: case RsMailStatusEventCode::NEW_MESSAGE: case RsMailStatusEventCode::MESSAGE_CHANGED: + case RsMailStatusEventCode::TAG_CHANGED: mMessageModel->updateMessages(); updateMessageSummaryList(); break; @@ -319,6 +321,27 @@ void MessagesDialog::handleEvent_main_thread(std::shared_ptr even } } +void MessagesDialog::handleTagEvent_main_thread(std::shared_ptr event) +{ + if (event->mType != RsEventType::MAIL_TAG) { + return; + } + + const RsMailTagEvent *fe = dynamic_cast(event.get()); + if (!fe) { + return; + } + + switch (fe->mMailTagEventCode) { + case RsMailTagEventCode::TAG_ADDED: + case RsMailTagEventCode::TAG_CHANGED: + case RsMailTagEventCode::TAG_REMOVED: + fillQuickView(); + mMessageModel->updateMessages(); + break; + } +} + void MessagesDialog::preModelUpdate() { // save current selection @@ -373,6 +396,7 @@ MessagesDialog::~MessagesDialog() processSettings(false); rsEvents->unregisterEventsHandler(mEventHandlerId); + rsEvents->unregisterEventsHandler(mTagEventHandlerId); } UserNotify *MessagesDialog::createUserNotify(QObject *parent) @@ -938,13 +962,6 @@ void MessagesDialog::changeQuickView(int newrow) mMessageProxyModel->setFilterRegExp(QRegExp(RsMessageModel::FilterString)); // this triggers the update of the proxy model } -void MessagesDialog::messagesTagsChanged() -{ - fillQuickView(); - mMessageModel->updateMessages(); -} - - // click in messageTreeWidget void MessagesDialog::currentChanged(const QModelIndex& new_proxy_index,const QModelIndex& /*old_proxy_index*/) { diff --git a/retroshare-gui/src/gui/msgs/MessagesDialog.h b/retroshare-gui/src/gui/msgs/MessagesDialog.h index 75a53ad4b..e2c3f4c6f 100644 --- a/retroshare-gui/src/gui/msgs/MessagesDialog.h +++ b/retroshare-gui/src/gui/msgs/MessagesDialog.h @@ -66,7 +66,6 @@ protected: public slots: //void insertMessages(); - void messagesTagsChanged(); void messageRemoved(); void preModelUpdate(); void postModelUpdate(); @@ -112,6 +111,7 @@ private slots: private: void handleEvent_main_thread(std::shared_ptr event); + void handleTagEvent_main_thread(std::shared_ptr event); void updateInterface(); @@ -163,6 +163,7 @@ private: QModelIndex lastSelectedIndex; RsEventsHandlerId_t mEventHandlerId; + RsEventsHandlerId_t mTagEventHandlerId; }; #endif diff --git a/retroshare-gui/src/gui/msgs/TagsMenu.cpp b/retroshare-gui/src/gui/msgs/TagsMenu.cpp index 357c37325..8ef4f7d93 100644 --- a/retroshare-gui/src/gui/msgs/TagsMenu.cpp +++ b/retroshare-gui/src/gui/msgs/TagsMenu.cpp @@ -30,6 +30,7 @@ #include "gui/common/TagDefs.h" #include "gui/settings/NewTag.h" #include "gui/notifyqt.h" +#include "util/qtthreadsutils.h" #include "gui/msgs/MessageInterface.h" @@ -46,11 +47,18 @@ TagsMenu::TagsMenu(const QString &title, QWidget *parent) : QMenu (title, parent) { connect(this, SIGNAL(triggered (QAction*)), this, SLOT(tagTriggered(QAction*))); - connect(NotifyQt::getInstance(), SIGNAL(messagesTagsChanged()), this, SLOT(fillTags())); + + mEventHandlerId = 0; + rsEvents->registerEventsHandler( [this](std::shared_ptr event) { RsQThreadUtils::postToObject( [this,event]() { handleEvent_main_thread(event); }); }, mEventHandlerId, RsEventType::MAIL_TAG ); fillTags(); } +TagsMenu::~TagsMenu() +{ + rsEvents->unregisterEventsHandler(mEventHandlerId); +} + void TagsMenu::paintEvent(QPaintEvent *e) { QMenu::paintEvent(e); @@ -89,6 +97,26 @@ void TagsMenu::paintEvent(QPaintEvent *e) } } +void TagsMenu::handleEvent_main_thread(std::shared_ptr event) +{ + if (event->mType != RsEventType::MAIL_TAG) { + return; + } + + const RsMailTagEvent *fe = dynamic_cast(event.get()); + if (!fe) { + return; + } + + switch (fe->mMailTagEventCode) { + case RsMailTagEventCode::TAG_ADDED: + case RsMailTagEventCode::TAG_CHANGED: + case RsMailTagEventCode::TAG_REMOVED: + fillTags(); + break; + } +} + void TagsMenu::fillTags() { clear(); diff --git a/retroshare-gui/src/gui/msgs/TagsMenu.h b/retroshare-gui/src/gui/msgs/TagsMenu.h index 279638aae..a3f2cdd55 100644 --- a/retroshare-gui/src/gui/msgs/TagsMenu.h +++ b/retroshare-gui/src/gui/msgs/TagsMenu.h @@ -24,6 +24,7 @@ #include #include +#include class TagsMenu : public QMenu { @@ -31,6 +32,7 @@ class TagsMenu : public QMenu public: TagsMenu(const QString &title, QWidget *parent); + virtual ~TagsMenu(); void activateActions(std::list& tagIds); @@ -42,8 +44,14 @@ protected: virtual void paintEvent(QPaintEvent *e); private slots: - void fillTags(); void tagTriggered(QAction *action); + +private: + void handleEvent_main_thread(std::shared_ptr event); + void fillTags(); + +private: + RsEventsHandlerId_t mEventHandlerId; }; #endif diff --git a/retroshare-gui/src/gui/notifyqt.cpp b/retroshare-gui/src/gui/notifyqt.cpp index 7211c10bc..380f2382c 100644 --- a/retroshare-gui/src/gui/notifyqt.cpp +++ b/retroshare-gui/src/gui/notifyqt.cpp @@ -563,12 +563,6 @@ void NotifyQt::notifyListChange(int list, int type) break; case NOTIFY_LIST_SEARCHLIST: break; - case NOTIFY_LIST_MESSAGE_TAGS: -#ifdef NOTIFY_DEBUG - std::cerr << "received msg tags changed" << std::endl ; -#endif - emit messagesTagsChanged(); - break; case NOTIFY_LIST_CHANNELLIST: break; case NOTIFY_LIST_TRANSFERLIST: diff --git a/retroshare-gui/src/gui/notifyqt.h b/retroshare-gui/src/gui/notifyqt.h index a72493a3a..f4fc063c7 100644 --- a/retroshare-gui/src/gui/notifyqt.h +++ b/retroshare-gui/src/gui/notifyqt.h @@ -109,7 +109,6 @@ class NotifyQt: public QObject, public NotifyClient void lobbyListChanged() const ; void chatLobbyEvent(qulonglong,int,const RsGxsId&,const QString&) ; void neighboursChanged() const ; - void messagesTagsChanged() const; void configChanged() const ; void logInfoChanged(const QString&) const ; void chatStatusChanged(const ChatId&,const QString&) const ; diff --git a/retroshare-gui/src/gui/settings/MessagePage.cpp b/retroshare-gui/src/gui/settings/MessagePage.cpp index 91a24ab02..ff302317d 100644 --- a/retroshare-gui/src/gui/settings/MessagePage.cpp +++ b/retroshare-gui/src/gui/settings/MessagePage.cpp @@ -27,6 +27,7 @@ #include "gui/common/TagDefs.h" #include #include "NewTag.h" +#include "util/qtthreadsutils.h" MessagePage::MessagePage(QWidget * parent, Qt::WindowFlags flags) : ConfigPage(parent, flags) @@ -54,10 +55,14 @@ MessagePage::MessagePage(QWidget * parent, Qt::WindowFlags flags) connect(ui.loadEmbeddedImages, SIGNAL(toggled(bool)), this,SLOT(updateLoadEmbededImages() )); connect(ui.openComboBox, SIGNAL(currentIndexChanged(int)),this,SLOT(updateMsgOpen() )); connect(ui.emoticonscheckBox, SIGNAL(toggled(bool)), this,SLOT(updateLoadEmoticons() )); + + mTagEventHandlerId = 0; + rsEvents->registerEventsHandler( [this](std::shared_ptr event) { RsQThreadUtils::postToObject( [this,event]() { handleEvent_main_thread(event); }); }, mTagEventHandlerId, RsEventType::MAIL_TAG ); } MessagePage::~MessagePage() { + rsEvents->unregisterEventsHandler(mTagEventHandlerId); delete(m_pTags); } @@ -134,6 +139,27 @@ MessagePage::load() fillTags(); } +void MessagePage::handleEvent_main_thread(std::shared_ptr event) +{ + if (event->mType != RsEventType::MAIL_TAG) { + return; + } + + const RsMailTagEvent *fe = dynamic_cast(event.get()); + if (!fe) { + return; + } + + switch (fe->mMailTagEventCode) { + case RsMailTagEventCode::TAG_ADDED: + case RsMailTagEventCode::TAG_CHANGED: + case RsMailTagEventCode::TAG_REMOVED: + rsMail->getMessageTagTypes(*m_pTags); + fillTags(); + break; + } +} + // fill tags void MessagePage::fillTags() { diff --git a/retroshare-gui/src/gui/settings/MessagePage.h b/retroshare-gui/src/gui/settings/MessagePage.h index f3a4c12a7..774d31b95 100644 --- a/retroshare-gui/src/gui/settings/MessagePage.h +++ b/retroshare-gui/src/gui/settings/MessagePage.h @@ -62,11 +62,13 @@ private slots: void updateLoadEmoticons(); private: + void handleEvent_main_thread(std::shared_ptr event); void fillTags(); /* Pointer for not include of rsmsgs.h */ MsgTagType *m_pTags; std::list m_changedTagIds; + RsEventsHandlerId_t mTagEventHandlerId; Ui::MessagePage ui; };