From e4ce32bef8d2d8e8593fd0c12f244e670e15498e Mon Sep 17 00:00:00 2001 From: csoler Date: Thu, 25 Nov 2021 23:28:01 +0100 Subject: [PATCH] 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