mirror of
https://github.com/amnezia-vpn/amnezia-client.git
synced 2026-07-03 14:07:39 +02:00
Compare commits
3 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 4911aa5eaa | |||
| f18dbc1e15 | |||
| 9753c3feb6 |
+1
-1
Submodule client/3rd-prebuilt updated: b4156d4d09...fcf3022a27
@@ -361,7 +361,7 @@ void AmneziaApplication::initControllers()
|
||||
m_settings, m_configurator));
|
||||
m_engine->rootContext()->setContextProperty("ExportController", m_exportController.get());
|
||||
|
||||
m_settingsController.reset(new SettingsController(m_serversModel, m_containersModel, m_languageModel, m_sitesModel, m_settings));
|
||||
m_settingsController.reset(new SettingsController(m_serversModel, m_containersModel, m_languageModel, m_settings));
|
||||
m_engine->rootContext()->setContextProperty("SettingsController", m_settingsController.get());
|
||||
if (m_settingsController->isAutoConnectEnabled() && m_serversModel->getDefaultServerIndex() >= 0) {
|
||||
QTimer::singleShot(1000, this, [this]() { m_connectionController->openConnection(); });
|
||||
|
||||
@@ -0,0 +1,112 @@
|
||||
#include <QDebug>
|
||||
#include <QTcpServer>
|
||||
#include <QTcpSocket>
|
||||
|
||||
#include "managementserver.h"
|
||||
|
||||
ManagementServer::ManagementServer(QObject *parent) : QObject(parent),
|
||||
m_tcpServer(nullptr)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
ManagementServer::~ManagementServer()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
bool ManagementServer::isOpen() const
|
||||
{
|
||||
return (m_socket && m_socket->isOpen());
|
||||
}
|
||||
|
||||
void ManagementServer::stop()
|
||||
{
|
||||
if (m_tcpServer) m_tcpServer->close();
|
||||
}
|
||||
|
||||
void ManagementServer::onAcceptError(QAbstractSocket::SocketError socketError)
|
||||
{
|
||||
qDebug().noquote() << QString("Accept error: %1").arg(socketError);
|
||||
}
|
||||
|
||||
qint64 ManagementServer::writeCommand(const QString& message)
|
||||
{
|
||||
if (!isOpen()) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
const QString command = message + "\n";
|
||||
qint64 bytesWritten = m_socket->write(command.toStdString().c_str());
|
||||
m_socket->flush();
|
||||
return bytesWritten;
|
||||
}
|
||||
|
||||
void ManagementServer::onNewConnection()
|
||||
{
|
||||
qDebug() << "New incoming connection";
|
||||
|
||||
m_socket = QPointer<QTcpSocket>(m_tcpServer->nextPendingConnection());
|
||||
if (m_tcpServer) m_tcpServer->close();
|
||||
|
||||
QObject::connect(m_socket.data(), &QTcpSocket::disconnected, this, &ManagementServer::onSocketDisconnected);
|
||||
QObject::connect(m_socket.data(), &QTcpSocket::errorOccurred, this, &ManagementServer::onSocketError);
|
||||
QObject::connect(m_socket.data(), &QTcpSocket::readyRead, this, &ManagementServer::onReadyRead);
|
||||
}
|
||||
|
||||
void ManagementServer::onSocketError(QAbstractSocket::SocketError socketError)
|
||||
{
|
||||
Q_UNUSED(socketError)
|
||||
qDebug().noquote() << QString("Management server error: %1").arg(m_socket->errorString());
|
||||
}
|
||||
|
||||
void ManagementServer::onSocketDisconnected()
|
||||
{
|
||||
if (m_socket) m_socket->deleteLater();
|
||||
}
|
||||
|
||||
QPointer<QTcpSocket> ManagementServer::socket() const
|
||||
{
|
||||
if (!isOpen()) {
|
||||
return nullptr;
|
||||
}
|
||||
return m_socket;
|
||||
}
|
||||
|
||||
void ManagementServer::onReadyRead()
|
||||
{
|
||||
emit readyRead();
|
||||
}
|
||||
|
||||
bool ManagementServer::start(const QString& host, unsigned int port)
|
||||
{
|
||||
if (m_tcpServer) m_tcpServer->close();
|
||||
|
||||
m_tcpServer = QSharedPointer<QTcpServer>(new QTcpServer(this), [](QTcpServer *s){
|
||||
if (s) s->deleteLater();
|
||||
});
|
||||
m_tcpServer->setMaxPendingConnections(1);
|
||||
|
||||
connect(m_tcpServer.data(), SIGNAL(acceptError(QAbstractSocket::SocketError)), this, SLOT(onAcceptError(QAbstractSocket::SocketError)));
|
||||
connect(m_tcpServer.data(), SIGNAL(newConnection()), this, SLOT(onNewConnection()));
|
||||
|
||||
if (m_tcpServer->listen(QHostAddress(host), port)) {
|
||||
emit serverStarted();
|
||||
return true;
|
||||
}
|
||||
|
||||
qDebug().noquote() << QString("Can't start TCP server, %1,%2")
|
||||
.arg(m_tcpServer->serverError())
|
||||
.arg(m_tcpServer->errorString());
|
||||
return false;
|
||||
}
|
||||
|
||||
QString ManagementServer::readLine()
|
||||
{
|
||||
if (!isOpen()) {
|
||||
qDebug() << "Socket is not opened";
|
||||
return QString();
|
||||
}
|
||||
|
||||
return m_socket->readLine();
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
#ifndef MANAGEMENTSERVER_H
|
||||
#define MANAGEMENTSERVER_H
|
||||
|
||||
#include <QAbstractSocket>
|
||||
#include <QPointer>
|
||||
#include <QSharedPointer>
|
||||
#include <QString>
|
||||
|
||||
class QTcpServer;
|
||||
class QTcpSocket;
|
||||
|
||||
class ManagementServer : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit ManagementServer(QObject *parent = nullptr);
|
||||
~ManagementServer();
|
||||
|
||||
bool start(const QString& host, unsigned int port);
|
||||
void stop();
|
||||
bool isOpen() const;
|
||||
|
||||
QString readLine();
|
||||
qint64 writeCommand(const QString& message);
|
||||
|
||||
QPointer<QTcpSocket> socket() const;
|
||||
|
||||
signals:
|
||||
void readyRead();
|
||||
void serverStarted();
|
||||
|
||||
protected slots:
|
||||
void onAcceptError(QAbstractSocket::SocketError socketError);
|
||||
void onNewConnection();
|
||||
void onReadyRead();
|
||||
void onSocketDisconnected();
|
||||
void onSocketError(QAbstractSocket::SocketError socketError);
|
||||
|
||||
protected:
|
||||
QSharedPointer<QTcpServer> m_tcpServer;
|
||||
QPointer<QTcpSocket> m_socket;
|
||||
};
|
||||
|
||||
#endif // MANAGEMENTSERVER_H
|
||||
@@ -22,8 +22,6 @@ OpenVpnOverCloakProtocol::~OpenVpnOverCloakProtocol()
|
||||
|
||||
ErrorCode OpenVpnOverCloakProtocol::start()
|
||||
{
|
||||
|
||||
#if 0
|
||||
if (!QFileInfo::exists(cloakExecPath())) {
|
||||
setLastError(ErrorCode::CloakExecutableMissing);
|
||||
return lastError();
|
||||
@@ -79,12 +77,10 @@ ErrorCode OpenVpnOverCloakProtocol::start()
|
||||
|
||||
if (m_ckProcess.state() == QProcess::ProcessState::Running) {
|
||||
setConnectionState(Vpn::ConnectionState::Connecting);
|
||||
#endif
|
||||
|
||||
return OpenVpnProtocol::start();
|
||||
#if 0
|
||||
}
|
||||
else return ErrorCode::CloakExecutableMissing;
|
||||
#endif
|
||||
}
|
||||
|
||||
void OpenVpnOverCloakProtocol::stop()
|
||||
@@ -94,6 +90,16 @@ void OpenVpnOverCloakProtocol::stop()
|
||||
|
||||
qDebug() << "OpenVpnOverCloakProtocol::stop()";
|
||||
|
||||
#ifdef Q_OS_WIN
|
||||
Utils::signalCtrl(m_ckProcess.processId(), CTRL_C_EVENT);
|
||||
#endif
|
||||
|
||||
m_ckProcess.terminate();
|
||||
|
||||
if (Utils::processIsRunning(Utils::executable("ck-client", false))) {
|
||||
QThread::msleep(1000);
|
||||
Utils::killProcessByName(Utils::executable("ck-client", false));
|
||||
}
|
||||
}
|
||||
|
||||
QString OpenVpnOverCloakProtocol::cloakExecPath()
|
||||
|
||||
@@ -10,10 +10,11 @@
|
||||
#include "utilities.h"
|
||||
#include "version.h"
|
||||
|
||||
|
||||
OpenVpnProtocol::OpenVpnProtocol(const QJsonObject &configuration, QObject *parent) : VpnProtocol(configuration, parent)
|
||||
{
|
||||
readOpenVpnConfiguration(configuration);
|
||||
connect(&m_managementServer, &ManagementServer::readyRead, this,
|
||||
&OpenVpnProtocol::onReadyReadDataFromManagementServer);
|
||||
}
|
||||
|
||||
OpenVpnProtocol::~OpenVpnProtocol()
|
||||
@@ -24,6 +25,7 @@ OpenVpnProtocol::~OpenVpnProtocol()
|
||||
|
||||
QString OpenVpnProtocol::defaultConfigFileName()
|
||||
{
|
||||
// qDebug() << "OpenVpnProtocol::defaultConfigFileName" << defaultConfigPath() + QString("/%1.ovpn").arg(APPLICATION_NAME);
|
||||
return defaultConfigPath() + QString("/%1.ovpn").arg(APPLICATION_NAME);
|
||||
}
|
||||
|
||||
@@ -31,20 +33,25 @@ QString OpenVpnProtocol::defaultConfigPath()
|
||||
{
|
||||
QString p = QStandardPaths::writableLocation(QStandardPaths::AppDataLocation) + "/config";
|
||||
Utils::initializePath(p);
|
||||
|
||||
return p;
|
||||
}
|
||||
|
||||
void OpenVpnProtocol::stop()
|
||||
{
|
||||
qDebug() << "OpenVpnProtocol::stop()";
|
||||
setConnectionState(Vpn::ConnectionState::Disconnecting);
|
||||
|
||||
// TODO: need refactoring
|
||||
// sendTermSignal() will even return true while server connected ???
|
||||
if ((m_connectionState == Vpn::ConnectionState::Preparing) || (m_connectionState == Vpn::ConnectionState::Connecting)
|
||||
|| (m_connectionState == Vpn::ConnectionState::Connected)
|
||||
|| (m_connectionState == Vpn::ConnectionState::Reconnecting)) {
|
||||
if (!sendTermSignal()) {
|
||||
killOpenVpnProcess();
|
||||
QThread::msleep(10);
|
||||
}
|
||||
QThread::msleep(10);
|
||||
m_managementServer.stop();
|
||||
}
|
||||
setConnectionState(Vpn::ConnectionState::Disconnected);
|
||||
}
|
||||
@@ -79,30 +86,9 @@ void OpenVpnProtocol::readOpenVpnConfiguration(const QJsonObject &configuration)
|
||||
{
|
||||
if (configuration.contains(ProtocolProps::key_proto_config_data(Proto::OpenVpn))) {
|
||||
QJsonObject jConfig = configuration.value(ProtocolProps::key_proto_config_data(Proto::OpenVpn)).toObject();
|
||||
QString plainConfig = jConfig.value(config_key::config).toString().toUtf8();
|
||||
if (configuration.contains(ProtocolProps::key_proto_config_data(Proto::Cloak))) {
|
||||
QJsonObject cloakConfig = configuration.value(ProtocolProps::key_proto_config_data(Proto::Cloak)).toObject();
|
||||
cloakConfig["NumConn"] = 1;
|
||||
cloakConfig["ProxyMethod"] = "openvpn";
|
||||
if (cloakConfig.contains("port")) {
|
||||
int portValue = cloakConfig.value("port").toInt();
|
||||
cloakConfig.remove("port");
|
||||
cloakConfig["RemotePort"] = portValue;
|
||||
}
|
||||
if (cloakConfig.contains("remote")) {
|
||||
QString hostValue = cloakConfig.value("remote").toString();
|
||||
cloakConfig.remove("remote");
|
||||
cloakConfig["RemoteHost"] = hostValue;
|
||||
}
|
||||
plainConfig += "\n<cloak>\n";
|
||||
QJsonDocument Doc(cloakConfig);
|
||||
QByteArray ba = Doc.toJson();
|
||||
QString plainCloak = ba;
|
||||
plainConfig += QString::fromLatin1(plainCloak.toUtf8().toBase64().data());
|
||||
plainConfig += "\n</cloak>\n";
|
||||
}
|
||||
|
||||
m_configFile.open();
|
||||
m_configFile.write(plainConfig.toUtf8());
|
||||
m_configFile.write(jConfig.value(config_key::config).toString().toUtf8());
|
||||
m_configFile.close();
|
||||
m_configFileName = m_configFile.fileName();
|
||||
|
||||
@@ -112,69 +98,60 @@ void OpenVpnProtocol::readOpenVpnConfiguration(const QJsonObject &configuration)
|
||||
|
||||
bool OpenVpnProtocol::openVpnProcessIsRunning() const
|
||||
{
|
||||
return Utils::processIsRunning("ovpncli");
|
||||
return Utils::processIsRunning("openvpn");
|
||||
}
|
||||
|
||||
void OpenVpnProtocol::disconnectFromManagementServer()
|
||||
{
|
||||
m_managementServer.stop();
|
||||
}
|
||||
|
||||
QString OpenVpnProtocol::configPath() const
|
||||
{
|
||||
return m_configFileName;
|
||||
}
|
||||
|
||||
void OpenVpnProtocol::sendManagementCommand(const QString &command)
|
||||
{
|
||||
QIODevice *device = dynamic_cast<QIODevice *>(m_managementServer.socket().data());
|
||||
if (device) {
|
||||
QTextStream stream(device);
|
||||
stream << command << Qt::endl;
|
||||
}
|
||||
}
|
||||
|
||||
uint OpenVpnProtocol::selectMgmtPort()
|
||||
{
|
||||
|
||||
for (int i = 0; i < 100; ++i) {
|
||||
quint32 port = QRandomGenerator::global()->generate();
|
||||
port = (double)(65000 - 15001) * port / UINT32_MAX + 15001;
|
||||
|
||||
QTcpServer s;
|
||||
bool ok = s.listen(QHostAddress::LocalHost, port);
|
||||
if (ok)
|
||||
return port;
|
||||
}
|
||||
|
||||
return m_managementPort;
|
||||
}
|
||||
|
||||
void OpenVpnProtocol::updateRouteGateway(QString line)
|
||||
{
|
||||
const QString substr = "sitnl_route_best_gw result: via ";
|
||||
int start = line.indexOf(substr) + substr.size();
|
||||
int end = line.indexOf(" dev ", start);
|
||||
|
||||
m_routeGateway = line.mid(start, (end-start));
|
||||
}
|
||||
|
||||
void OpenVpnProtocol::handle_cli_message(QString message)
|
||||
{
|
||||
QString line = message;
|
||||
|
||||
if (line.isEmpty()) {
|
||||
// TODO: fix for macos
|
||||
line = line.split("ROUTE_GATEWAY", Qt::SkipEmptyParts).at(1);
|
||||
if (!line.contains("/"))
|
||||
return;
|
||||
}
|
||||
|
||||
if (line.contains("EVENT: CONNECTED")) {
|
||||
setConnectionState(Vpn::ConnectionState::Connected);
|
||||
} else if (line.contains("EXITING")) {
|
||||
// openVpnStateSigTermHandler();
|
||||
setConnectionState(Vpn::ConnectionState::Disconnecting);
|
||||
} else if (line.contains("RECONNECTING")) {
|
||||
setConnectionState(Vpn::ConnectionState::Reconnecting);
|
||||
}
|
||||
|
||||
if (line.contains("sitnl_route_best_gw")) {
|
||||
updateRouteGateway(line);
|
||||
}
|
||||
|
||||
if (line.contains("[ifconfig]")) {
|
||||
updateVpnGateway(line);
|
||||
}
|
||||
|
||||
// TODO: SET CORRECT STRING
|
||||
if (line.contains("FATAL")) {
|
||||
if (line.contains("tap-windows6 adapters on this system are currently in use or disabled")) {
|
||||
emit protocolError(ErrorCode::OpenVpnAdaptersInUseError);
|
||||
} else {
|
||||
emit protocolError(ErrorCode::OpenVpnUnknownError);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
m_routeGateway = line.split("/", Qt::SkipEmptyParts).first();
|
||||
m_routeGateway.replace(" ", "");
|
||||
qDebug() << "Set VPN route gateway" << m_routeGateway;
|
||||
}
|
||||
|
||||
|
||||
ErrorCode OpenVpnProtocol::start()
|
||||
{
|
||||
// qDebug() << "Start OpenVPN connection";
|
||||
OpenVpnProtocol::stop();
|
||||
|
||||
qDebug() << " Utils::openVpnExecPath();" << Utils::openVpnExecPath();
|
||||
|
||||
if (!QFileInfo::exists(Utils::openVpnExecPath())) {
|
||||
setLastError(ErrorCode::OpenVpnExecutableMissing);
|
||||
return lastError();
|
||||
@@ -207,11 +184,23 @@ ErrorCode OpenVpnProtocol::start()
|
||||
}
|
||||
#endif
|
||||
|
||||
// QString vpnLogFileNamePath = Utils::systemLogPath() + "/openvpn.log";
|
||||
// Utils::createEmptyFile(vpnLogFileNamePath);
|
||||
|
||||
uint mgmtPort = selectMgmtPort();
|
||||
qDebug() << "OpenVpnProtocol::start mgmt port selected:" << mgmtPort;
|
||||
|
||||
if (!m_managementServer.start(m_managementHost, mgmtPort)) {
|
||||
setLastError(ErrorCode::OpenVpnManagementServerError);
|
||||
return lastError();
|
||||
}
|
||||
|
||||
setConnectionState(Vpn::ConnectionState::Connecting);
|
||||
|
||||
m_openVpnProcess = IpcClient::CreatePrivilegedProcess();
|
||||
|
||||
if (!m_openVpnProcess) {
|
||||
qWarning() << "IpcProcess replica is not created!";
|
||||
// qWarning() << "IpcProcess replica is not created!";
|
||||
setLastError(ErrorCode::AmneziaServiceConnectionFailed);
|
||||
return ErrorCode::AmneziaServiceConnectionFailed;
|
||||
}
|
||||
@@ -223,100 +212,122 @@ ErrorCode OpenVpnProtocol::start()
|
||||
return ErrorCode::AmneziaServiceConnectionFailed;
|
||||
}
|
||||
m_openVpnProcess->setProgram(PermittedProcess::OpenVPN);
|
||||
QStringList arguments({ configPath()/*, "--management", m_managementHost, QString::number(mgmtPort),
|
||||
"--management-client" *//*, "--log", vpnLogFileNamePath */
|
||||
QStringList arguments({
|
||||
"--config", configPath(), "--management", m_managementHost, QString::number(mgmtPort),
|
||||
"--management-client" /*, "--log", vpnLogFileNamePath */
|
||||
});
|
||||
m_openVpnProcess->setArguments(arguments);
|
||||
|
||||
qDebug() << arguments.join(" ");
|
||||
connect(m_openVpnProcess.data(), &PrivilegedProcess::errorOccurred,
|
||||
[&](QProcess::ProcessError error) {
|
||||
qDebug() << "PrivilegedProcess errorOccurred" << error;
|
||||
setConnectionState(Vpn::ConnectionState::Disconnected);
|
||||
});
|
||||
[&](QProcess::ProcessError error) { qDebug() << "PrivilegedProcess errorOccurred" << error; });
|
||||
|
||||
connect(m_openVpnProcess.data(), &PrivilegedProcess::stateChanged, [&](QProcess::ProcessState newState) {
|
||||
switch ( newState )
|
||||
{
|
||||
case QProcess::Starting:
|
||||
setConnectionState(Vpn::ConnectionState::Connecting);
|
||||
break;
|
||||
case QProcess::Running:
|
||||
setConnectionState(Vpn::ConnectionState::Connecting);
|
||||
break;
|
||||
default:
|
||||
setConnectionState(Vpn::ConnectionState::Disconnected);
|
||||
}
|
||||
qDebug() << "PrivilegedProcess stateChanged" << newState;
|
||||
});
|
||||
connect(m_openVpnProcess.data(), &PrivilegedProcess::stateChanged,
|
||||
[&](QProcess::ProcessState newState) { qDebug() << "PrivilegedProcess stateChanged" << newState; });
|
||||
|
||||
connect(m_openVpnProcess.data(), &PrivilegedProcess::finished, this,
|
||||
[&]() { setConnectionState(Vpn::ConnectionState::Disconnected); });
|
||||
|
||||
|
||||
connect(m_openVpnProcess.data(), &PrivilegedProcess::readyRead, this, [&] {
|
||||
|
||||
QRemoteObjectPendingReply<QByteArray> call = m_openVpnProcess->readAll();
|
||||
auto *watcher = new QRemoteObjectPendingCallWatcher(call, this);
|
||||
|
||||
auto *timeoutTimer = new QTimer(this);
|
||||
timeoutTimer->setSingleShot(true);
|
||||
m_watchers.insert(watcher, timeoutTimer);
|
||||
|
||||
connect(timeoutTimer, &QTimer::timeout, this, [this, watcher, timeoutTimer]() {
|
||||
qDebug() << "Foo request timed out.";
|
||||
|
||||
m_watchers.remove(watcher);
|
||||
watcher->deleteLater();
|
||||
timeoutTimer->deleteLater();
|
||||
});
|
||||
|
||||
connect(watcher, &QRemoteObjectPendingCallWatcher::finished, [this](QRemoteObjectPendingCallWatcher *self) {
|
||||
QTimer *timer = m_watchers.take(self);
|
||||
if (timer) {
|
||||
timer->stop();
|
||||
timer->deleteLater();
|
||||
}
|
||||
|
||||
QByteArray result = self->returnValue().toByteArray();
|
||||
handle_cli_message(QString(result));
|
||||
self->deleteLater();
|
||||
});
|
||||
|
||||
timeoutTimer->start(30000);
|
||||
|
||||
});
|
||||
|
||||
connect(m_openVpnProcess.data(), QOverload<int, QProcess::ExitStatus>::of(&PrivilegedProcess::finished), this, [this](int exitCode, QProcess::ExitStatus exitStatus) {
|
||||
qDebug().noquote() << "OpenVPN finished, exitCode, exiStatus" << exitCode << exitStatus;
|
||||
setConnectionState(Vpn::ConnectionState::Disconnected);
|
||||
if (exitStatus != QProcess::NormalExit) {
|
||||
emit protocolError(amnezia::ErrorCode::ShadowSocksExecutableCrashed);
|
||||
stop();
|
||||
}
|
||||
if (exitCode !=0 ) {
|
||||
emit protocolError(amnezia::ErrorCode::InternalError);
|
||||
stop();
|
||||
}
|
||||
});
|
||||
|
||||
m_openVpnProcess->start();
|
||||
|
||||
// startTimeoutTimer();
|
||||
|
||||
return ErrorCode::NoError;
|
||||
}
|
||||
|
||||
bool OpenVpnProtocol::sendTermSignal()
|
||||
{
|
||||
return m_managementServer.writeCommand("signal SIGTERM");
|
||||
}
|
||||
|
||||
void OpenVpnProtocol::sendByteCount()
|
||||
{
|
||||
m_managementServer.writeCommand("bytecount 1");
|
||||
}
|
||||
|
||||
void OpenVpnProtocol::sendInitialData()
|
||||
{
|
||||
m_managementServer.writeCommand("state on");
|
||||
m_managementServer.writeCommand("log on");
|
||||
}
|
||||
|
||||
void OpenVpnProtocol::onReadyReadDataFromManagementServer()
|
||||
{
|
||||
for (;;) {
|
||||
QString line = m_managementServer.readLine().simplified();
|
||||
|
||||
if (line.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!line.contains(">BYTECOUNT")) {
|
||||
qDebug().noquote() << line;
|
||||
}
|
||||
|
||||
if (line.contains(">INFO:OpenVPN Management Interface")) {
|
||||
sendInitialData();
|
||||
} else if (line.startsWith(">STATE")) {
|
||||
if (line.contains("CONNECTED,SUCCESS")) {
|
||||
sendByteCount();
|
||||
stopTimeoutTimer();
|
||||
setConnectionState(Vpn::ConnectionState::Connected);
|
||||
continue;
|
||||
} else if (line.contains("EXITING,SIGTER")) {
|
||||
// openVpnStateSigTermHandler();
|
||||
setConnectionState(Vpn::ConnectionState::Disconnecting);
|
||||
continue;
|
||||
} else if (line.contains("RECONNECTING")) {
|
||||
setConnectionState(Vpn::ConnectionState::Reconnecting);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if (line.contains("ROUTE_GATEWAY")) {
|
||||
updateRouteGateway(line);
|
||||
}
|
||||
|
||||
if (line.contains("PUSH: Received control message")) {
|
||||
updateVpnGateway(line);
|
||||
}
|
||||
|
||||
if (line.contains("FATAL")) {
|
||||
if (line.contains("tap-windows6 adapters on this system are currently in use or disabled")) {
|
||||
emit protocolError(ErrorCode::OpenVpnAdaptersInUseError);
|
||||
} else {
|
||||
emit protocolError(ErrorCode::OpenVpnUnknownError);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
QByteArray data(line.toStdString().c_str());
|
||||
if (data.contains(">BYTECOUNT:")) {
|
||||
int beg = data.lastIndexOf(">BYTECOUNT:");
|
||||
int end = data.indexOf("\n", beg);
|
||||
|
||||
beg += sizeof(">BYTECOUNT:") - 1;
|
||||
QList<QByteArray> count = data.mid(beg, end - beg + 1).split(',');
|
||||
|
||||
quint64 r = static_cast<quint64>(count.at(0).trimmed().toULongLong());
|
||||
quint64 s = static_cast<quint64>(count.at(1).trimmed().toULongLong());
|
||||
|
||||
setBytesChanged(r, s);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void OpenVpnProtocol::updateVpnGateway(const QString &line)
|
||||
{
|
||||
// "[ifconfig] [10.8.0.14] [10.8.0.13]"
|
||||
QStringList params = line.split("\n");
|
||||
for (const QString ¶m : params) {
|
||||
if (param.contains("ifconfig")) {
|
||||
QString l = param.right(param.size() - param.indexOf("ifconfig"));
|
||||
// line looks like
|
||||
// PUSH: Received control message: 'PUSH_REPLY,route 10.8.0.1,topology net30,ping 10,ping-restart
|
||||
// 120,ifconfig 10.8.0.6 10.8.0.5,peer-id 0,cipher AES-256-GCM'
|
||||
|
||||
QStringList params = line.split(",");
|
||||
for (const QString &l : params) {
|
||||
if (l.contains("ifconfig")) {
|
||||
if (l.split(" ").size() == 3) {
|
||||
m_vpnLocalAddress = l.split(" ").at(1);
|
||||
m_vpnLocalAddress.remove("[");m_vpnLocalAddress.remove("]");
|
||||
m_vpnGateway = l.split(" ").at(2);
|
||||
m_vpnGateway.remove("[");m_vpnGateway.remove("]");
|
||||
|
||||
qDebug() << QString("Set vpn local address %1, gw %2").arg(m_vpnLocalAddress).arg(vpnGateway());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
#include <QString>
|
||||
#include <QTimer>
|
||||
|
||||
#include "managementserver.h"
|
||||
#include "vpnprotocol.h"
|
||||
|
||||
#include "core/ipcclient.h"
|
||||
@@ -24,21 +25,28 @@ public:
|
||||
static QString defaultConfigFileName();
|
||||
static QString defaultConfigPath();
|
||||
|
||||
protected slots:
|
||||
void onReadyReadDataFromManagementServer();
|
||||
|
||||
private:
|
||||
QString configPath() const;
|
||||
bool openVpnProcessIsRunning() const;
|
||||
bool sendTermSignal();
|
||||
void readOpenVpnConfiguration(const QJsonObject &configuration);
|
||||
void handle_cli_message(QString message);
|
||||
void disconnectFromManagementServer();
|
||||
void killOpenVpnProcess();
|
||||
void sendByteCount();
|
||||
void sendInitialData();
|
||||
void sendManagementCommand(const QString& command);
|
||||
|
||||
QHash<QRemoteObjectPendingCallWatcher*, QTimer*> m_watchers;
|
||||
const QString m_managementHost = "127.0.0.1";
|
||||
const unsigned int m_managementPort = 57775;
|
||||
|
||||
ManagementServer m_managementServer;
|
||||
QString m_configFileName;
|
||||
QTemporaryFile m_configFile;
|
||||
|
||||
uint selectMgmtPort();
|
||||
|
||||
private:
|
||||
void updateRouteGateway(QString line);
|
||||
|
||||
+15
-15
@@ -25,7 +25,8 @@ SecureQSettings::SecureQSettings(const QString &organization, const QString &app
|
||||
if (encryptionRequired() && !encrypted) {
|
||||
for (const QString &key : m_settings.allKeys()) {
|
||||
if (encryptedKeys.contains(key)) {
|
||||
const QVariant &val = value(key);
|
||||
QVariant val;
|
||||
value(key, val);
|
||||
setValue(key, val);
|
||||
}
|
||||
}
|
||||
@@ -34,16 +35,18 @@ SecureQSettings::SecureQSettings(const QString &organization, const QString &app
|
||||
}
|
||||
}
|
||||
|
||||
QVariant SecureQSettings::value(const QString &key, const QVariant &defaultValue) const
|
||||
void SecureQSettings::value(const QString &key, QVariant &returnValue, const QVariant &defaultValue) const
|
||||
{
|
||||
QMutexLocker locker(&mutex);
|
||||
|
||||
if (m_cache.contains(key)) {
|
||||
return m_cache.value(key);
|
||||
returnValue = m_cache.value(key);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!m_settings.contains(key)) {
|
||||
returnValue = defaultValue;
|
||||
return;
|
||||
}
|
||||
|
||||
if (!m_settings.contains(key))
|
||||
return defaultValue;
|
||||
|
||||
QVariant retVal;
|
||||
|
||||
@@ -54,7 +57,7 @@ QVariant SecureQSettings::value(const QString &key, const QVariant &defaultValue
|
||||
|
||||
if (getEncKey().isEmpty() || getEncIv().isEmpty()) {
|
||||
qCritical() << "SecureQSettings::setValue Decryption requested, but key is empty";
|
||||
return {};
|
||||
return;
|
||||
}
|
||||
|
||||
QByteArray encryptedValue = retVal.toByteArray().mid(magicString.size());
|
||||
@@ -75,13 +78,11 @@ QVariant SecureQSettings::value(const QString &key, const QVariant &defaultValue
|
||||
}
|
||||
|
||||
m_cache.insert(key, retVal);
|
||||
return retVal;
|
||||
returnValue = retVal;
|
||||
}
|
||||
|
||||
void SecureQSettings::setValue(const QString &key, const QVariant &value)
|
||||
{
|
||||
QMutexLocker locker(&mutex);
|
||||
|
||||
if (encryptionRequired() && encryptedKeys.contains(key)) {
|
||||
if (!getEncKey().isEmpty() && !getEncIv().isEmpty()) {
|
||||
QByteArray decryptedValue;
|
||||
@@ -107,8 +108,6 @@ void SecureQSettings::setValue(const QString &key, const QVariant &value)
|
||||
|
||||
void SecureQSettings::remove(const QString &key)
|
||||
{
|
||||
QMutexLocker locker(&mutex);
|
||||
|
||||
m_settings.remove(key);
|
||||
m_cache.remove(key);
|
||||
|
||||
@@ -125,7 +124,9 @@ QByteArray SecureQSettings::backupAppConfig() const
|
||||
QJsonObject cfg;
|
||||
|
||||
for (const QString &key : m_settings.allKeys()) {
|
||||
cfg.insert(key, QJsonValue::fromVariant(value(key)));
|
||||
QVariant v;
|
||||
value(key, v);
|
||||
cfg.insert(key, QJsonValue::fromVariant(v));
|
||||
}
|
||||
|
||||
return QJsonDocument(cfg).toJson();
|
||||
@@ -253,7 +254,6 @@ void SecureQSettings::setSecTag(const QString &tag, const QByteArray &data)
|
||||
|
||||
void SecureQSettings::clearSettings()
|
||||
{
|
||||
QMutexLocker locker(&mutex);
|
||||
m_settings.clear();
|
||||
m_cache.clear();
|
||||
sync();
|
||||
|
||||
@@ -20,8 +20,9 @@ public:
|
||||
explicit SecureQSettings(const QString &organization, const QString &application = QString(),
|
||||
QObject *parent = nullptr);
|
||||
|
||||
Q_INVOKABLE QVariant value(const QString &key, const QVariant &defaultValue = QVariant()) const;
|
||||
Q_INVOKABLE void value(const QString &key, QVariant &eturnValue, const QVariant &defaultValue = QVariant()) const;
|
||||
Q_INVOKABLE void setValue(const QString &key, const QVariant &value);
|
||||
|
||||
void remove(const QString &key);
|
||||
void sync();
|
||||
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
if which apt-get > /dev/null 2>&1; then LOCK_FILE="/var/lib/dpkg/lock-frontend";\
|
||||
elif which dnf > /dev/null 2>&1; then LOCK_FILE="/var/run/dnf.pid";\
|
||||
elif which yum > /dev/null 2>&1; then LOCK_FILE="/var/run/yum.pid";\
|
||||
elif which pacman > /dev/null 2>&1; then LOCK_FILE="/var/lib/pacman/db.lck";\
|
||||
else echo "Packet manager not found"; echo "Internal error"; exit 1; fi;\
|
||||
if command -v fuser > /dev/null 2>&1; then sudo fuser $LOCK_FILE 2>/dev/null; else echo "fuser not installed"; fi
|
||||
if command -v fuser > /dev/null 2>&1; then sudo fuser $LOCK_FILE 2>/dev/null; else echo "fuser not installed"; fi
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
if which apt-get > /dev/null 2>&1; then pm=$(which apt-get); silent_inst="-yq install"; check_pkgs="-yq update"; docker_pkg="docker.io"; dist="debian";\
|
||||
elif which dnf > /dev/null 2>&1; then pm=$(which dnf); silent_inst="-yq install"; check_pkgs="-yq check-update"; docker_pkg="docker"; dist="fedora";\
|
||||
elif which yum > /dev/null 2>&1; then pm=$(which yum); silent_inst="-y -q install"; check_pkgs="-y -q check-update"; docker_pkg="docker"; dist="centos";\
|
||||
elif which pacman > /dev/null 2>&1; then pm=$(which pacman); silent_inst="-S --noconfirm --noprogressbar --quiet"; check_pkgs="> /dev/null 2>&1"; docker_pkg="docker"; dist="archlinux";\
|
||||
else echo "Packet manager not found"; exit 1; fi;\
|
||||
echo "Dist: $dist, Packet manager: $pm, Install command: $silent_inst, Check pkgs command: $check_pkgs, Docker pkg: $docker_pkg";\
|
||||
if [ "$dist" = "debian" ]; then export DEBIAN_FRONTEND=noninteractive; fi;\
|
||||
|
||||
+25
-17
@@ -39,12 +39,12 @@ Settings::Settings(QObject *parent) : QObject(parent), m_settings(ORGANIZATION_N
|
||||
}
|
||||
}
|
||||
|
||||
int Settings::serversCount() const
|
||||
int Settings::serversCount()
|
||||
{
|
||||
return serversArray().size();
|
||||
}
|
||||
|
||||
QJsonObject Settings::server(int index) const
|
||||
QJsonObject Settings::server(int index)
|
||||
{
|
||||
const QJsonArray &servers = serversArray();
|
||||
if (index >= servers.size())
|
||||
@@ -88,12 +88,12 @@ void Settings::setDefaultContainer(int serverIndex, DockerContainer container)
|
||||
editServer(serverIndex, s);
|
||||
}
|
||||
|
||||
DockerContainer Settings::defaultContainer(int serverIndex) const
|
||||
DockerContainer Settings::defaultContainer(int serverIndex)
|
||||
{
|
||||
return ContainerProps::containerFromString(defaultContainerName(serverIndex));
|
||||
}
|
||||
|
||||
QString Settings::defaultContainerName(int serverIndex) const
|
||||
QString Settings::defaultContainerName(int serverIndex)
|
||||
{
|
||||
QString name = server(serverIndex).value(config_key::defaultContainer).toString();
|
||||
if (name.isEmpty()) {
|
||||
@@ -102,7 +102,7 @@ QString Settings::defaultContainerName(int serverIndex) const
|
||||
return name;
|
||||
}
|
||||
|
||||
QMap<DockerContainer, QJsonObject> Settings::containers(int serverIndex) const
|
||||
QMap<DockerContainer, QJsonObject> Settings::containers(int serverIndex)
|
||||
{
|
||||
const QJsonArray &containers = server(serverIndex).value(config_key::containers).toArray();
|
||||
|
||||
@@ -186,7 +186,7 @@ void Settings::clearLastConnectionConfig(int serverIndex, DockerContainer contai
|
||||
setProtocolConfig(serverIndex, container, proto, c);
|
||||
}
|
||||
|
||||
bool Settings::haveAuthData(int serverIndex) const
|
||||
bool Settings::haveAuthData(int serverIndex)
|
||||
{
|
||||
if (serverIndex < 0)
|
||||
return false;
|
||||
@@ -194,7 +194,7 @@ bool Settings::haveAuthData(int serverIndex) const
|
||||
return (!cred.hostName.isEmpty() && !cred.userName.isEmpty() && !cred.secretData.isEmpty());
|
||||
}
|
||||
|
||||
QString Settings::nextAvailableServerName() const
|
||||
QString Settings::nextAvailableServerName()
|
||||
{
|
||||
int i = 0;
|
||||
bool nameExist = false;
|
||||
@@ -226,7 +226,7 @@ void Settings::setSaveLogs(bool enabled)
|
||||
emit saveLogsChanged();
|
||||
}
|
||||
|
||||
QString Settings::routeModeString(RouteMode mode) const
|
||||
QString Settings::routeModeString(RouteMode mode)
|
||||
{
|
||||
switch (mode) {
|
||||
case VpnAllSites: return "AllSites";
|
||||
@@ -235,7 +235,7 @@ QString Settings::routeModeString(RouteMode mode) const
|
||||
}
|
||||
}
|
||||
|
||||
Settings::RouteMode Settings::routeMode() const
|
||||
Settings::RouteMode Settings::routeMode()
|
||||
{
|
||||
return static_cast<RouteMode>(value("Conf/routeMode", 0).toInt());
|
||||
}
|
||||
@@ -267,7 +267,7 @@ void Settings::addVpnSites(RouteMode mode, const QMap<QString, QString> &sites)
|
||||
setVpnSites(mode, allSites);
|
||||
}
|
||||
|
||||
QStringList Settings::getVpnIps(RouteMode mode) const
|
||||
QStringList Settings::getVpnIps(RouteMode mode)
|
||||
{
|
||||
QStringList ips;
|
||||
const QVariantMap &m = vpnSites(mode);
|
||||
@@ -323,12 +323,12 @@ void Settings::removeAllVpnSites(RouteMode mode)
|
||||
setVpnSites(mode, QVariantMap());
|
||||
}
|
||||
|
||||
QString Settings::primaryDns() const
|
||||
QString Settings::primaryDns()
|
||||
{
|
||||
return value("Conf/primaryDns", cloudFlareNs1).toString();
|
||||
}
|
||||
|
||||
QString Settings::secondaryDns() const
|
||||
QString Settings::secondaryDns()
|
||||
{
|
||||
return value("Conf/secondaryDns", cloudFlareNs2).toString();
|
||||
}
|
||||
@@ -338,12 +338,12 @@ void Settings::clearSettings()
|
||||
m_settings.clearSettings();
|
||||
}
|
||||
|
||||
ServerCredentials Settings::defaultServerCredentials() const
|
||||
ServerCredentials Settings::defaultServerCredentials()
|
||||
{
|
||||
return serverCredentials(defaultServerIndex());
|
||||
}
|
||||
|
||||
ServerCredentials Settings::serverCredentials(int index) const
|
||||
ServerCredentials Settings::serverCredentials(int index)
|
||||
{
|
||||
const QJsonObject &s = server(index);
|
||||
|
||||
@@ -356,18 +356,26 @@ ServerCredentials Settings::serverCredentials(int index) const
|
||||
return credentials;
|
||||
}
|
||||
|
||||
QVariant Settings::value(const QString &key, const QVariant &defaultValue) const
|
||||
QVariant Settings::value(const QString &key, const QVariant &defaultValue)
|
||||
{
|
||||
QVariant returnValue;
|
||||
// if (defaultValue.isNull() || !defaultValue.isValid()) {
|
||||
// QMetaObject::invokeMethod(&m_settings, "value",
|
||||
// Qt::QueuedConnection,
|
||||
// Q_ARG(const QString&, key),
|
||||
// Q_ARG(QVariant, returnValue));
|
||||
// } else {
|
||||
|
||||
if (QThread::currentThread() == QCoreApplication::instance()->thread()) {
|
||||
returnValue = m_settings.value(key, defaultValue);
|
||||
m_settings.value(key, returnValue, defaultValue);
|
||||
} else {
|
||||
QMetaObject::invokeMethod(&m_settings, "value",
|
||||
Qt::BlockingQueuedConnection,
|
||||
Q_RETURN_ARG(QVariant, returnValue),
|
||||
Q_ARG(const QString&, key),
|
||||
Q_ARG(QVariant&, returnValue),
|
||||
Q_ARG(const QVariant&, defaultValue));
|
||||
}
|
||||
// }
|
||||
return returnValue;
|
||||
}
|
||||
|
||||
|
||||
+29
-29
@@ -24,10 +24,10 @@ class Settings : public QObject
|
||||
public:
|
||||
explicit Settings(QObject *parent = nullptr);
|
||||
|
||||
ServerCredentials defaultServerCredentials() const;
|
||||
ServerCredentials serverCredentials(int index) const;
|
||||
ServerCredentials defaultServerCredentials();
|
||||
ServerCredentials serverCredentials(int index);
|
||||
|
||||
QJsonArray serversArray() const
|
||||
QJsonArray serversArray()
|
||||
{
|
||||
return QJsonDocument::fromJson(value("Servers/serversList").toByteArray()).array();
|
||||
}
|
||||
@@ -37,13 +37,13 @@ public:
|
||||
}
|
||||
|
||||
// Servers section
|
||||
int serversCount() const;
|
||||
QJsonObject server(int index) const;
|
||||
int serversCount();
|
||||
QJsonObject server(int index);
|
||||
void addServer(const QJsonObject &server);
|
||||
void removeServer(int index);
|
||||
bool editServer(int index, const QJsonObject &server);
|
||||
|
||||
int defaultServerIndex() const
|
||||
int defaultServerIndex()
|
||||
{
|
||||
return value("Servers/defaultServerIndex", 0).toInt();
|
||||
}
|
||||
@@ -51,16 +51,16 @@ public:
|
||||
{
|
||||
setValue("Servers/defaultServerIndex", index);
|
||||
}
|
||||
QJsonObject defaultServer() const
|
||||
QJsonObject defaultServer()
|
||||
{
|
||||
return server(defaultServerIndex());
|
||||
}
|
||||
|
||||
void setDefaultContainer(int serverIndex, DockerContainer container);
|
||||
DockerContainer defaultContainer(int serverIndex) const;
|
||||
QString defaultContainerName(int serverIndex) const;
|
||||
DockerContainer defaultContainer(int serverIndex);
|
||||
QString defaultContainerName(int serverIndex);
|
||||
|
||||
QMap<DockerContainer, QJsonObject> containers(int serverIndex) const;
|
||||
QMap<DockerContainer, QJsonObject> containers(int serverIndex);
|
||||
void setContainers(int serverIndex, const QMap<DockerContainer, QJsonObject> &containers);
|
||||
|
||||
QJsonObject containerConfig(int serverIndex, DockerContainer container);
|
||||
@@ -72,11 +72,11 @@ public:
|
||||
|
||||
void clearLastConnectionConfig(int serverIndex, DockerContainer container, Proto proto = Proto::Any);
|
||||
|
||||
bool haveAuthData(int serverIndex) const;
|
||||
QString nextAvailableServerName() const;
|
||||
bool haveAuthData(int serverIndex);
|
||||
QString nextAvailableServerName();
|
||||
|
||||
// App settings section
|
||||
bool isAutoConnect() const
|
||||
bool isAutoConnect()
|
||||
{
|
||||
return value("Conf/autoConnect", false).toBool();
|
||||
}
|
||||
@@ -85,7 +85,7 @@ public:
|
||||
setValue("Conf/autoConnect", enabled);
|
||||
}
|
||||
|
||||
bool isStartMinimized() const
|
||||
bool isStartMinimized()
|
||||
{
|
||||
return value("Conf/startMinimized", false).toBool();
|
||||
}
|
||||
@@ -94,7 +94,7 @@ public:
|
||||
setValue("Conf/startMinimized", enabled);
|
||||
}
|
||||
|
||||
bool isSaveLogs() const
|
||||
bool isSaveLogs()
|
||||
{
|
||||
return value("Conf/saveLogs", false).toBool();
|
||||
}
|
||||
@@ -107,12 +107,12 @@ public:
|
||||
};
|
||||
Q_ENUM(RouteMode)
|
||||
|
||||
QString routeModeString(RouteMode mode) const;
|
||||
QString routeModeString(RouteMode mode);
|
||||
|
||||
RouteMode routeMode() const;
|
||||
RouteMode routeMode();
|
||||
void setRouteMode(RouteMode mode) { setValue("Conf/routeMode", mode); }
|
||||
|
||||
QVariantMap vpnSites(RouteMode mode) const
|
||||
QVariantMap vpnSites(RouteMode mode)
|
||||
{
|
||||
return value("Conf/" + routeModeString(mode)).toMap();
|
||||
}
|
||||
@@ -123,14 +123,14 @@ public:
|
||||
}
|
||||
bool addVpnSite(RouteMode mode, const QString &site, const QString &ip = "");
|
||||
void addVpnSites(RouteMode mode, const QMap<QString, QString> &sites); // map <site, ip>
|
||||
QStringList getVpnIps(RouteMode mode) const;
|
||||
QStringList getVpnIps(RouteMode mode);
|
||||
void removeVpnSite(RouteMode mode, const QString &site);
|
||||
|
||||
void addVpnIps(RouteMode mode, const QStringList &ip);
|
||||
void removeVpnSites(RouteMode mode, const QStringList &sites);
|
||||
void removeAllVpnSites(RouteMode mode);
|
||||
|
||||
bool useAmneziaDns() const
|
||||
bool useAmneziaDns()
|
||||
{
|
||||
return value("Conf/useAmneziaDns", true).toBool();
|
||||
}
|
||||
@@ -139,16 +139,16 @@ public:
|
||||
setValue("Conf/useAmneziaDns", enabled);
|
||||
}
|
||||
|
||||
QString primaryDns() const;
|
||||
QString secondaryDns() const;
|
||||
QString primaryDns();
|
||||
QString secondaryDns();
|
||||
|
||||
// QString primaryDns() const { return m_primaryDns; }
|
||||
// QString primaryDns() { return m_primaryDns; }
|
||||
void setPrimaryDns(const QString &primaryDns)
|
||||
{
|
||||
setValue("Conf/primaryDns", primaryDns);
|
||||
}
|
||||
|
||||
// QString secondaryDns() const { return m_secondaryDns; }
|
||||
// QString secondaryDns() { return m_secondaryDns; }
|
||||
void setSecondaryDns(const QString &secondaryDns)
|
||||
{
|
||||
setValue("Conf/secondaryDns", secondaryDns);
|
||||
@@ -160,7 +160,7 @@ public:
|
||||
// static constexpr char openNicNs5[] = "94.103.153.176";
|
||||
// static constexpr char openNicNs13[] = "144.76.103.143";
|
||||
|
||||
QByteArray backupAppConfig() const
|
||||
QByteArray backupAppConfig()
|
||||
{
|
||||
return m_settings.backupAppConfig();
|
||||
}
|
||||
@@ -178,7 +178,7 @@ public:
|
||||
setValue("Conf/appLanguage", locale);
|
||||
};
|
||||
|
||||
bool isScreenshotsEnabled() const
|
||||
bool isScreenshotsEnabled()
|
||||
{
|
||||
return value("Conf/screenshotsEnabled", false).toBool();
|
||||
}
|
||||
@@ -193,10 +193,10 @@ signals:
|
||||
void saveLogsChanged();
|
||||
|
||||
private:
|
||||
QVariant value(const QString &key, const QVariant &defaultValue = QVariant()) const;
|
||||
void setValue(const QString &key, const QVariant &value);
|
||||
SecureQSettings m_settings;
|
||||
|
||||
mutable SecureQSettings m_settings;
|
||||
QVariant value(const QString &key, const QVariant &defaultValue = QVariant());
|
||||
void setValue(const QString &key, const QVariant &value);
|
||||
};
|
||||
|
||||
#endif // SETTINGS_H
|
||||
|
||||
@@ -15,13 +15,11 @@
|
||||
SettingsController::SettingsController(const QSharedPointer<ServersModel> &serversModel,
|
||||
const QSharedPointer<ContainersModel> &containersModel,
|
||||
const QSharedPointer<LanguageModel> &languageModel,
|
||||
const QSharedPointer<SitesModel> &sitesModel,
|
||||
const std::shared_ptr<Settings> &settings, QObject *parent)
|
||||
: QObject(parent),
|
||||
m_serversModel(serversModel),
|
||||
m_containersModel(containersModel),
|
||||
m_languageModel(languageModel),
|
||||
m_sitesModel(sitesModel),
|
||||
m_settings(settings)
|
||||
{
|
||||
m_appVersion = QString("%1: %2 (%3)").arg(tr("Software version"), QString(APP_VERSION), __DATE__);
|
||||
@@ -136,7 +134,6 @@ void SettingsController::clearSettings()
|
||||
m_serversModel->resetModel();
|
||||
m_languageModel->changeLanguage(
|
||||
static_cast<LanguageSettings::AvailableLanguageEnum>(m_languageModel->getCurrentLanguageIndex()));
|
||||
m_sitesModel->setRouteMode(Settings::RouteMode::VpnAllSites);
|
||||
emit changeSettingsFinished(tr("All settings have been reset to default values"));
|
||||
}
|
||||
|
||||
|
||||
@@ -6,7 +6,6 @@
|
||||
#include "ui/models/containers_model.h"
|
||||
#include "ui/models/languageModel.h"
|
||||
#include "ui/models/servers_model.h"
|
||||
#include "ui/models/sites_model.h"
|
||||
|
||||
class SettingsController : public QObject
|
||||
{
|
||||
@@ -15,7 +14,6 @@ public:
|
||||
explicit SettingsController(const QSharedPointer<ServersModel> &serversModel,
|
||||
const QSharedPointer<ContainersModel> &containersModel,
|
||||
const QSharedPointer<LanguageModel> &languageModel,
|
||||
const QSharedPointer<SitesModel> &sitesModel,
|
||||
const std::shared_ptr<Settings> &settings, QObject *parent = nullptr);
|
||||
|
||||
Q_PROPERTY(QString primaryDns READ getPrimaryDns WRITE setPrimaryDns NOTIFY primaryDnsChanged)
|
||||
@@ -78,7 +76,6 @@ private:
|
||||
QSharedPointer<ServersModel> m_serversModel;
|
||||
QSharedPointer<ContainersModel> m_containersModel;
|
||||
QSharedPointer<LanguageModel> m_languageModel;
|
||||
QSharedPointer<SitesModel> m_sitesModel;
|
||||
std::shared_ptr<Settings> m_settings;
|
||||
|
||||
QString m_appVersion;
|
||||
|
||||
@@ -231,7 +231,7 @@ ErrorCode ClientManagementModel::appendClient(const QString &clientId, const QSt
|
||||
}
|
||||
}
|
||||
|
||||
beginInsertRows(QModelIndex(), rowCount(), rowCount() + 1);
|
||||
beginInsertRows(QModelIndex(), rowCount(), 1);
|
||||
QJsonObject client;
|
||||
client[configKey::clientId] = clientId;
|
||||
|
||||
|
||||
@@ -101,7 +101,7 @@ PageType {
|
||||
|
||||
text: qsTr("Show other methods on Github")
|
||||
|
||||
onClicked: Qt.openUrlExternally(qsTr("https://github.com/amnezia-vpn/amnezia-client#donate"))
|
||||
onClicked: Qt.openUrlExternally("https://github.com/amnezia-vpn/amnezia-client#donate")
|
||||
}
|
||||
|
||||
ParagraphTextType {
|
||||
|
||||
@@ -135,7 +135,7 @@ PageType {
|
||||
|
||||
text: qsTr("I have nothing")
|
||||
|
||||
onClicked: Qt.openUrlExternally(qsTr("https://amnezia.org/instructions/0_starter-guide"))
|
||||
onClicked: Qt.openUrlExternally("https://amnezia.org/instructions/0_starter-guide")
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -226,13 +226,13 @@ QStringList Utils::summarizeRoutes(const QStringList &ips, const QString cidr)
|
||||
QString Utils::openVpnExecPath()
|
||||
{
|
||||
#ifdef Q_OS_WIN
|
||||
return Utils::executable("openvpn/ovpncli", true);
|
||||
return Utils::executable("openvpn/openvpn", true);
|
||||
#elif defined Q_OS_LINUX
|
||||
// We have service that runs OpenVPN on Linux. We need to make same
|
||||
// path for client and service.
|
||||
return Utils::executable("../../client/bin/ovpncli", true);
|
||||
return Utils::executable("../../client/bin/openvpn", true);
|
||||
#else
|
||||
return Utils::executable("/ovpncli", true);
|
||||
return Utils::executable("/openvpn", true);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
@@ -261,7 +261,7 @@ QString TapController::getTapInstallPath()
|
||||
|
||||
QString TapController::getOpenVpnPath()
|
||||
{
|
||||
return qApp->applicationDirPath() + "\\openvpn\\ovpncli.exe";
|
||||
return qApp->applicationDirPath() + "\\openvpn\\openvpn.exe";
|
||||
}
|
||||
|
||||
QString TapController::getTapDriverDir()
|
||||
|
||||
Reference in New Issue
Block a user