mirror of
https://github.com/RetroShare/RetroShare.git
synced 2025-01-18 10:57:18 -05:00
continue on switching QString and QByteArray
This commit is contained in:
parent
e4ce32bef8
commit
6a4cdcc471
@ -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 \
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
};
|
||||
|
||||
|
@ -41,12 +41,12 @@ GetConfCommand::GetConfCommand(Type t)
|
||||
{
|
||||
}
|
||||
|
||||
ByteArray GetConfCommand::build(const ByteArray &key)
|
||||
ByteArray GetConfCommand::build(const std::string &key)
|
||||
{
|
||||
return build(QList<ByteArray>() << key);
|
||||
return build(std::list<std::string> { key } );
|
||||
}
|
||||
|
||||
ByteArray GetConfCommand::build(const QList<ByteArray> &keys)
|
||||
ByteArray GetConfCommand::build(const std::list<std::string> &keys)
|
||||
{
|
||||
ByteArray out;
|
||||
if (type == GetConf) {
|
||||
@ -97,9 +97,9 @@ void GetConfCommand::onDataFinished()
|
||||
m_lastKey.clear();
|
||||
}
|
||||
|
||||
std::list<std::string> GetConfCommand::get(const ByteArray& key) const
|
||||
std::list<std::string> 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;
|
||||
|
@ -56,11 +56,11 @@ public:
|
||||
|
||||
GetConfCommand(Type type);
|
||||
|
||||
ByteArray build(const ByteArray &key);
|
||||
ByteArray build(const QList<ByteArray> &keys);
|
||||
ByteArray build(const std::string &key);
|
||||
ByteArray build(const std::list<std::string> &keys);
|
||||
|
||||
const std::map<std::string,std::list<std::string> > &results() const { return m_results; }
|
||||
std::list<std::string> get(const ByteArray &key) const;
|
||||
std::list<std::string> get(const std::string &key) const;
|
||||
|
||||
protected:
|
||||
virtual void onReply(int statusCode, const ByteArray &data);
|
||||
|
@ -34,9 +34,7 @@
|
||||
#include "TorControl.h"
|
||||
#include "CryptoKey.h"
|
||||
#include "Useful.h"
|
||||
#include <QDir>
|
||||
#include <QTimer>
|
||||
#include <QDebug>
|
||||
#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;
|
||||
}
|
||||
|
@ -35,9 +35,7 @@
|
||||
|
||||
#include <QObject>
|
||||
#include <QHostAddress>
|
||||
#include <QList>
|
||||
#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; }
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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*)
|
||||
|
@ -33,7 +33,6 @@
|
||||
#include "ProtocolInfoCommand.h"
|
||||
#include "TorControl.h"
|
||||
#include "StrUtil.h"
|
||||
#include <QList>
|
||||
|
||||
using namespace Tor;
|
||||
|
||||
@ -55,14 +54,15 @@ void ProtocolInfoCommand::onReply(int statusCode, const ByteArray &data)
|
||||
|
||||
if (data.startsWith("AUTH "))
|
||||
{
|
||||
QList<ByteArray> tokens = splitQuotedStrings(data.mid(5), ' ');
|
||||
std::list<ByteArray> tokens = splitQuotedStrings(data.mid(5), ' ');
|
||||
|
||||
foreach (ByteArray token, tokens)
|
||||
{
|
||||
if (token.startsWith("METHODS="))
|
||||
{
|
||||
QList<ByteArray> textMethods = unquotedString(token.mid(8)).split(',');
|
||||
for (QList<ByteArray>::Iterator it = textMethods.begin(); it != textMethods.end(); ++it)
|
||||
std::list<ByteArray> textMethods = unquotedString(token.mid(8)).split(',');
|
||||
|
||||
for (std::list<ByteArray>::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();
|
||||
}
|
||||
}
|
||||
|
@ -34,7 +34,6 @@
|
||||
#define PROTOCOLINFOCOMMAND_H
|
||||
|
||||
#include "TorControlCommand.h"
|
||||
#include <QFlags>
|
||||
|
||||
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;
|
||||
};
|
||||
|
||||
}
|
||||
|
@ -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::pair<ByteArray, ByteArray> > { std::make_pair(key, value) } );
|
||||
return build(std::list<std::pair<std::string, std::string> > { std::make_pair(key, value) } );
|
||||
}
|
||||
|
||||
// ByteArray SetConfCommand::build(const std::list<std::pair<ByteArray,ByteArray> > &data)
|
||||
@ -74,7 +74,7 @@ ByteArray SetConfCommand::build(const ByteArray &key, const ByteArray &value)
|
||||
// return build(out);
|
||||
// }
|
||||
|
||||
ByteArray SetConfCommand::build(const std::list<std::pair<ByteArray, ByteArray> >& data)
|
||||
ByteArray SetConfCommand::build(const std::list<std::pair<std::string, std::string> >& data)
|
||||
{
|
||||
ByteArray out(m_resetMode ? "RESETCONF" : "SETCONF");
|
||||
|
||||
|
@ -54,8 +54,8 @@ public:
|
||||
|
||||
void setResetMode(bool resetMode);
|
||||
|
||||
ByteArray build(const ByteArray &key, const ByteArray &value);
|
||||
ByteArray build(const std::list<std::pair<ByteArray, ByteArray> > &data);
|
||||
ByteArray build(const std::string &key, const std::string &value);
|
||||
ByteArray build(const std::list<std::pair<std::string, std::string> > &data);
|
||||
|
||||
std::string errorMessage() const { return m_errorMessage; }
|
||||
bool isSuccessful() const;
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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<typename T> T read(const QString &key) const;
|
||||
Q_INVOKABLE void write(const QString &key, const QJsonValue &value);
|
||||
template<typename T> 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<typename T> T read(const std::string &key) const;
|
||||
Q_INVOKABLE void write(const std::string &key, const QJsonValue &value);
|
||||
template<typename T> 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<typename T> T read(const char *key) const
|
||||
{
|
||||
return read<T>(QString::fromLatin1(key));
|
||||
return read<T>(std::string(key));
|
||||
}
|
||||
void write(const char *key, const QJsonValue &value)
|
||||
{
|
||||
write(QString::fromLatin1(key), value);
|
||||
write(std::string(key), value);
|
||||
}
|
||||
template<typename T> void write(const char *key, const T &value)
|
||||
{
|
||||
write<T>(QString::fromLatin1(key), value);
|
||||
write<T>(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<typename T> inline void SettingsObject::write(const QString &key, const T &value)
|
||||
template<typename T> inline void SettingsObject::write(const std::string &key, const T &value)
|
||||
{
|
||||
write(key, QJsonValue(value));
|
||||
}
|
||||
|
||||
template<> inline QString SettingsObject::read<QString>(const QString &key) const
|
||||
template<> inline std::string SettingsObject::read<std::string>(const std::string &key) const
|
||||
{
|
||||
return read(key).toString();
|
||||
}
|
||||
|
||||
template<> inline QJsonArray SettingsObject::read<QJsonArray>(const QString &key) const
|
||||
template<> inline QJsonArray SettingsObject::read<QJsonArray>(const std::string &key) const
|
||||
{
|
||||
return read(key).toArray();
|
||||
}
|
||||
|
||||
template<> inline QJsonObject SettingsObject::read<QJsonObject>(const QString &key) const
|
||||
template<> inline QJsonObject SettingsObject::read<QJsonObject>(const std::string &key) const
|
||||
{
|
||||
return read(key).toObject();
|
||||
}
|
||||
|
||||
template<> inline double SettingsObject::read<double>(const QString &key) const
|
||||
template<> inline double SettingsObject::read<double>(const std::string &key) const
|
||||
{
|
||||
return read(key).toDouble();
|
||||
}
|
||||
|
||||
template<> inline int SettingsObject::read<int>(const QString &key) const
|
||||
template<> inline int SettingsObject::read<int>(const std::string &key) const
|
||||
{
|
||||
return read(key).toInt();
|
||||
}
|
||||
|
||||
template<> inline bool SettingsObject::read<bool>(const QString &key) const
|
||||
template<> inline bool SettingsObject::read<bool>(const std::string &key) const
|
||||
{
|
||||
return read(key).toBool();
|
||||
}
|
||||
|
||||
template<> inline QDateTime SettingsObject::read<QDateTime>(const QString &key) const
|
||||
template<> inline QDateTime SettingsObject::read<QDateTime>(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<QDateTime>(const QString &key, const QDateTime &value)
|
||||
template<> inline void SettingsObject::write<QDateTime>(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<Base64Encode>(const QString &key) const
|
||||
template<> inline Base64Encode SettingsObject::read<Base64Encode>(const std::string &key) const
|
||||
{
|
||||
return Base64Encode(QByteArray::fromBase64(read(key).toString().toLatin1()));
|
||||
}
|
||||
|
||||
template<> inline void SettingsObject::write<Base64Encode>(const QString &key, const Base64Encode &value)
|
||||
template<> inline void SettingsObject::write<Base64Encode>(const std::string &key, const Base64Encode &value)
|
||||
{
|
||||
write(key, QJsonValue(QString::fromLatin1(value.encoded())));
|
||||
write(key, QJsonValue(std::string(value.encoded())));
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@ -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;
|
||||
|
@ -31,6 +31,8 @@
|
||||
*/
|
||||
|
||||
#include <time.h>
|
||||
#include <fstream>
|
||||
#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<HiddenService*> services;
|
||||
quint16 controlPort, socksPort;
|
||||
TorControl::Status status;
|
||||
TorControl::TorStatus torStatus;
|
||||
QVariantMap bootstrapStatus;
|
||||
std::map<std::string,std::string> 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<ByteArray> &data);
|
||||
void updateBootstrap(const std::list<ByteArray> &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<HiddenService*> TorControl::hiddenServices() const
|
||||
return d->services;
|
||||
}
|
||||
|
||||
QVariantMap TorControl::bootstrapStatus() const
|
||||
std::map<std::string,std::string> 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<ByteArray> keys;
|
||||
keys << ByteArray("status/circuit-established") << ByteArray("status/bootstrap-phase");
|
||||
std::list<std::string> 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<ByteArray> listenAddresses = splitQuotedStrings(command->get(ByteArray("net/listeners/socks")).toString().toLatin1(), ' ');
|
||||
for (QList<ByteArray>::Iterator it = listenAddresses.begin(); it != listenAddresses.end(); ++it) {
|
||||
ByteArray value = unquotedString(*it);
|
||||
std::list<ByteArray> 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<QPair<ByteArray,ByteArray> > torConfig;
|
||||
std::list<std::pair<std::string,std::string> > 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<HiddenService::Target> &targets = service->targets();
|
||||
for (QList<HiddenService::Target>::ConstIterator tit = targets.begin(); tit != targets.end(); ++tit)
|
||||
const std::list<HiddenService::Target> &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<ByteArray> tokens = splitQuotedStrings(data.trimmed(), ' ');
|
||||
std::list<ByteArray> 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<ByteArray> &data)
|
||||
void TorControlPrivate::updateBootstrap(const std::list<ByteArray> &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<ByteArray> &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<std::pair<std::string,std::string> >& 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<ByteArray>() << "config-text" << "config-file"));
|
||||
|
||||
socket->sendCommand(command, command->build(std::list<std::string> { "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<std::pair<std::string,std::string> > 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);
|
||||
|
@ -38,6 +38,7 @@
|
||||
#include <QObject>
|
||||
#include <QHostAddress>
|
||||
#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<HiddenService*> 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<std::string, std::string> bootstrapStatus() const;
|
||||
Q_INVOKABLE QObject *getConfiguration(const std::string &options);
|
||||
Q_INVOKABLE QObject *setConfiguration(const std::list<std::pair<std::string, std::string> > &options);
|
||||
Q_INVOKABLE PendingOperation *saveConfiguration();
|
||||
|
||||
signals:
|
||||
|
@ -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();
|
||||
|
@ -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<TorControlCommand*> commandQueue;
|
||||
QHash<QByteArray,TorControlCommand*> eventCommands;
|
||||
std::map<ByteArray,TorControlCommand*> eventCommands;
|
||||
std::string m_errorMessage;
|
||||
TorControlCommand *currentCommand;
|
||||
bool inDataReply;
|
||||
@ -70,5 +71,3 @@ private:
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif // TORCONTROLSOCKET_H
|
||||
|
@ -31,6 +31,7 @@
|
||||
*/
|
||||
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
|
||||
// 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<std::string> 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<Tor::HiddenService*> 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<RsTorManagerEvent>();
|
||||
|
||||
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<std::string> RsTor::logMessages()
|
||||
{
|
||||
QStringList qs = instance()->logMessages();
|
||||
|
||||
std::list<std::string> 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()
|
||||
|
@ -38,7 +38,6 @@
|
||||
#include "retroshare/rstor.h"
|
||||
#include "HiddenService.h"
|
||||
|
||||
#include <QStringList>
|
||||
#include <QHostAddress>
|
||||
|
||||
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<std::string> 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:
|
||||
|
@ -30,6 +30,12 @@
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <unistd.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#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<std::string> TorProcess::extraSettings() const
|
||||
{
|
||||
return d->extraSettings;
|
||||
}
|
||||
|
||||
void TorProcess::setExtraSettings(const QStringList &settings)
|
||||
void TorProcess::setExtraSettings(const std::list<std::string> &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<std::string> 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);
|
||||
|
@ -36,6 +36,8 @@
|
||||
#include <QObject>
|
||||
#include <QHostAddress>
|
||||
|
||||
#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<std::string> extraSettings() const;
|
||||
void setExtraSettings(const std::list<std::string> &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();
|
||||
|
@ -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<std::string> 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:
|
||||
|
@ -1,8 +1,11 @@
|
||||
#pragma once
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <list>
|
||||
|
||||
#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<size();++i) if( res[i]<='z' && res[i]>='a') res[i] += 'A'-'a'; return res; }
|
||||
ByteArray toUpper() const { auto res = *this; for(uint32_t i=0;i<size();++i) if( res[i]<='z' && res[i]>='a') res[i] += int('A')-int('a'); return res; }
|
||||
ByteArray toLower() const { auto res = *this; for(uint32_t i=0;i<size();++i) if( res[i]<='Z' && res[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<ByteArray> split(unsigned char sep)
|
||||
{
|
||||
std::list<ByteArray> res;
|
||||
ByteArray current_block;
|
||||
|
||||
for(uint32_t i=0;i<size();++i)
|
||||
if(operator[](i) == sep)
|
||||
{
|
||||
res.push_back(current_block);
|
||||
current_block.clear();
|
||||
}
|
||||
else
|
||||
current_block += operator[](i);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
// Removes the following characters from the beginning and from the end of the array:
|
||||
// '\t', '\n', '\v', '\f', '\r', and ' '.
|
||||
|
||||
ByteArray trimmed() const
|
||||
{
|
||||
auto res(*this);
|
||||
|
||||
while(!res.empty() && ( res.back() == '\t' || res.back() == '\n' || res.back() == '\v'
|
||||
|| res.back() == '\f' || res.back() == '\r' || res.back() == ' ' ) )
|
||||
res.pop_back();
|
||||
|
||||
uint32_t i=0;
|
||||
|
||||
for(;i<res.size();++i)
|
||||
if(res[i] != '\t' && res[i] != '\n' && res[i] != '\v' && res[i] != '\f' && res[i] != '\r' && res[i] != ' ')
|
||||
break;
|
||||
|
||||
return res.mid(i);
|
||||
}
|
||||
|
||||
// Removes n bytes from the end of the array
|
||||
|
||||
void chop(uint32_t n)
|
||||
{
|
||||
resize(std::max(0,(int)size() - (int)n));
|
||||
}
|
||||
|
||||
// Returns the last index of a given byte, -1 if not found.
|
||||
|
||||
int lastIndexOf(unsigned char s)
|
||||
{
|
||||
for(int i=size()-1;i>=0;--i)
|
||||
if(operator[](i) == s)
|
||||
return i;
|
||||
|
||||
return -1;
|
||||
}
|
||||
};
|
||||
|
@ -84,6 +84,25 @@ bool std::filesystem::create_directories(const std::string& path)
|
||||
# include <filesystem>
|
||||
#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;
|
||||
|
@ -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.
|
||||
|
Loading…
Reference in New Issue
Block a user