Compare commits

..

30 Commits

Author SHA1 Message Date
Mykola Baibuz 4205bb1d31 fix: flush dns after in connected status 2025-08-20 13:44:55 +03:00
Mykola Baibuz 5570cb94b5 Setup DNS resolver for Linux IPSec 2025-08-19 19:44:58 +03:00
Mykola Baibuz 45323e67fb add trace info 2025-08-18 15:36:11 +03:00
Mykola Baibuz ae3ed9c741 Merge branch 'dev' into feature/linux-ipsec 2025-08-10 02:47:32 -07:00
Mykola Baibuz f47e4cb729 Enable PFS for Linux IPSec 2025-02-07 12:58:37 +02:00
Mykola Baibuz b5cbcc5f2a Merge branch 'dev' of https://github.com/amnezia-vpn/amnezia-client into feature/linux-ipsec 2025-02-07 12:48:57 +02:00
Mykola Baibuz f18d980bdb Merge branch 'dev' into feature/linux-ipsec 2025-02-07 12:48:41 +02:00
Mykola Baibuz 81cfab3566 fix: broken routing 2025-01-27 17:20:05 +02:00
Mykola Baibuz 7f123dabac Merge remote-tracking branch 'origin/bugfix/pre-release-hotfixes' into feature/linux-ipsec 2025-01-27 16:32:46 +02:00
Mykola Baibuz de0b400934 Merge remote-tracking branch 'origin/bugfix/pre-release-hotfixes' into feature/linux-ipsec 2025-01-26 16:36:50 +02:00
Mykola Baibuz dcde24649f Merge branch 'dev' into feature/linux-ipsec 2025-01-24 22:00:16 +02:00
vladimir.kuznetsov b717560047 Merge branch 'dev' of github.com:amnezia-vpn/amnezia-client into HEAD 2025-01-08 14:41:02 +07:00
vladimir.kuznetsov afd2542a11 Merge branch 'dev' of github.com:amnezia-vpn/amnezia-client into feature/linux-ipsec 2024-12-19 14:28:20 +07:00
Pokamest Nikak 1438a21902 Merge branch 'dev' into feature/linux-ipsec 2024-09-11 19:41:20 +01:00
Mykola Baibuz 4147632a62 Fix Android build 2024-08-30 22:15:51 +03:00
Mykola Baibuz 948ab4cf71 Set local IPSec VPN address 2024-08-30 22:10:39 +03:00
Mykola Baibuz f54308e4f4 Merge branch 'dev' into feature/linux-ipsec 2024-08-30 21:50:40 +03:00
Mykola Baibuz 052261c2b4 Get Linux IPSec tunnel status 2024-08-30 21:46:52 +03:00
Mykola Baibuz 3cec0dc2a7 Restart IPSec service before VPN connect 2024-08-29 23:18:21 +03:00
Mykola Baibuz ad61ef0b22 Cleanup ipsec.secrets from duplicates 2024-08-29 00:24:51 +03:00
Mykola Baibuz 63c569c3d2 Setup routing for Linux IPSec 2024-08-25 00:26:32 +03:00
Mykola Baibuz 30df4c6800 Merge branch 'feature/linux-ipsec' of https://github.com/amnezia-vpn/amnezia-client into feature/linux-ipsec 2024-08-24 00:59:37 +03:00
Mykola Baibuz a96f9dc18a Start and Stop for Linux tunnel 2024-08-24 00:57:47 +03:00
Mykola Baibuz fb63cdf7e9 Fix work with PKCS12 TempFile 2024-08-20 22:45:06 +03:00
Mykola Baibuz 2d3b9c2752 Windows import PFX changes 2024-08-20 13:44:33 +03:00
Mykola Baibuz 09c58cb39e Fix certwrite for Win IPSec 2024-08-19 18:46:53 +03:00
Mykola Baibuz 654d219e7e Fix Win Build for IPSec protocol 2024-08-18 13:53:38 +03:00
Mykola Baibuz 89d4c18e87 Update IPSec configs templates 2024-08-18 01:46:06 +03:00
Mykola Baibuz b0b185027e Linux IPSec initial 2024-08-01 21:37:56 +03:00
Mykola Baibuz 90912f9231 Fix Windows IPsec 2024-07-26 00:55:13 +03:00
40 changed files with 1015 additions and 486 deletions
+9
View File
@@ -174,6 +174,15 @@ endif()
if(LINUX AND NOT ANDROID) if(LINUX AND NOT ANDROID)
set(LIBS ${LIBS} -static-libstdc++ -static-libgcc -ldl) set(LIBS ${LIBS} -static-libstdc++ -static-libgcc -ldl)
link_directories(${CMAKE_CURRENT_LIST_DIR}/platforms/linux) link_directories(${CMAKE_CURRENT_LIST_DIR}/platforms/linux)
set(HEADERS ${HEADERS}
${CMAKE_CURRENT_LIST_DIR}/protocols/ikev2_vpn_protocol_linux.h
)
set(SOURCES ${SOURCES}
${CMAKE_CURRENT_LIST_DIR}/protocols/ikev2_vpn_protocol_linux.cpp
)
endif() endif()
if(WIN32 OR (APPLE AND NOT IOS AND NOT MACOS_NE) OR (LINUX AND NOT ANDROID)) if(WIN32 OR (APPLE AND NOT IOS AND NOT MACOS_NE) OR (LINUX AND NOT ANDROID))
+3 -5
View File
@@ -53,16 +53,14 @@ AmneziaApplication::~AmneziaApplication()
{ {
if (m_vpnConnection) { if (m_vpnConnection) {
QMetaObject::invokeMethod(m_vpnConnection.get(), "disconnectFromVpn", Qt::QueuedConnection); QMetaObject::invokeMethod(m_vpnConnection.get(), "disconnectFromVpn", Qt::QueuedConnection);
QThread::msleep(2000); QMetaObject::invokeMethod(m_vpnConnection.get(), "deleteLater", Qt::QueuedConnection);
QMetaObject::invokeMethod(m_vpnConnection.get(), "disconnectSlots", Qt::QueuedConnection);
} }
m_vpnConnectionThread.requestInterruption();
m_vpnConnectionThread.quit(); m_vpnConnectionThread.quit();
if (!m_vpnConnectionThread.wait(3000)) { if (!m_vpnConnectionThread.wait(5000)) {
m_vpnConnectionThread.terminate(); m_vpnConnectionThread.terminate();
m_vpnConnectionThread.wait(500); m_vpnConnectionThread.wait();
} }
if (m_engine) { if (m_engine) {
@@ -64,6 +64,26 @@ QString Ikev2Configurator::createConfig(const ServerCredentials &credentials, Do
return ""; return "";
} }
#if defined(Q_OS_LINUX)
QString config = m_serverController->replaceVars(amnezia::scriptData(ProtocolScriptType::ipsec_template, container),
m_serverController->genVarsForScript(credentials, container, containerConfig));
config.replace("$CLIENT_NAME", connData.clientId);
config.replace("$UUID1", QUuid::createUuid().toString());
config.replace("$SERVER_ADDR", connData.host);
QJsonObject jConfig;
jConfig[config_key::config] = config;
jConfig[config_key::hostName] = connData.host;
jConfig[config_key::userName] = connData.clientId;
jConfig[config_key::cert] = QString(connData.clientCert.toBase64());
jConfig[config_key::cacert] = QString(connData.caCert);
jConfig[config_key::password] = connData.password;
return QJsonDocument(jConfig).toJson();
#endif
return genIkev2Config(connData); return genIkev2Config(connData);
} }
@@ -73,6 +93,7 @@ QString Ikev2Configurator::genIkev2Config(const ConnectionData &connData)
config[config_key::hostName] = connData.host; config[config_key::hostName] = connData.host;
config[config_key::userName] = connData.clientId; config[config_key::userName] = connData.clientId;
config[config_key::cert] = QString(connData.clientCert.toBase64()); config[config_key::cert] = QString(connData.clientCert.toBase64());
config[config_key::cacert] = QString(connData.caCert);
config[config_key::password] = connData.password; config[config_key::password] = connData.password;
return QJsonDocument(config).toJson(); return QJsonDocument(config).toJson();
@@ -115,3 +136,22 @@ QString Ikev2Configurator::genStrongSwanConfig(const ConnectionData &connData)
return config; return config;
} }
QString Ikev2Configurator::processConfigWithLocalSettings(const QPair<QString, QString> &dns, const bool isApiConfig,
QString &protocolConfigString)
{
processConfigWithDnsSettings(dns, protocolConfigString);
QJsonObject json;
json[config_key::config] = protocolConfigString;
return QJsonDocument(json).toJson();
}
QString Ikev2Configurator::processConfigWithExportSettings(const QPair<QString, QString> &dns, const bool isApiConfig,
QString &protocolConfigString)
{
processConfigWithDnsSettings(dns, protocolConfigString);
QJsonObject json;
json[config_key::config] = protocolConfigString;
return QJsonDocument(json).toJson();
}
@@ -27,6 +27,10 @@ public:
QString genIkev2Config(const ConnectionData &connData); QString genIkev2Config(const ConnectionData &connData);
QString genMobileConfig(const ConnectionData &connData); QString genMobileConfig(const ConnectionData &connData);
QString genStrongSwanConfig(const ConnectionData &connData); QString genStrongSwanConfig(const ConnectionData &connData);
QString genIPSecConfig(const ConnectionData &connData);
QString processConfigWithLocalSettings(const QPair<QString, QString> &dns, const bool isApiConfig, QString &protocolConfigString);
QString processConfigWithExportSettings(const QPair<QString, QString> &dns, const bool isApiConfig, QString &protocolConfigString);
ConnectionData prepareIkev2Config(const ServerCredentials &credentials, ConnectionData prepareIkev2Config(const ServerCredentials &credentials,
DockerContainer container, ErrorCode &errorCode); DockerContainer container, ErrorCode &errorCode);
+1 -8
View File
@@ -257,7 +257,7 @@ Proto ContainerProps::defaultProtocol(DockerContainer c)
bool ContainerProps::isSupportedByCurrentPlatform(DockerContainer c) bool ContainerProps::isSupportedByCurrentPlatform(DockerContainer c)
{ {
#ifdef Q_OS_WINDOWS #if defined(Q_OS_WINDOWS) || defined(Q_OS_LINUX)
return true; return true;
#elif defined(Q_OS_IOS) #elif defined(Q_OS_IOS)
@@ -306,13 +306,6 @@ bool ContainerProps::isSupportedByCurrentPlatform(DockerContainer c)
case DockerContainer::SSXray: return true; case DockerContainer::SSXray: return true;
default: return false; default: return false;
} }
#elif defined(Q_OS_LINUX)
switch (c) {
case DockerContainer::Ipsec: return false;
default: return true;
}
#else #else
return false; return false;
#endif #endif
+1 -2
View File
@@ -85,9 +85,8 @@ bool IpcClient::init(IpcClient *instance)
} }
qDebug() << "IpcClient::init succeed"; qDebug() << "IpcClient::init succeed";
instance->m_isSocketConnected = (Instance()->m_ipcClient->isReplicaValid() && Instance()->m_Tun2SocksClient->isReplicaValid());
return Instance()->isSocketConnected(); return (Instance()->m_ipcClient->isReplicaValid() && Instance()->m_Tun2SocksClient->isReplicaValid());
} }
QSharedPointer<PrivilegedProcess> IpcClient::CreatePrivilegedProcess() QSharedPointer<PrivilegedProcess> IpcClient::CreatePrivilegedProcess()
+1
View File
@@ -50,6 +50,7 @@ QString amnezia::scriptName(ProtocolScriptType type)
case ProtocolScriptType::wireguard_template: return QLatin1String("template.conf"); case ProtocolScriptType::wireguard_template: return QLatin1String("template.conf");
case ProtocolScriptType::awg_template: return QLatin1String("template.conf"); case ProtocolScriptType::awg_template: return QLatin1String("template.conf");
case ProtocolScriptType::xray_template: return QLatin1String("template.json"); case ProtocolScriptType::xray_template: return QLatin1String("template.json");
case ProtocolScriptType::ipsec_template: return QLatin1String("template.conf");
default: return QString(); default: return QString();
} }
} }
+2 -1
View File
@@ -28,7 +28,8 @@ enum ProtocolScriptType {
openvpn_template, openvpn_template,
wireguard_template, wireguard_template,
awg_template, awg_template,
xray_template xray_template,
ipsec_template
}; };
@@ -0,0 +1,185 @@
#include <QCoreApplication>
#include <QFileInfo>
#include <QProcess>
#include <QNetworkInterface>
#include <QThread>
#include <chrono>
#include "core/networkUtilities.h"
#include "settings.h"
#include "logger.h"
#include "ikev2_vpn_protocol_linux.h"
#include "utilities.h"
#include "core/ipcclient.h"
#include <openssl/pkcs12.h>
#include <openssl/bio.h>
#include <openssl/pem.h>
static Ikev2Protocol* self = nullptr;
Ikev2Protocol::Ikev2Protocol(const QJsonObject &configuration, QObject* parent) :
VpnProtocol(configuration, parent)
{
qDebug() << "IpsecProtocol::Ikev2Protocol()";
self = this;
readIkev2Configuration(configuration);
m_routeGateway = NetworkUtilities::getGatewayAndIface();
m_vpnGateway = "192.168.43.10";
m_vpnLocalAddress = "192.168.43.10";
m_remoteAddress = NetworkUtilities::getIPAddress(configuration.value(amnezia::config_key::hostName).toString());
m_routeMode = static_cast<Settings::RouteMode>(configuration.value(amnezia::config_key::splitTunnelType).toInt());
m_configData = configuration;
}
Ikev2Protocol::~Ikev2Protocol()
{
qDebug() << "IpsecProtocol::~IpsecProtocol()";
Ikev2Protocol::stop();
}
void Ikev2Protocol::stop()
{
setConnectionState(Vpn::ConnectionState::Disconnected);
Ikev2Protocol::disconnect_vpn();
qDebug() << "IpsecProtocol::stop()";
}
void Ikev2Protocol::readIkev2Configuration(const QJsonObject &configuration)
{
qDebug() << "IpsecProtocol::readIkev2Configuration()";
QJsonObject ikev2_data = configuration.value(ProtocolProps::key_proto_config_data(Proto::Ikev2)).toObject();
m_config = QJsonDocument::fromJson(ikev2_data.value(config_key::config).toString().toUtf8()).object();
}
ErrorCode Ikev2Protocol::start()
{
qDebug() << "IpsecProtocol::start()";
STACK_OF(X509) *certstack = sk_X509_new_null();
BIO *p12 = BIO_new(BIO_s_mem());
EVP_PKEY *pkey;
X509 *cert;
BIO_write(p12, QByteArray::fromBase64(m_config[config_key::cert].toString().toUtf8()),
QByteArray::fromBase64(m_config[config_key::cert].toString().toUtf8()).size());
PKCS12 *pkcs12 = d2i_PKCS12_bio(p12, NULL);
PKCS12_parse(pkcs12, m_config[config_key::password].toString().toStdString().c_str(), &pkey, &cert, &certstack);
BIO *bio = BIO_new(BIO_s_mem());
PEM_write_bio_X509(bio, cert);
BUF_MEM *mem = NULL;
BIO_get_mem_ptr(bio, &mem);
std::string pem(mem->data, mem->length);
QString alias(pem.c_str());
IpcClient::Interface()->writeIPsecUserCert(alias, m_config[config_key::userName].toString());
IpcClient::Interface()->writeIPsecConfig(m_config[config_key::config].toString());
IpcClient::Interface()->writeIPsecCaCert(m_config[config_key::cacert].toString(), m_config[config_key::userName].toString());
IpcClient::Interface()->writeIPsecPrivate(m_config[config_key::cert].toString(), m_config[config_key::userName].toString());
IpcClient::Interface()->writeIPsecPrivatePass(m_config[config_key::password].toString(), m_config[config_key::hostName].toString(),
m_config[config_key::userName].toString());
connect_to_vpn("ikev2-vpn");
if (!IpcClient::Interface()) {
return ErrorCode::AmneziaServiceConnectionFailed;
}
QString connectionStatus;
auto futureResult = IpcClient::Interface()->getTunnelStatus("ikev2-vpn");
futureResult.waitForFinished();
if (futureResult.returnValue().isEmpty()) {
auto futureResult = IpcClient::Interface()->getTunnelStatus("ikev2-vpn");
futureResult.waitForFinished();
}
connectionStatus = futureResult.returnValue();
if (connectionStatus.contains("ESTABLISHED")) {
QStringList lines = connectionStatus.split('\n');
for (auto iter = lines.begin(); iter!=lines.end(); iter++)
{
if (iter->contains("0.0.0.0/0")) {
QList<QHostAddress> dnsAddr;
dnsAddr.push_back(QHostAddress(m_configData.value(config_key::dns1).toString()));
// We don't use secondary DNS if primary DNS is AmneziaDNS
if (!m_configData.value(amnezia::config_key::dns1).toString().
contains(amnezia::protocols::dns::amneziaDnsIp)) {
dnsAddr.push_back(QHostAddress(m_configData.value(config_key::dns2).toString()));
}
m_vpnGateway = iter->split("===", Qt::SkipEmptyParts).first();
m_vpnGateway = m_vpnGateway.split(" ").at(2);
m_vpnGateway = m_vpnGateway.split("/").first();
m_vpnLocalAddress = m_vpnGateway;
// killSwitch toggle
if (QVariant(m_config.value(config_key::killSwitchOption).toString()).toBool()) {
m_config.insert("vpnServer", m_remoteAddress);
IpcClient::Interface()->enableKillSwitch(m_config, 0);
}
if (m_routeMode == Settings::RouteMode::VpnAllSites) {
IpcClient::Interface()->routeAddList(m_vpnGateway, QStringList() << "0.0.0.0/1");
IpcClient::Interface()->routeAddList(m_vpnGateway, QStringList() << "128.0.0.0/1");
IpcClient::Interface()->routeAddList(m_routeGateway, QStringList() << m_remoteAddress);
}
QList<QNetworkInterface> netInterfaces = QNetworkInterface::allInterfaces();
for (int i = 0; i < netInterfaces.size(); i++) {
for (int j=0; j < netInterfaces.at(i).addressEntries().size(); j++)
{
if (netInterfaces.at(i).addressEntries().at(j).ip().toString() == m_vpnGateway)
{
IpcClient::Interface()->updateResolvers(netInterfaces.at(i).humanReadableName(), dnsAddr);
}
}
}
IpcClient::Interface()->StopRoutingIpv6();
}
}
setConnectionState(Vpn::ConnectionState::Connected);
} else {
setConnectionState(Vpn::ConnectionState::Disconnected);
}
return ErrorCode::NoError;
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
bool Ikev2Protocol::create_new_vpn(const QString & vpn_name,
const QString & serv_addr) {
qDebug() << "Ikev2Protocol::create_new_vpn()";
return true;
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
bool Ikev2Protocol::delete_vpn_connection(const QString &vpn_name) {
return false;
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
bool Ikev2Protocol::connect_to_vpn(const QString &vpn_name) {
qDebug() << "IpsecProtocol::connect_to_vpn()";
IpcClient::Interface()->startIPsec(vpn_name);
QThread::msleep(3000);
return true;
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
bool Ikev2Protocol::disconnect_vpn() {
qDebug() << "IpsecProtocol::disconnect_vpn()";
IpcClient::Interface()->stopIPsec("ikev2-vpn");
IpcClient::Interface()->disableKillSwitch();
IpcClient::Interface()->StartRoutingIpv6();
return true;
}
@@ -0,0 +1,52 @@
#ifndef IKEV2_VPN_PROTOCOL_LINUX_H
#define IKEV2_VPN_PROTOCOL_LINUX_H
#include <QObject>
#include <QProcess>
#include <QString>
#include <QTemporaryFile>
#include <QTimer>
#include "vpnprotocol.h"
#include <string>
#include <memory>
#include <atomic>
#include <thread>
#include <condition_variable>
#include <mutex>
class Ikev2Protocol : public VpnProtocol
{
Q_OBJECT
public:
explicit Ikev2Protocol(const QJsonObject& configuration, QObject* parent = nullptr);
virtual ~Ikev2Protocol() override;
ErrorCode start() override;
void stop() override;
static QString tunnelName() { return "AmneziaVPN IKEv2"; }
private:
void readIkev2Configuration(const QJsonObject &configuration);
private:
QJsonObject m_config;
QJsonObject m_configData;
QString m_remoteAddress;
int m_routeMode;
bool create_new_vpn(const QString & vpn_name,
const QString & serv_addr);
bool delete_vpn_connection(const QString &vpn_name);
bool connect_to_vpn(const QString & vpn_name);
bool disconnect_vpn();
};
#endif // IKEV2_VPN_PROTOCOL_LINUX_H
@@ -172,7 +172,8 @@ void Ikev2Protocol::newConnectionStateEventReceived(UINT unMsg, tagRASCONNSTATE
void Ikev2Protocol::readIkev2Configuration(const QJsonObject &configuration) void Ikev2Protocol::readIkev2Configuration(const QJsonObject &configuration)
{ {
m_config = configuration.value(ProtocolProps::key_proto_config_data(Proto::Ikev2)).toObject(); QJsonObject ikev2_data = configuration.value(ProtocolProps::key_proto_config_data(Proto::Ikev2)).toObject();
m_config = QJsonDocument::fromJson(ikev2_data.value(config_key::config).toString().toUtf8()).object();
} }
ErrorCode Ikev2Protocol::start() ErrorCode Ikev2Protocol::start()
+1 -2
View File
@@ -56,8 +56,7 @@ void OpenVpnProtocol::stop()
} }
#if defined(Q_OS_WIN) || defined(Q_OS_LINUX) || defined(Q_OS_MACOS) #if defined(Q_OS_WIN) || defined(Q_OS_LINUX) || defined(Q_OS_MACOS)
QRemoteObjectPendingReply<bool> disableKillSwitchResp = IpcClient::Interface()->disableKillSwitch(); IpcClient::Interface()->disableKillSwitch();
disableKillSwitchResp.waitForFinished(1000);
#endif #endif
setConnectionState(Vpn::ConnectionState::Disconnected); setConnectionState(Vpn::ConnectionState::Disconnected);
+1
View File
@@ -24,6 +24,7 @@ namespace amnezia
constexpr char description[] = "description"; constexpr char description[] = "description";
constexpr char name[] = "name"; constexpr char name[] = "name";
constexpr char cert[] = "cert"; constexpr char cert[] = "cert";
constexpr char cacert[] = "cacert";
constexpr char config[] = "config"; constexpr char config[] = "config";
constexpr char containers[] = "containers"; constexpr char containers[] = "containers";
+5 -1
View File
@@ -16,6 +16,10 @@
#include "ikev2_vpn_protocol_windows.h" #include "ikev2_vpn_protocol_windows.h"
#endif #endif
#ifdef Q_OS_LINUX
#include "ikev2_vpn_protocol_linux.h"
#endif
VpnProtocol::VpnProtocol(const QJsonObject &configuration, QObject *parent) VpnProtocol::VpnProtocol(const QJsonObject &configuration, QObject *parent)
: QObject(parent), : QObject(parent),
m_connectionState(Vpn::ConnectionState::Unknown), m_connectionState(Vpn::ConnectionState::Unknown),
@@ -106,7 +110,7 @@ QString VpnProtocol::vpnGateway() const
VpnProtocol *VpnProtocol::factory(DockerContainer container, const QJsonObject &configuration) VpnProtocol *VpnProtocol::factory(DockerContainer container, const QJsonObject &configuration)
{ {
switch (container) { switch (container) {
#if defined(Q_OS_WINDOWS) #if defined(Q_OS_WINDOWS) || defined(Q_OS_LINUX) && !defined(Q_OS_ANDROID)
case DockerContainer::Ipsec: return new Ikev2Protocol(configuration); case DockerContainer::Ipsec: return new Ikev2Protocol(configuration);
#endif #endif
#if defined(Q_OS_WINDOWS) || defined(Q_OS_MACX) and !defined MACOS_NE || (defined(Q_OS_LINUX) && !defined(Q_OS_ANDROID)) #if defined(Q_OS_WINDOWS) || defined(Q_OS_MACX) and !defined MACOS_NE || (defined(Q_OS_LINUX) && !defined(Q_OS_ANDROID))
+2 -5
View File
@@ -167,10 +167,8 @@ ErrorCode XrayProtocol::startTun2Sock()
void XrayProtocol::stop() void XrayProtocol::stop()
{ {
#if defined(Q_OS_WIN) || defined(Q_OS_LINUX) || defined(Q_OS_MACOS) #if defined(Q_OS_WIN) || defined(Q_OS_LINUX) || defined(Q_OS_MACOS)
QRemoteObjectPendingReply<bool> disableKillSwitchResp = IpcClient::Interface()->disableKillSwitch(); IpcClient::Interface()->disableKillSwitch();
disableKillSwitchResp.waitForFinished(1000); IpcClient::Interface()->StartRoutingIpv6();
QRemoteObjectPendingReply<bool> StartRoutingIpv6Resp = IpcClient::Interface()->StartRoutingIpv6();
StartRoutingIpv6Resp.waitForFinished(1000);
#endif #endif
qDebug() << "XrayProtocol::stop()"; qDebug() << "XrayProtocol::stop()";
m_xrayProcess.disconnect(); m_xrayProcess.disconnect();
@@ -178,7 +176,6 @@ void XrayProtocol::stop()
m_xrayProcess.waitForFinished(3000); m_xrayProcess.waitForFinished(3000);
if (m_t2sProcess) { if (m_t2sProcess) {
m_t2sProcess->stop(); m_t2sProcess->stop();
QThread::msleep(200);
} }
setConnectionState(Vpn::ConnectionState::Disconnected); setConnectionState(Vpn::ConnectionState::Disconnected);
+1
View File
@@ -77,6 +77,7 @@
<file>server_scripts/ipsec/mobileconfig.plist</file> <file>server_scripts/ipsec/mobileconfig.plist</file>
<file>server_scripts/ipsec/run_container.sh</file> <file>server_scripts/ipsec/run_container.sh</file>
<file>server_scripts/ipsec/start.sh</file> <file>server_scripts/ipsec/start.sh</file>
<file>server_scripts/ipsec/template.conf</file>
<file>server_scripts/ipsec/strongswan.profile</file> <file>server_scripts/ipsec/strongswan.profile</file>
<file>server_scripts/openvpn_cloak/configure_container.sh</file> <file>server_scripts/openvpn_cloak/configure_container.sh</file>
<file>server_scripts/openvpn_cloak/Dockerfile</file> <file>server_scripts/openvpn_cloak/Dockerfile</file>
@@ -242,6 +242,7 @@ conn ikev2-cp
dpdtimeout=120 dpdtimeout=120
dpdaction=clear dpdaction=clear
auto=add auto=add
authby=rsa-sha1
ikev2=insist ikev2=insist
rekey=no rekey=no
pfs=yes pfs=yes
+28
View File
@@ -0,0 +1,28 @@
config setup
charondebug="ike 1, knl 1, cfg 0"
uniqueids=no
conn ikev2-vpn
auto=add
type=tunnel
keyexchange=ikev2
fragmentation=yes
forceencaps=yes
dpdaction=clear
dpddelay=300s
rekey=no
leftid=$CLIENT_NAME
leftcert=$CLIENT_NAME.crt
leftdns=$PRIMARY_DNS,$SECONDARY_DNS
leftsendcert=always
leftsourceip=%config
right=$SERVER_IP_ADDRESS
rightsubnet=0.0.0.0/0
rightsendcert=never
eap_identity=%identity
encapsulation=yes
pfs=yes
ike=aes256-sha256-modp2048,aes256-sha1-modp1024,3des-sha1-modp1024
esp=aes256-sha256,aes256-sha1,3des-sha1
@@ -34,7 +34,7 @@ PageType {
ListViewType { ListViewType {
id: listView id: listView
anchors.top: backButton.bottom anchors.top: backButtonLayout.bottom
anchors.bottom: saveButton.top anchors.bottom: saveButton.top
anchors.right: parent.right anchors.right: parent.right
anchors.left: parent.left anchors.left: parent.left
@@ -37,7 +37,7 @@ PageType {
ListViewType { ListViewType {
id: listView id: listView
anchors.top: backButton.bottom anchors.top: backButtonLayout.bottom
anchors.bottom: parent.bottom anchors.bottom: parent.bottom
anchors.left: parent.left anchors.left: parent.left
anchors.right: parent.right anchors.right: parent.right
@@ -17,413 +17,427 @@ import "../Components"
PageType { PageType {
id: root id: root
BackButtonType { ColumnLayout {
id: backButton id: backButtonLayout
anchors.top: parent.top anchors.top: parent.top
anchors.left: parent.left anchors.left: parent.left
anchors.right: parent.right anchors.right: parent.right
anchors.topMargin: 20 anchors.topMargin: 20
onActiveFocusChanged: { BackButtonType {
if(backButton.enabled && backButton.activeFocus) { id: backButton
listView.positionViewAtBeginning()
}
} }
} }
ListViewType { FlickableType {
id: listView id: fl
anchors.top: backButtonLayout.bottom
anchors.top: backButton.bottom
anchors.bottom: parent.bottom anchors.bottom: parent.bottom
anchors.right: parent.right contentHeight: content.implicitHeight
anchors.left: parent.left
enabled: ServersModel.isProcessedServerHasWriteAccess() Column {
id: content
header: ColumnLayout { anchors.top: parent.top
width: listView.width anchors.left: parent.left
anchors.right: parent.right
BaseHeaderType { enabled: ServersModel.isProcessedServerHasWriteAccess()
id: header
Layout.fillWidth: true ListView {
Layout.rightMargin: 16 id: listview
Layout.leftMargin: 16
headerText: qsTr("OpenVPN Settings") width: parent.width
} height: listview.contentItem.height
}
model: OpenVpnConfigModel clip: true
interactive: false
delegate: ColumnLayout { model: OpenVpnConfigModel
width: listView.width
spacing: 0 delegate: Item {
id: delegateItem
TextFieldWithHeaderType { property alias vpnAddressSubnetTextField: vpnAddressSubnetTextField
id: vpnAddressSubnetTextField property bool isEnabled: ServersModel.isProcessedServerHasWriteAccess()
Layout.fillWidth: true implicitWidth: listview.width
Layout.topMargin: 32 implicitHeight: col.implicitHeight
Layout.leftMargin: 16
Layout.rightMargin: 16
enabled: listView.enabled ColumnLayout {
id: col
headerText: qsTr("VPN address subnet") anchors.top: parent.top
textField.text: subnetAddress anchors.left: parent.left
anchors.right: parent.right
textField.onEditingFinished: { anchors.leftMargin: 16
if (textField.text !== subnetAddress) { anchors.rightMargin: 16
subnetAddress = textField.text
}
}
checkEmptyText: true spacing: 0
}
ParagraphTextType { BaseHeaderType {
Layout.fillWidth: true Layout.fillWidth: true
Layout.topMargin: 32 headerText: qsTr("OpenVPN settings")
Layout.leftMargin: 16 }
Layout.rightMargin: 16
text: qsTr("Network protocol") TextFieldWithHeaderType {
} id: vpnAddressSubnetTextField
TransportProtoSelector { Layout.fillWidth: true
id: transportProtoSelector Layout.topMargin: 32
Layout.fillWidth: true
Layout.topMargin: 16
Layout.leftMargin: 16
Layout.rightMargin: 16
rootWidth: root.width enabled: delegateItem.isEnabled
enabled: isTransportProtoEditable headerText: qsTr("VPN address subnet")
textField.text: subnetAddress
currentIndex: { parentFlickable: fl
return transportProto === "tcp" ? 1 : 0
}
onCurrentIndexChanged: { textField.onEditingFinished: {
if (transportProto === "tcp" && currentIndex === 0) { if (textField.text !== subnetAddress) {
transportProto = "udp" subnetAddress = textField.text
} else if (transportProto === "udp" && currentIndex === 1) { }
transportProto = "tcp" }
}
}
}
TextFieldWithHeaderType { checkEmptyText: true
id: portTextField }
Layout.fillWidth: true ParagraphTextType {
Layout.topMargin: 40 Layout.fillWidth: true
Layout.leftMargin: 16 Layout.topMargin: 32
Layout.rightMargin: 16
enabled: listView.enabled text: qsTr("Network protocol")
}
headerText: qsTr("Port") TransportProtoSelector {
textField.text: port id: transportProtoSelector
textField.maximumLength: 5 Layout.fillWidth: true
textField.validator: IntValidator { bottom: 1; top: 65535 } Layout.topMargin: 16
rootWidth: root.width
textField.onEditingFinished: { enabled: isTransportProtoEditable
if (textField.text !== port) {
port = textField.text
}
}
checkEmptyText: true currentIndex: {
} return transportProto === "tcp" ? 1 : 0
}
SwitcherType { onCurrentIndexChanged: {
id: autoNegotiateEncryprionSwitcher if (transportProto === "tcp" && currentIndex === 0) {
transportProto = "udp"
Layout.fillWidth: true } else if (transportProto === "udp" && currentIndex === 1) {
Layout.topMargin: 24 transportProto = "tcp"
Layout.leftMargin: 16 }
Layout.rightMargin: 16
text: qsTr("Auto-negotiate encryption")
checked: autoNegotiateEncryprion
onCheckedChanged: {
if (checked !== autoNegotiateEncryprion) {
autoNegotiateEncryprion = checked
}
}
}
DropDownType {
id: hashDropDown
Layout.fillWidth: true
Layout.topMargin: 20
Layout.leftMargin: 16
Layout.rightMargin: 16
enabled: !autoNegotiateEncryprionSwitcher.checked
descriptionText: qsTr("Hash")
headerText: qsTr("Hash")
drawerParent: root
listView: ListViewWithRadioButtonType {
id: hashListView
rootWidth: root.width
model: ListModel {
ListElement { name : qsTr("SHA512") }
ListElement { name : qsTr("SHA384") }
ListElement { name : qsTr("SHA256") }
ListElement { name : qsTr("SHA3-512") }
ListElement { name : qsTr("SHA3-384") }
ListElement { name : qsTr("SHA3-256") }
ListElement { name : qsTr("whirlpool") }
ListElement { name : qsTr("BLAKE2b512") }
ListElement { name : qsTr("BLAKE2s256") }
ListElement { name : qsTr("SHA1") }
}
clickedFunction: function() {
hashDropDown.text = selectedText
hash = hashDropDown.text
hashDropDown.closeTriggered()
}
Component.onCompleted: {
hashDropDown.text = hash
for (var i = 0; i < hashListView.model.count; i++) {
if (hashListView.model.get(i).name === hashDropDown.text) {
currentIndex = i
} }
} }
}
}
}
DropDownType { TextFieldWithHeaderType {
id: cipherDropDown id: portTextField
Layout.fillWidth: true
Layout.topMargin: 16
Layout.leftMargin: 16
Layout.rightMargin: 16
enabled: !autoNegotiateEncryprionSwitcher.checked Layout.fillWidth: true
Layout.topMargin: 40
parentFlickable: fl
descriptionText: qsTr("Cipher") enabled: delegateItem.isEnabled
headerText: qsTr("Cipher")
drawerParent: root headerText: qsTr("Port")
textField.text: port
textField.maximumLength: 5
textField.validator: IntValidator { bottom: 1; top: 65535 }
listView: ListViewWithRadioButtonType { textField.onEditingFinished: {
id: cipherListView if (textField.text !== port) {
port = textField.text
}
}
rootWidth: root.width checkEmptyText: true
}
model: ListModel { SwitcherType {
ListElement { name : qsTr("AES-256-GCM") } id: autoNegotiateEncryprionSwitcher
ListElement { name : qsTr("AES-192-GCM") }
ListElement { name : qsTr("AES-128-GCM") }
ListElement { name : qsTr("AES-256-CBC") }
ListElement { name : qsTr("AES-192-CBC") }
ListElement { name : qsTr("AES-128-CBC") }
ListElement { name : qsTr("ChaCha20-Poly1305") }
ListElement { name : qsTr("ARIA-256-CBC") }
ListElement { name : qsTr("CAMELLIA-256-CBC") }
ListElement { name : qsTr("none") }
}
clickedFunction: function() { Layout.fillWidth: true
cipherDropDown.text = selectedText Layout.topMargin: 24
cipher = cipherDropDown.text parentFlickable: fl
cipherDropDown.closeTriggered()
}
Component.onCompleted: { text: qsTr("Auto-negotiate encryption")
cipherDropDown.text = cipher checked: autoNegotiateEncryprion
for (var i = 0; i < cipherListView.model.count; i++) { onCheckedChanged: {
if (cipherListView.model.get(i).name === cipherDropDown.text) { if (checked !== autoNegotiateEncryprion) {
currentIndex = i autoNegotiateEncryprion = checked
}
} }
} }
}
}
}
Rectangle { DropDownType {
id: contentRect id: hashDropDown
Layout.fillWidth: true Layout.fillWidth: true
Layout.topMargin: 32 Layout.topMargin: 20
Layout.leftMargin: 16
Layout.rightMargin: 16
Layout.preferredHeight: checkboxLayout.implicitHeight enabled: !autoNegotiateEncryprionSwitcher.checked
color: AmneziaStyle.color.onyxBlack
radius: 16
ColumnLayout { descriptionText: qsTr("Hash")
id: checkboxLayout headerText: qsTr("Hash")
anchors.fill: parent drawerParent: root
CheckBoxType { listView: ListViewWithRadioButtonType {
id: tlsAuthCheckBox id: hashListView
Layout.fillWidth: true
text: qsTr("TLS auth") rootWidth: root.width
checked: tlsAuth
onCheckedChanged: { model: ListModel {
if (checked !== tlsAuth) { ListElement { name : qsTr("SHA512") }
console.log("tlsAuth changed to: " + checked) ListElement { name : qsTr("SHA384") }
tlsAuth = checked ListElement { name : qsTr("SHA256") }
ListElement { name : qsTr("SHA3-512") }
ListElement { name : qsTr("SHA3-384") }
ListElement { name : qsTr("SHA3-256") }
ListElement { name : qsTr("whirlpool") }
ListElement { name : qsTr("BLAKE2b512") }
ListElement { name : qsTr("BLAKE2s256") }
ListElement { name : qsTr("SHA1") }
}
clickedFunction: function() {
hashDropDown.text = selectedText
hash = hashDropDown.text
hashDropDown.closeTriggered()
}
Component.onCompleted: {
hashDropDown.text = hash
for (var i = 0; i < hashListView.model.count; i++) {
if (hashListView.model.get(i).name === hashDropDown.text) {
currentIndex = i
}
}
}
} }
} }
}
DividerType {} DropDownType {
id: cipherDropDown
Layout.fillWidth: true
Layout.topMargin: 16
CheckBoxType { enabled: !autoNegotiateEncryprionSwitcher.checked
id: blockDnsCheckBox
Layout.fillWidth: true
text: qsTr("Block DNS requests outside of VPN") descriptionText: qsTr("Cipher")
checked: blockDns headerText: qsTr("Cipher")
onCheckedChanged: { drawerParent: root
if (checked !== blockDns) {
blockDns = checked listView: ListViewWithRadioButtonType {
id: cipherListView
rootWidth: root.width
model: ListModel {
ListElement { name : qsTr("AES-256-GCM") }
ListElement { name : qsTr("AES-192-GCM") }
ListElement { name : qsTr("AES-128-GCM") }
ListElement { name : qsTr("AES-256-CBC") }
ListElement { name : qsTr("AES-192-CBC") }
ListElement { name : qsTr("AES-128-CBC") }
ListElement { name : qsTr("ChaCha20-Poly1305") }
ListElement { name : qsTr("ARIA-256-CBC") }
ListElement { name : qsTr("CAMELLIA-256-CBC") }
ListElement { name : qsTr("none") }
}
clickedFunction: function() {
cipherDropDown.text = selectedText
cipher = cipherDropDown.text
cipherDropDown.closeTriggered()
}
Component.onCompleted: {
cipherDropDown.text = cipher
for (var i = 0; i < cipherListView.model.count; i++) {
if (cipherListView.model.get(i).name === cipherDropDown.text) {
currentIndex = i
}
}
}
} }
} }
}
}
}
SwitcherType { Rectangle {
id: additionalClientCommandsSwitcher id: contentRect
Layout.fillWidth: true Layout.fillWidth: true
Layout.topMargin: 32 Layout.topMargin: 32
Layout.leftMargin: 16 Layout.preferredHeight: checkboxLayout.implicitHeight
Layout.rightMargin: 16 color: AmneziaStyle.color.onyxBlack
radius: 16
checked: additionalClientCommands !== "" Connections {
target: tlsAuthCheckBox
enabled: !GC.isMobile()
text: qsTr("Additional client configuration commands") function onFocusChanged() {
if (tlsAuthCheckBox.activeFocus) {
fl.ensureVisible(contentRect)
}
}
}
onCheckedChanged: { ColumnLayout {
if (!checked) { id: checkboxLayout
additionalClientCommands = ""
}
}
}
TextAreaType { anchors.fill: parent
id: additionalClientCommandsTextArea CheckBoxType {
Layout.fillWidth: true id: tlsAuthCheckBox
Layout.topMargin: 16 Layout.fillWidth: true
Layout.leftMargin: 16
Layout.rightMargin: 16
visible: additionalClientCommandsSwitcher.checked text: qsTr("TLS auth")
checked: tlsAuth
textAreaText: additionalClientCommands onCheckedChanged: {
placeholderText: qsTr("Commands:") if (checked !== tlsAuth) {
console.log("tlsAuth changed to: " + checked)
tlsAuth = checked
}
}
}
textArea.onEditingFinished: { DividerType {}
if (additionalClientCommands !== textAreaText) {
additionalClientCommands = textAreaText
}
}
}
SwitcherType { CheckBoxType {
id: additionalServerCommandsSwitcher id: blockDnsCheckBox
Layout.fillWidth: true Layout.fillWidth: true
Layout.topMargin: 16
Layout.leftMargin: 16
Layout.rightMargin: 16
checked: additionalServerCommands !== "" text: qsTr("Block DNS requests outside of VPN")
checked: blockDns
text: qsTr("Additional server configuration commands") onCheckedChanged: {
if (checked !== blockDns) {
onCheckedChanged: { blockDns = checked
if (!checked) { }
additionalServerCommands = "" }
} }
} }
}
TextAreaType {
id: additionalServerCommandsTextArea
Layout.fillWidth: true
Layout.topMargin: 16
Layout.leftMargin: 16
Layout.rightMargin: 16
visible: additionalServerCommandsSwitcher.checked
textAreaText: additionalServerCommands
placeholderText: qsTr("Commands:")
textArea.onEditingFinished: {
if (additionalServerCommands !== textAreaText) {
additionalServerCommands = textAreaText
}
}
}
BasicButtonType {
id: saveButton
Layout.fillWidth: true
Layout.topMargin: 24
Layout.bottomMargin: 24
Layout.leftMargin: 16
Layout.rightMargin: 16
enabled: vpnAddressSubnetTextField.errorText === "" &&
portTextField.errorText === ""
text: qsTr("Save")
onClicked: function() {
forceActiveFocus()
var headerText = qsTr("Save settings?")
var descriptionText = qsTr("All users with whom you shared a connection with will no longer be able to connect to it.")
var yesButtonText = qsTr("Continue")
var noButtonText = qsTr("Cancel")
var yesButtonFunction = function() {
if (ConnectionController.isConnected && ServersModel.getDefaultServerData("defaultContainer") === ContainersModel.getProcessedContainerIndex()) {
PageController.showNotificationMessage(qsTr("Unable change settings while there is an active connection"))
return
} }
PageController.goToPage(PageEnum.PageSetupWizardInstalling); SwitcherType {
InstallController.updateContainer(OpenVpnConfigModel.getConfig()) id: additionalClientCommandsSwitcher
} Layout.fillWidth: true
var noButtonFunction = function() { Layout.topMargin: 32
if (!GC.isMobile()) { parentFlickable: fl
saveButton.forceActiveFocus()
checked: additionalClientCommands !== ""
text: qsTr("Additional client configuration commands")
onCheckedChanged: {
if (!checked) {
additionalClientCommands = ""
}
}
}
TextAreaType {
id: additionalClientCommandsTextArea
Layout.fillWidth: true
Layout.topMargin: 16
visible: additionalClientCommandsSwitcher.checked
parentFlickable: fl
textAreaText: additionalClientCommands
placeholderText: qsTr("Commands:")
textArea.onEditingFinished: {
if (additionalClientCommands !== textAreaText) {
additionalClientCommands = textAreaText
}
}
}
SwitcherType {
id: additionalServerCommandsSwitcher
Layout.fillWidth: true
Layout.topMargin: 16
parentFlickable: fl
checked: additionalServerCommands !== ""
text: qsTr("Additional server configuration commands")
onCheckedChanged: {
if (!checked) {
additionalServerCommands = ""
}
}
}
TextAreaType {
id: additionalServerCommandsTextArea
Layout.fillWidth: true
Layout.topMargin: 16
visible: additionalServerCommandsSwitcher.checked
textAreaText: additionalServerCommands
placeholderText: qsTr("Commands:")
parentFlickable: fl
textArea.onEditingFinished: {
if (additionalServerCommands !== textAreaText) {
additionalServerCommands = textAreaText
}
}
}
BasicButtonType {
id: saveButton
Layout.fillWidth: true
Layout.topMargin: 24
Layout.bottomMargin: 24
enabled: vpnAddressSubnetTextField.errorText === "" &&
portTextField.errorText === ""
text: qsTr("Save")
parentFlickable: fl
onClicked: function() {
forceActiveFocus()
var headerText = qsTr("Save settings?")
var descriptionText = qsTr("All users with whom you shared a connection with will no longer be able to connect to it.")
var yesButtonText = qsTr("Continue")
var noButtonText = qsTr("Cancel")
var yesButtonFunction = function() {
if (ConnectionController.isConnected && ServersModel.getDefaultServerData("defaultContainer") === ContainersModel.getProcessedContainerIndex()) {
PageController.showNotificationMessage(qsTr("Unable change settings while there is an active connection"))
return
}
PageController.goToPage(PageEnum.PageSetupWizardInstalling);
InstallController.updateContainer(OpenVpnConfigModel.getConfig())
}
var noButtonFunction = function() {
if (!GC.isMobile()) {
saveButton.forceActiveFocus()
}
}
showQuestionDrawer(headerText, descriptionText, yesButtonText, noButtonText, yesButtonFunction, noButtonFunction)
}
Keys.onEnterPressed: saveButton.clicked()
Keys.onReturnPressed: saveButton.clicked()
} }
} }
showQuestionDrawer(headerText, descriptionText, yesButtonText, noButtonText, yesButtonFunction, noButtonFunction)
} }
Keys.onEnterPressed: saveButton.clicked()
Keys.onReturnPressed: saveButton.clicked()
} }
} }
} }
@@ -66,6 +66,8 @@ PageType {
Layout.leftMargin: 16 Layout.leftMargin: 16
Layout.rightMargin: 16 Layout.rightMargin: 16
enabled: delegateItem.isEnabled
headerText: qsTr("VPN address subnet") headerText: qsTr("VPN address subnet")
textField.text: subnetAddress textField.text: subnetAddress
@@ -85,6 +87,8 @@ PageType {
Layout.leftMargin: 16 Layout.leftMargin: 16
Layout.rightMargin: 16 Layout.rightMargin: 16
enabled: delegateItem.isEnabled
headerText: qsTr("Port") headerText: qsTr("Port")
textField.text: port textField.text: port
textField.maximumLength: 5 textField.maximumLength: 5
+4
View File
@@ -43,6 +43,8 @@ PageType {
LabelWithButtonType { LabelWithButtonType {
Layout.fillWidth: true Layout.fillWidth: true
Layout.leftMargin: 16
Layout.rightMargin: 16
visible: isVisible visible: isVisible
@@ -66,6 +68,8 @@ PageType {
visible: GC.isDesktop() visible: GC.isDesktop()
Layout.fillWidth: true Layout.fillWidth: true
Layout.leftMargin: 16
Layout.rightMargin: 16
text: qsTr("Close application") text: qsTr("Close application")
leftImageSource: "qrc:/images/controls/x-circle.svg" leftImageSource: "qrc:/images/controls/x-circle.svg"
+11 -7
View File
@@ -66,13 +66,6 @@ PageType {
text: qsTr("If AmneziaDNS is not used or installed") text: qsTr("If AmneziaDNS is not used or installed")
} }
}
model: 1 // fake model to force the ListView to be created without a model
delegate: ColumnLayout {
width: listView.width
spacing: 16
TextFieldWithHeaderType { TextFieldWithHeaderType {
id: primaryDns id: primaryDns
@@ -103,6 +96,13 @@ PageType {
regularExpression: InstallController.ipAddressRegExp() regularExpression: InstallController.ipAddressRegExp()
} }
} }
}
model: 1 // fake model to force the ListView to be created without a model
spacing: 16
delegate: ColumnLayout {
width: listView.width
BasicButtonType { BasicButtonType {
id: restoreDefaultButton id: restoreDefaultButton
@@ -139,6 +139,10 @@ PageType {
showQuestionDrawer(headerText, "", yesButtonText, noButtonText, yesButtonFunction, noButtonFunction) showQuestionDrawer(headerText, "", yesButtonText, noButtonText, yesButtonFunction, noButtonFunction)
} }
} }
}
footer: ColumnLayout {
width: listView.width
BasicButtonType { BasicButtonType {
id: saveButton id: saveButton
@@ -18,8 +18,6 @@ PageType {
signal lastItemTabClickedSignal() signal lastItemTabClickedSignal()
property bool isServerWithWriteAccess: ServersModel.isProcessedServerHasWriteAccess()
Connections { Connections {
target: InstallController target: InstallController
@@ -61,13 +59,15 @@ PageType {
target: ServersModel target: ServersModel
function onProcessedServerIndexChanged() { function onProcessedServerIndexChanged() {
root.isServerWithWriteAccess = ServersModel.isProcessedServerHasWriteAccess() listView.isServerWithWriteAccess = ServersModel.isProcessedServerHasWriteAccess()
} }
} }
ListViewType { ListViewType {
id: listView id: listView
property bool isServerWithWriteAccess: ServersModel.isProcessedServerHasWriteAccess()
anchors.fill: parent anchors.fill: parent
model: serverActions model: serverActions
@@ -107,7 +107,7 @@ PageType {
QtObject { QtObject {
id: check id: check
property bool isVisible: root.isServerWithWriteAccess property bool isVisible: true
readonly property string title: qsTr("Check the server for previously installed Amnezia services") readonly property string title: qsTr("Check the server for previously installed Amnezia services")
readonly property string description: qsTr("Add them to the application if they were not displayed") readonly property string description: qsTr("Add them to the application if they were not displayed")
readonly property var tColor: AmneziaStyle.color.paleGray readonly property var tColor: AmneziaStyle.color.paleGray
@@ -121,7 +121,7 @@ PageType {
QtObject { QtObject {
id: reboot id: reboot
property bool isVisible: root.isServerWithWriteAccess property bool isVisible: true
readonly property string title: qsTr("Reboot server") readonly property string title: qsTr("Reboot server")
readonly property string description: "" readonly property string description: ""
readonly property var tColor: AmneziaStyle.color.vibrantRed readonly property var tColor: AmneziaStyle.color.vibrantRed
@@ -181,7 +181,7 @@ PageType {
QtObject { QtObject {
id: clear id: clear
property bool isVisible: root.isServerWithWriteAccess property bool isVisible: true
readonly property string title: qsTr("Clear server from Amnezia software") readonly property string title: qsTr("Clear server from Amnezia software")
readonly property string description: "" readonly property string description: ""
readonly property var tColor: AmneziaStyle.color.vibrantRed readonly property var tColor: AmneziaStyle.color.vibrantRed
@@ -240,7 +240,7 @@ PageType {
QtObject { QtObject {
id: switch_to_premium id: switch_to_premium
property bool isVisible: ServersModel.getProcessedServerData("isServerFromTelegramApi") && ServersModel.processedServerIsPremium property bool isVisible: ServersModel.getProcessedServerData("isServerFromTelegramApi")
readonly property string title: qsTr("Switch to the new Amnezia Premium subscription") readonly property string title: qsTr("Switch to the new Amnezia Premium subscription")
readonly property string description: "" readonly property string description: ""
readonly property var tColor: AmneziaStyle.color.vibrantRed readonly property var tColor: AmneziaStyle.color.vibrantRed
@@ -161,4 +161,10 @@ PageType {
} }
} }
} }
ShareConnectionDrawer {
id: shareConnectionDrawer
anchors.fill: parent
}
} }
+42 -49
View File
@@ -32,8 +32,8 @@
VpnConnection::VpnConnection(std::shared_ptr<Settings> settings, QObject *parent) VpnConnection::VpnConnection(std::shared_ptr<Settings> settings, QObject *parent)
: QObject(parent), m_settings(settings), m_checkTimer(new QTimer(this)) : QObject(parent), m_settings(settings), m_checkTimer(new QTimer(this))
{ {
#if defined(Q_OS_IOS) || defined(MACOS_NE)
m_checkTimer.setInterval(1000); m_checkTimer.setInterval(1000);
#if defined(Q_OS_IOS) || defined(MACOS_NE)
connect(IosController::Instance(), &IosController::connectionStateChanged, this, &VpnConnection::onConnectionStateChanged); connect(IosController::Instance(), &IosController::connectionStateChanged, this, &VpnConnection::onConnectionStateChanged);
connect(IosController::Instance(), &IosController::bytesChanged, this, &VpnConnection::onBytesChanged); connect(IosController::Instance(), &IosController::bytesChanged, this, &VpnConnection::onBytesChanged);
@@ -42,6 +42,9 @@ VpnConnection::VpnConnection(std::shared_ptr<Settings> settings, QObject *parent
VpnConnection::~VpnConnection() VpnConnection::~VpnConnection()
{ {
#if defined AMNEZIA_DESKTOP
disconnectFromVpn();
#endif
} }
void VpnConnection::onBytesChanged(quint64 receivedBytes, quint64 sentBytes) void VpnConnection::onBytesChanged(quint64 receivedBytes, quint64 sentBytes)
@@ -52,7 +55,19 @@ void VpnConnection::onBytesChanged(quint64 receivedBytes, quint64 sentBytes)
void VpnConnection::onKillSwitchModeChanged(bool enabled) void VpnConnection::onKillSwitchModeChanged(bool enabled)
{ {
#ifdef AMNEZIA_DESKTOP #ifdef AMNEZIA_DESKTOP
if (InterfaceReady()) { if (!m_IpcClient) {
m_IpcClient = new IpcClient(this);
}
if (!m_IpcClient->isSocketConnected()) {
if (!IpcClient::init(m_IpcClient)) {
qWarning() << "Error occurred when init IPC client";
emit serviceIsNotReady();
return;
}
}
if (IpcClient::Interface()) {
qDebug() << "Set KillSwitch Strict mode enabled " << enabled; qDebug() << "Set KillSwitch Strict mode enabled " << enabled;
IpcClient::Interface()->refreshKillSwitch(enabled); IpcClient::Interface()->refreshKillSwitch(enabled);
} }
@@ -65,10 +80,12 @@ void VpnConnection::onConnectionStateChanged(Vpn::ConnectionState state)
#ifdef AMNEZIA_DESKTOP #ifdef AMNEZIA_DESKTOP
auto container = m_settings->defaultContainer(m_settings->defaultServerIndex()); auto container = m_settings->defaultContainer(m_settings->defaultServerIndex());
if (InterfaceReady()) { if (IpcClient::Interface()) {
if (state == Vpn::ConnectionState::Connected) { if (state == Vpn::ConnectionState::Connected) {
IpcClient::Interface()->resetIpStack(); IpcClient::Interface()->resetIpStack();
IpcClient::Interface()->flushDns(); if (container != DockerContainer::Ipsec) {
IpcClient::Interface()->flushDns();
}
if (container != DockerContainer::Awg && container != DockerContainer::WireGuard) { if (container != DockerContainer::Awg && container != DockerContainer::WireGuard) {
QString dns1 = m_vpnConfiguration.value(config_key::dns1).toString(); QString dns1 = m_vpnConfiguration.value(config_key::dns1).toString();
@@ -197,41 +214,14 @@ void VpnConnection::deleteRoutes(const QStringList &ips)
#endif #endif
} }
bool VpnConnection::InterfaceReady()
{
#ifdef AMNEZIA_DESKTOP
if (!m_IpcClient) {
m_IpcClient = new IpcClient(this);
}
if (!m_IpcClient->isSocketConnected()) {
if (!IpcClient::init(m_IpcClient)) {
qWarning() << "Error occurred when init IPC client";
emit serviceIsNotReady();
return false;
}
}
return IpcClient::Interface() != nullptr;
#endif
return true;
}
void VpnConnection::flushDns() void VpnConnection::flushDns()
{ {
#ifdef AMNEZIA_DESKTOP #ifdef AMNEZIA_DESKTOP
if (InterfaceReady()) if (IpcClient::Interface())
IpcClient::Interface()->flushDns(); IpcClient::Interface()->flushDns();
#endif #endif
} }
void VpnConnection::disconnectSlots()
{
if (m_vpnProtocol) {
m_vpnProtocol->disconnect();
}
}
ErrorCode VpnConnection::lastError() const ErrorCode VpnConnection::lastError() const
{ {
#ifdef Q_OS_ANDROID #ifdef Q_OS_ANDROID
@@ -252,12 +242,21 @@ void VpnConnection::connectToVpn(int serverIndex, const ServerCredentials &crede
.arg(serverIndex) .arg(serverIndex)
.arg(ContainerProps::containerToString(container)) .arg(ContainerProps::containerToString(container))
<< m_settings->routeMode(); << m_settings->routeMode();
#if !defined(Q_OS_ANDROID) && !defined(Q_OS_IOS) && !defined(MACOS_NE)
if (!InterfaceReady()) { if (!m_IpcClient) {
emit connectionStateChanged(Vpn::ConnectionState::Error); m_IpcClient = new IpcClient(this);
return;
} }
if (!m_IpcClient->isSocketConnected()) {
if (!IpcClient::init(m_IpcClient)) {
qWarning() << "Error occurred when init IPC client";
emit serviceIsNotReady();
emit connectionStateChanged(Vpn::ConnectionState::Error);
return;
}
}
#endif
m_remoteAddress = NetworkUtilities::getIPAddress(credentials.hostName); m_remoteAddress = NetworkUtilities::getIPAddress(credentials.hostName);
emit connectionStateChanged(Vpn::ConnectionState::Connecting); emit connectionStateChanged(Vpn::ConnectionState::Connecting);
@@ -443,18 +442,13 @@ QString VpnConnection::bytesPerSecToText(quint64 bytes)
void VpnConnection::disconnectFromVpn() void VpnConnection::disconnectFromVpn()
{ {
#ifdef AMNEZIA_DESKTOP #ifdef AMNEZIA_DESKTOP
if (InterfaceReady()) { QString proto = m_settings->defaultContainerName(m_settings->defaultServerIndex());
if (IpcClient::Interface()) {
IpcClient::Interface()->flushDns();
m_vpnProtocol.data()->stop();
qDebug() << "Interface is ready!";
QRemoteObjectPendingReply<bool> flushDnsResp = IpcClient::Interface()->flushDns();
flushDnsResp.waitForFinished(1000);
qDebug() << "Flushed DNS";
// delete cached routes // delete cached routes
QRemoteObjectPendingReply<bool> clearSavedRoutesResp = IpcClient::Interface()->clearSavedRoutes(); QRemoteObjectPendingReply<bool> response = IpcClient::Interface()->clearSavedRoutes();
clearSavedRoutesResp.waitForFinished(1000); response.waitForFinished(1000);
} }
#endif #endif
@@ -483,13 +477,12 @@ void VpnConnection::disconnectFromVpn()
return; return;
} }
#if !defined(Q_OS_ANDROID) && !defined(AMNEZIA_DESKTOP) #ifndef Q_OS_ANDROID
if (m_vpnProtocol) { if (m_vpnProtocol) {
m_vpnProtocol->deleteLater(); m_vpnProtocol->deleteLater();
} }
#endif
m_vpnProtocol = nullptr; m_vpnProtocol = nullptr;
#endif
} }
Vpn::ConnectionState VpnConnection::connectionState() Vpn::ConnectionState VpnConnection::connectionState()
-2
View File
@@ -56,7 +56,6 @@ public slots:
void deleteRoutes(const QStringList &ips); void deleteRoutes(const QStringList &ips);
void flushDns(); void flushDns();
void onKillSwitchModeChanged(bool enabled); void onKillSwitchModeChanged(bool enabled);
void disconnectSlots();
signals: signals:
void bytesChanged(quint64 receivedBytes, quint64 sentBytes); void bytesChanged(quint64 receivedBytes, quint64 sentBytes);
@@ -96,7 +95,6 @@ private:
void appendSplitTunnelingConfig(); void appendSplitTunnelingConfig();
void appendKillSwitchConfig(); void appendKillSwitchConfig();
bool InterfaceReady();
}; };
#endif // VPNCONNECTION_H #endif // VPNCONNECTION_H
+15 -3
View File
@@ -12,7 +12,7 @@ class IpcInterface
SLOT( int routeAddList(const QString &gw, const QStringList &ips) ); SLOT( int routeAddList(const QString &gw, const QStringList &ips) );
SLOT( bool clearSavedRoutes() ); SLOT( bool clearSavedRoutes() );
SLOT( bool routeDeleteList(const QString &gw, const QStringList &ip) ); SLOT( bool routeDeleteList(const QString &gw, const QStringList &ip) );
SLOT( bool flushDns() ); SLOT( void flushDns() );
SLOT( void resetIpStack() ); SLOT( void resetIpStack() );
SLOT( bool checkAndInstallDriver() ); SLOT( bool checkAndInstallDriver() );
@@ -25,8 +25,8 @@ class IpcInterface
SLOT( bool createTun(const QString &dev, const QString &subnet) ); SLOT( bool createTun(const QString &dev, const QString &subnet) );
SLOT( bool deleteTun(const QString &dev) ); SLOT( bool deleteTun(const QString &dev) );
SLOT( bool StartRoutingIpv6() ); SLOT( void StartRoutingIpv6() );
SLOT( bool StopRoutingIpv6() ); SLOT( void StopRoutingIpv6() );
SLOT( bool disableKillSwitch() ); SLOT( bool disableKillSwitch() );
SLOT( bool disableAllTraffic() ); SLOT( bool disableAllTraffic() );
@@ -36,5 +36,17 @@ class IpcInterface
SLOT( bool enablePeerTraffic( const QJsonObject &configStr) ); SLOT( bool enablePeerTraffic( const QJsonObject &configStr) );
SLOT( bool enableKillSwitch( const QJsonObject &excludeAddr, int vpnAdapterIndex) ); SLOT( bool enableKillSwitch( const QJsonObject &excludeAddr, int vpnAdapterIndex) );
SLOT( bool updateResolvers(const QString& ifname, const QList<QHostAddress>& resolvers) ); SLOT( bool updateResolvers(const QString& ifname, const QList<QHostAddress>& resolvers) );
SLOT( bool writeIPsecCaCert(QString cacert, QString uuid) );
SLOT( bool writeIPsecPrivate(QString privKey, QString uuid) );
SLOT( bool writeIPsecConfig(QString config) );
SLOT( bool writeIPsecUserCert(QString usercert, QString uuid) );
SLOT( bool writeIPsecPrivatePass(QString pass, QString host, QString uuid) );
SLOT( bool stopIPsec(QString tunnelName) );
SLOT( bool startIPsec(QString tunnelName) );
SLOT( QString getTunnelStatus(QString tunnelName) );
}; };
+197 -5
View File
@@ -4,6 +4,7 @@
#include <QFileInfo> #include <QFileInfo>
#include <QLocalSocket> #include <QLocalSocket>
#include <QObject> #include <QObject>
#include <QJsonArray>
#include "logger.h" #include "logger.h"
#include "router.h" #include "router.h"
@@ -83,7 +84,7 @@ bool IpcServer::routeDeleteList(const QString &gw, const QStringList &ips)
return Router::routeDeleteList(gw, ips); return Router::routeDeleteList(gw, ips);
} }
bool IpcServer::flushDns() void IpcServer::flushDns()
{ {
#ifdef MZ_DEBUG #ifdef MZ_DEBUG
qDebug() << "IpcServer::flushDns"; qDebug() << "IpcServer::flushDns";
@@ -157,13 +158,14 @@ bool IpcServer::updateResolvers(const QString &ifname, const QList<QHostAddress>
return Router::updateResolvers(ifname, resolvers); return Router::updateResolvers(ifname, resolvers);
} }
bool IpcServer::StartRoutingIpv6() void IpcServer::StartRoutingIpv6()
{ {
return Router::StartRoutingIpv6(); Router::StartRoutingIpv6();
} }
bool IpcServer::StopRoutingIpv6()
void IpcServer::StopRoutingIpv6()
{ {
return Router::StopRoutingIpv6(); Router::StopRoutingIpv6();
} }
void IpcServer::setLogsEnabled(bool enabled) void IpcServer::setLogsEnabled(bool enabled)
@@ -204,6 +206,196 @@ bool IpcServer::disableKillSwitch()
return KillSwitch::instance()->disableKillSwitch(); return KillSwitch::instance()->disableKillSwitch();
} }
bool IpcServer::startIPsec(QString tunnelName)
{
#ifdef Q_OS_LINUX
QProcess processSystemd;
QStringList commandsSystemd;
commandsSystemd << "systemctl" << "restart" << "ipsec";
processSystemd.start("sudo", commandsSystemd);
if (!processSystemd.waitForStarted(1000))
{
qDebug().noquote() << "Could not start ipsec tunnel!\n";
return false;
}
else if (!processSystemd.waitForFinished(2000))
{
qDebug().noquote() << "Could not start ipsec tunnel\n";
return false;
}
commandsSystemd.clear();
QThread::msleep(5000);
QProcess process;
QStringList commands;
commands << "ipsec" << "up" << QString("%1").arg(tunnelName);
process.start("sudo", commands);
if (!process.waitForStarted(1000))
{
qDebug().noquote() << "Could not start ipsec tunnel!\n";
return false;
}
else if (!process.waitForFinished(2000))
{
qDebug().noquote() << "Could not start ipsec tunnel\n";
return false;
}
commands.clear();
#endif
return true;
}
bool IpcServer::stopIPsec(QString tunnelName)
{
#ifdef Q_OS_LINUX
QProcess process;
QStringList commands;
commands << "ipsec" << "down" << QString("%1").arg(tunnelName);
process.start("sudo", commands);
if (!process.waitForStarted(1000))
{
qDebug().noquote() << "Could not stop ipsec tunnel\n";
return false;
}
else if (!process.waitForFinished(2000))
{
qDebug().noquote() << "Could not stop ipsec tunnel\n";
return false;
}
commands.clear();
#endif
return true;
}
bool IpcServer::writeIPsecConfig(QString config)
{
#ifdef Q_OS_LINUX
qDebug() << "IPSEC: IPSec config file";
QString configFile = QString("/etc/ipsec.conf");
QFile ipSecConfFile(configFile);
if (ipSecConfFile.open(QIODevice::WriteOnly)) {
ipSecConfFile.write(config.toUtf8());
ipSecConfFile.close();
}
#endif
return true;
}
bool IpcServer::writeIPsecUserCert(QString usercert, QString uuid)
{
#ifdef Q_OS_LINUX
qDebug() << "IPSEC: Write user cert " << uuid;
QString certName = QString("/etc/ipsec.d/certs/%1.crt").arg(uuid);
QFile userCertFile(certName);
if (userCertFile.open(QIODevice::WriteOnly)) {
userCertFile.write(usercert.toUtf8());
userCertFile.close();
}
#endif
return true;
}
bool IpcServer::writeIPsecCaCert(QString cacert, QString uuid)
{
#ifdef Q_OS_LINUX
qDebug() << "IPSEC: Write CA cert user " << uuid;
QString certName = QString("/etc/ipsec.d/cacerts/%1.crt").arg(uuid);
QFile caCertFile(certName);
if (caCertFile.open(QIODevice::WriteOnly)) {
caCertFile.write(cacert.toUtf8());
caCertFile.close();
}
#endif
return true;
}
bool IpcServer::writeIPsecPrivate(QString privKey, QString uuid)
{
#ifdef Q_OS_LINUX
qDebug() << "IPSEC: User private key " << uuid;
QString privateKey = QString("/etc/ipsec.d/private/%1.p12").arg(uuid);
QFile pKeyFile(privateKey);
if (pKeyFile.open(QIODevice::WriteOnly)) {
pKeyFile.write(QByteArray::fromBase64(privKey.toUtf8()));
pKeyFile.close();
}
#endif
return true;
}
bool IpcServer::writeIPsecPrivatePass(QString pass, QString host, QString uuid)
{
#ifdef Q_OS_LINUX
qDebug() << "IPSEC: User private key " << uuid;
const QString secretsFilename = "/etc/ipsec.secrets";
QStringList lines;
{
QFile secretsFile(secretsFilename);
if (secretsFile.open(QIODevice::ReadOnly | QIODevice::Text))
{
QTextStream edit(&secretsFile);
while (!edit.atEnd()) lines.push_back(edit.readLine());
}
secretsFile.close();
}
for (auto iter = lines.begin(); iter!=lines.end();)
{
if (iter->contains(host))
{
iter = lines.erase(iter);
}
else
{
++iter;
}
}
{
QFile secretsFile(secretsFilename);
if (secretsFile.open(QIODevice::WriteOnly | QIODevice::Text))
{
QTextStream edit(&secretsFile);
for (int i=0; i<lines.size(); i++) edit << lines[i] << Qt::endl;
}
QString P12 = QString("%any %1 : P12 %2.p12 \"%3\" \n").arg(host, uuid, pass);
secretsFile.write(P12.toUtf8());
secretsFile.close();
}
#endif
return true;
}
QString IpcServer::getTunnelStatus(QString tunnelName)
{
#ifdef Q_OS_LINUX
QProcess process;
QStringList commands;
commands << "ipsec" << "status" << QString("%1").arg(tunnelName);
process.start("sudo", commands);
if (!process.waitForStarted(1000))
{
qDebug().noquote() << "Could not stop ipsec tunnel\n";
return "";
}
else if (!process.waitForFinished(2000))
{
qDebug().noquote() << "Could not stop ipsec tunnel\n";
return "";
}
commands.clear();
QString status = process.readAll();
return status;
#endif
return QString();
}
bool IpcServer::enablePeerTraffic(const QJsonObject &configStr) bool IpcServer::enablePeerTraffic(const QJsonObject &configStr)
{ {
return KillSwitch::instance()->enablePeerTraffic(configStr); return KillSwitch::instance()->enablePeerTraffic(configStr);
+11 -3
View File
@@ -23,7 +23,7 @@ public:
virtual int routeAddList(const QString &gw, const QStringList &ips) override; virtual int routeAddList(const QString &gw, const QStringList &ips) override;
virtual bool clearSavedRoutes() override; virtual bool clearSavedRoutes() override;
virtual bool routeDeleteList(const QString &gw, const QStringList &ips) override; virtual bool routeDeleteList(const QString &gw, const QStringList &ips) override;
virtual bool flushDns() override; virtual void flushDns() override;
virtual void resetIpStack() override; virtual void resetIpStack() override;
virtual bool checkAndInstallDriver() override; virtual bool checkAndInstallDriver() override;
virtual QStringList getTapList() override; virtual QStringList getTapList() override;
@@ -32,8 +32,8 @@ public:
virtual void setLogsEnabled(bool enabled) override; virtual void setLogsEnabled(bool enabled) override;
virtual bool createTun(const QString &dev, const QString &subnet) override; virtual bool createTun(const QString &dev, const QString &subnet) override;
virtual bool deleteTun(const QString &dev) override; virtual bool deleteTun(const QString &dev) override;
virtual bool StartRoutingIpv6() override; virtual void StartRoutingIpv6() override;
virtual bool StopRoutingIpv6() override; virtual void StopRoutingIpv6() override;
virtual bool disableAllTraffic() override; virtual bool disableAllTraffic() override;
virtual bool addKillSwitchAllowedRange(QStringList ranges) override; virtual bool addKillSwitchAllowedRange(QStringList ranges) override;
virtual bool resetKillSwitchAllowedRange(QStringList ranges) override; virtual bool resetKillSwitchAllowedRange(QStringList ranges) override;
@@ -42,6 +42,14 @@ public:
virtual bool disableKillSwitch() override; virtual bool disableKillSwitch() override;
virtual bool refreshKillSwitch( bool enabled ) override; virtual bool refreshKillSwitch( bool enabled ) override;
virtual bool updateResolvers(const QString& ifname, const QList<QHostAddress>& resolvers) override; virtual bool updateResolvers(const QString& ifname, const QList<QHostAddress>& resolvers) override;
virtual bool writeIPsecCaCert(QString cacert, QString uuid) override;
virtual bool writeIPsecPrivate(QString privKey, QString uuid) override;
virtual bool writeIPsecConfig(QString config) override;
virtual bool writeIPsecUserCert(QString usercert, QString uuid) override;
virtual bool writeIPsecPrivatePass(QString pass, QString host, QString uuid) override;
virtual bool stopIPsec(QString tunnelName) override;
virtual bool startIPsec(QString tunnelName) override;
virtual QString getTunnelStatus(QString tunnelName) override;
private: private:
int m_localpid = 0; int m_localpid = 0;
-11
View File
@@ -98,17 +98,6 @@ bool KillSwitch::disableKillSwitch() {
LinuxFirewall::setAnchorEnabled(LinuxFirewall::IPv4, QStringLiteral("320.allowDNS"), false); LinuxFirewall::setAnchorEnabled(LinuxFirewall::IPv4, QStringLiteral("320.allowDNS"), false);
LinuxFirewall::setAnchorEnabled(LinuxFirewall::Both, QStringLiteral("400.allowPIA"), false); LinuxFirewall::setAnchorEnabled(LinuxFirewall::Both, QStringLiteral("400.allowPIA"), false);
} else { } else {
LinuxFirewall::setAnchorEnabled(LinuxFirewall::Both, QStringLiteral("000.allowLoopback"), true);
LinuxFirewall::setAnchorEnabled(LinuxFirewall::Both, QStringLiteral("100.blockAll"), false);
LinuxFirewall::setAnchorEnabled(LinuxFirewall::IPv4, QStringLiteral("110.allowNets"), false);
LinuxFirewall::setAnchorEnabled(LinuxFirewall::IPv4, QStringLiteral("120.blockNets"), false);
LinuxFirewall::setAnchorEnabled(LinuxFirewall::IPv4, QStringLiteral("200.allowVPN"), false);
LinuxFirewall::setAnchorEnabled(LinuxFirewall::IPv6, QStringLiteral("250.blockIPv6"), false);
LinuxFirewall::setAnchorEnabled(LinuxFirewall::Both, QStringLiteral("290.allowDHCP"), true);
LinuxFirewall::setAnchorEnabled(LinuxFirewall::Both, QStringLiteral("300.allowLAN"), true);
LinuxFirewall::setAnchorEnabled(LinuxFirewall::IPv4, QStringLiteral("310.blockDNS"), false);
LinuxFirewall::setAnchorEnabled(LinuxFirewall::IPv4, QStringLiteral("320.allowDNS"), false);
LinuxFirewall::setAnchorEnabled(LinuxFirewall::Both, QStringLiteral("400.allowPIA"), false);
LinuxFirewall::uninstall(); LinuxFirewall::uninstall();
} }
#endif #endif
+12 -12
View File
@@ -42,14 +42,14 @@ int Router::routeDeleteList(const QString &gw, const QStringList &ips)
#endif #endif
} }
bool Router::flushDns() void Router::flushDns()
{ {
#ifdef Q_OS_WIN #ifdef Q_OS_WIN
return RouterWin::Instance().flushDns(); RouterWin::Instance().flushDns();
#elif defined (Q_OS_MAC) #elif defined (Q_OS_MAC)
return RouterMac::Instance().flushDns(); RouterMac::Instance().flushDns();
#elif defined Q_OS_LINUX #elif defined Q_OS_LINUX
return RouterLinux::Instance().flushDns(); RouterLinux::Instance().flushDns();
#endif #endif
} }
@@ -100,25 +100,25 @@ bool Router::updateResolvers(const QString& ifname, const QList<QHostAddress>& r
} }
bool Router::StopRoutingIpv6() void Router::StopRoutingIpv6()
{ {
#ifdef Q_OS_WIN #ifdef Q_OS_WIN
return RouterWin::Instance().StopRoutingIpv6(); RouterWin::Instance().StopRoutingIpv6();
#elif defined (Q_OS_MAC) #elif defined (Q_OS_MAC)
return true;// todo fixme // todo fixme
#elif defined Q_OS_LINUX #elif defined Q_OS_LINUX
return RouterLinux::Instance().StopRoutingIpv6(); RouterLinux::Instance().StopRoutingIpv6();
#endif #endif
} }
bool Router::StartRoutingIpv6() void Router::StartRoutingIpv6()
{ {
#ifdef Q_OS_WIN #ifdef Q_OS_WIN
return RouterWin::Instance().StartRoutingIpv6(); RouterWin::Instance().StartRoutingIpv6();
#elif defined (Q_OS_MAC) #elif defined (Q_OS_MAC)
return true;// todo fixme // todo fixme
#elif defined Q_OS_LINUX #elif defined Q_OS_LINUX
return RouterLinux::Instance().StartRoutingIpv6(); RouterLinux::Instance().StartRoutingIpv6();
#endif #endif
} }
+3 -3
View File
@@ -19,12 +19,12 @@ public:
static int routeAddList(const QString &gw, const QStringList &ips); static int routeAddList(const QString &gw, const QStringList &ips);
static bool clearSavedRoutes(); static bool clearSavedRoutes();
static int routeDeleteList(const QString &gw, const QStringList &ips); static int routeDeleteList(const QString &gw, const QStringList &ips);
static bool flushDns(); static void flushDns();
static void resetIpStack(); static void resetIpStack();
static bool createTun(const QString &dev, const QString &subnet); static bool createTun(const QString &dev, const QString &subnet);
static bool deleteTun(const QString &dev); static bool deleteTun(const QString &dev);
static bool StartRoutingIpv6(); static void StartRoutingIpv6();
static bool StopRoutingIpv6(); static void StopRoutingIpv6();
static bool updateResolvers(const QString& ifname, const QList<QHostAddress>& resolvers); static bool updateResolvers(const QString& ifname, const QList<QHostAddress>& resolvers);
}; };
+12 -16
View File
@@ -160,7 +160,7 @@ bool RouterLinux::isServiceActive(const QString &serviceName) {
return process.exitCode() == 0; return process.exitCode() == 0;
} }
bool RouterLinux::flushDns() void RouterLinux::flushDns()
{ {
QProcess p; QProcess p;
p.setProcessChannelMode(QProcess::MergedChannels); p.setProcessChannelMode(QProcess::MergedChannels);
@@ -174,7 +174,7 @@ bool RouterLinux::flushDns()
p.start("systemctl", { "restart", "systemd-resolved" }); p.start("systemctl", { "restart", "systemd-resolved" });
} else { } else {
qDebug() << "No suitable DNS manager found."; qDebug() << "No suitable DNS manager found.";
return false; return;
} }
p.waitForFinished(); p.waitForFinished();
@@ -183,8 +183,6 @@ bool RouterLinux::flushDns()
qDebug().noquote() << "Flush dns completed"; qDebug().noquote() << "Flush dns completed";
else else
qDebug().noquote() << "OUTPUT systemctl restart nscd/systemd-resolved: " + output; qDebug().noquote() << "OUTPUT systemctl restart nscd/systemd-resolved: " + output;
return true;
} }
bool RouterLinux::createTun(const QString &dev, const QString &subnet) { bool RouterLinux::createTun(const QString &dev, const QString &subnet) {
@@ -281,7 +279,7 @@ bool RouterLinux::updateResolvers(const QString& ifname, const QList<QHostAddres
return m_dnsUtil->updateResolvers(ifname, resolvers); return m_dnsUtil->updateResolvers(ifname, resolvers);
} }
bool RouterLinux::StartRoutingIpv6() void RouterLinux::StartRoutingIpv6()
{ {
QProcess process; QProcess process;
QStringList commands; QStringList commands;
@@ -291,12 +289,12 @@ bool RouterLinux::StartRoutingIpv6()
if (!process.waitForStarted(1000)) if (!process.waitForStarted(1000))
{ {
qDebug().noquote() << "Could not start activate ipv6\n"; qDebug().noquote() << "Could not start activate ipv6\n";
return false; return;
} }
else if (!process.waitForFinished(2000)) else if (!process.waitForFinished(2000))
{ {
qDebug().noquote() << "Could not activate ipv6\n"; qDebug().noquote() << "Could not activate ipv6\n";
return false; return;
} }
commands.clear(); commands.clear();
@@ -305,20 +303,19 @@ bool RouterLinux::StartRoutingIpv6()
if (!process.waitForStarted(1000)) if (!process.waitForStarted(1000))
{ {
qDebug().noquote() << "Could not start activate ipv6\n"; qDebug().noquote() << "Could not start activate ipv6\n";
return false; return;
} }
else if (!process.waitForFinished(2000)) else if (!process.waitForFinished(2000))
{ {
qDebug().noquote() << "Could not activate ipv6\n"; qDebug().noquote() << "Could not activate ipv6\n";
return false; return;
} }
commands.clear(); commands.clear();
qDebug().noquote() << "StartRoutingIpv6 OK"; qDebug().noquote() << "StartRoutingIpv6 OK";
return true;
} }
bool RouterLinux::StopRoutingIpv6() void RouterLinux::StopRoutingIpv6()
{ {
QProcess process; QProcess process;
QStringList commands; QStringList commands;
@@ -328,12 +325,12 @@ bool RouterLinux::StopRoutingIpv6()
if (!process.waitForStarted(1000)) if (!process.waitForStarted(1000))
{ {
qDebug().noquote() << "Could not start disable ipv6\n"; qDebug().noquote() << "Could not start disable ipv6\n";
return false; return;
} }
else if (!process.waitForFinished(2000)) else if (!process.waitForFinished(2000))
{ {
qDebug().noquote() << "Could not disable ipv6\n"; qDebug().noquote() << "Could not disable ipv6\n";
return false; return;
} }
commands.clear(); commands.clear();
@@ -342,15 +339,14 @@ bool RouterLinux::StopRoutingIpv6()
if (!process.waitForStarted(1000)) if (!process.waitForStarted(1000))
{ {
qDebug().noquote() << "Could not start disable ipv6\n"; qDebug().noquote() << "Could not start disable ipv6\n";
return false; return;
} }
else if (!process.waitForFinished(2000)) else if (!process.waitForFinished(2000))
{ {
qDebug().noquote() << "Could not disable ipv6\n"; qDebug().noquote() << "Could not disable ipv6\n";
return false; return;
} }
commands.clear(); commands.clear();
qDebug().noquote() << "StopRoutingIpv6 OK"; qDebug().noquote() << "StopRoutingIpv6 OK";
return true;
} }
+3 -3
View File
@@ -30,11 +30,11 @@ public:
bool routeDelete(const QString &ip, const QString &gw, const int &sock); bool routeDelete(const QString &ip, const QString &gw, const int &sock);
bool routeDeleteList(const QString &gw, const QStringList &ips); bool routeDeleteList(const QString &gw, const QStringList &ips);
QString getgatewayandiface(); QString getgatewayandiface();
bool flushDns(); void flushDns();
bool createTun(const QString &dev, const QString &subnet); bool createTun(const QString &dev, const QString &subnet);
bool deleteTun(const QString &dev); bool deleteTun(const QString &dev);
bool StartRoutingIpv6(); void StartRoutingIpv6();
bool StopRoutingIpv6(); void StopRoutingIpv6();
bool updateResolvers(const QString& ifname, const QList<QHostAddress>& resolvers); bool updateResolvers(const QString& ifname, const QList<QHostAddress>& resolvers);
public slots: public slots:
+1 -3
View File
@@ -166,7 +166,7 @@ bool RouterMac::deleteTun(const QString &dev)
return true; return true;
} }
bool RouterMac::flushDns() void RouterMac::flushDns()
{ {
// sudo killall -HUP mDNSResponder // sudo killall -HUP mDNSResponder
QProcess p; QProcess p;
@@ -174,7 +174,5 @@ bool RouterMac::flushDns()
p.start("killall", QStringList() << "-HUP" << "mDNSResponder"); p.start("killall", QStringList() << "-HUP" << "mDNSResponder");
p.waitForFinished(); p.waitForFinished();
qDebug().noquote() << "OUTPUT killall -HUP mDNSResponder: " + p.readAll(); qDebug().noquote() << "OUTPUT killall -HUP mDNSResponder: " + p.readAll();
return true;
} }
+1 -1
View File
@@ -29,7 +29,7 @@ public:
bool clearSavedRoutes(); bool clearSavedRoutes();
bool routeDelete(const QString &ip, const QString &gw); bool routeDelete(const QString &ip, const QString &gw);
bool routeDeleteList(const QString &gw, const QStringList &ips); bool routeDeleteList(const QString &gw, const QStringList &ips);
bool flushDns(); void flushDns();
bool createTun(const QString &dev, const QString &subnet); bool createTun(const QString &dev, const QString &subnet);
bool deleteTun(const QString &dev); bool deleteTun(const QString &dev);
bool updateResolvers(const QString& ifname, const QList<QHostAddress>& resolvers); bool updateResolvers(const QString& ifname, const QList<QHostAddress>& resolvers);
+3 -6
View File
@@ -273,7 +273,7 @@ int RouterWin::routeDeleteList(const QString &gw, const QStringList &ips)
return success_count; return success_count;
} }
bool RouterWin::flushDns() void RouterWin::flushDns()
{ {
QProcess p; QProcess p;
p.setProcessChannelMode(QProcess::MergedChannels); p.setProcessChannelMode(QProcess::MergedChannels);
@@ -281,7 +281,6 @@ bool RouterWin::flushDns()
p.start(command); p.start(command);
p.waitForFinished(); p.waitForFinished();
return true;
//qDebug().noquote() << "OUTPUT ipconfig /flushdns: " + p.readAll(); //qDebug().noquote() << "OUTPUT ipconfig /flushdns: " + p.readAll();
} }
@@ -445,7 +444,7 @@ bool RouterWin::updateResolvers(const QString& ifname, const QList<QHostAddress>
} }
bool RouterWin::StopRoutingIpv6() void RouterWin::StopRoutingIpv6()
{ {
{ {
QProcess p; QProcess p;
@@ -465,10 +464,9 @@ bool RouterWin::StopRoutingIpv6()
p.start(command); p.start(command);
p.waitForFinished(); p.waitForFinished();
} }
return true;
} }
bool RouterWin::StartRoutingIpv6() void RouterWin::StartRoutingIpv6()
{ {
{ {
QProcess p; QProcess p;
@@ -488,6 +486,5 @@ bool RouterWin::StartRoutingIpv6()
p.start(command); p.start(command);
p.waitForFinished(); p.waitForFinished();
} }
return true;
} }
+3 -3
View File
@@ -39,11 +39,11 @@ public:
int routeAddList(const QString &gw, const QStringList &ips); int routeAddList(const QString &gw, const QStringList &ips);
bool clearSavedRoutes(); bool clearSavedRoutes();
int routeDeleteList(const QString &gw, const QStringList &ips); int routeDeleteList(const QString &gw, const QStringList &ips);
bool flushDns(); void flushDns();
void resetIpStack(); void resetIpStack();
bool StartRoutingIpv6(); void StartRoutingIpv6();
bool StopRoutingIpv6(); void StopRoutingIpv6();
void suspendWcmSvc(bool suspend); void suspendWcmSvc(bool suspend);
bool updateResolvers(const QString& ifname, const QList<QHostAddress>& resolvers); bool updateResolvers(const QString& ifname, const QList<QHostAddress>& resolvers);