mirror of
https://github.com/amnezia-vpn/amnezia-client.git
synced 2026-07-03 14:07:39 +02:00
Compare commits
30 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 4205bb1d31 | |||
| 5570cb94b5 | |||
| 45323e67fb | |||
| ae3ed9c741 | |||
| f47e4cb729 | |||
| b5cbcc5f2a | |||
| f18d980bdb | |||
| 81cfab3566 | |||
| 7f123dabac | |||
| de0b400934 | |||
| dcde24649f | |||
| b717560047 | |||
| afd2542a11 | |||
| 1438a21902 | |||
| 4147632a62 | |||
| 948ab4cf71 | |||
| f54308e4f4 | |||
| 052261c2b4 | |||
| 3cec0dc2a7 | |||
| ad61ef0b22 | |||
| 63c569c3d2 | |||
| 30df4c6800 | |||
| a96f9dc18a | |||
| fb63cdf7e9 | |||
| 2d3b9c2752 | |||
| 09c58cb39e | |||
| 654d219e7e | |||
| 89d4c18e87 | |||
| b0b185027e | |||
| 90912f9231 |
@@ -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))
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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()
|
||||||
|
|||||||
@@ -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();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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()
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|||||||
@@ -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";
|
||||||
|
|||||||
@@ -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))
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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"
|
||||||
|
|||||||
@@ -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
@@ -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()
|
||||||
|
|||||||
@@ -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
@@ -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
@@ -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
@@ -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;
|
||||||
|
|||||||
@@ -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
@@ -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
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -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;
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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:
|
||||||
|
|
||||||
|
|||||||
@@ -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;
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|||||||
@@ -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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|||||||
Reference in New Issue
Block a user