Compare commits

...

57 Commits

Author SHA1 Message Date
pokamest 52450ef2f5 Release 1.8 2021-06-17 01:04:09 +03:00
pokamest 69170940c9 Merge pull request #19 from amnezia-vpn/cloak_ss_2
ShadowSocks over cloak
2021-06-17 00:53:48 +03:00
pokamest e89caaee52 bump version 1.7.6 2021-06-17 00:51:15 +03:00
pokamest 0b3535ff13 hide wireguard settings 2021-06-16 22:40:34 +03:00
pokamest e7a22ad159 Export shadowsocks over cloak config support 2021-06-16 22:25:08 +03:00
pokamest 74a517d985 Windows server 2012 support 2021-06-16 22:24:33 +03:00
pokamest d57e56de70 Setup container more debugging 2021-06-16 22:24:13 +03:00
pokamest e2f8f77adf Revert "Added threads suspend, Edited suspendWcmSvc() func for Windows. Based on old SuspendProcess func."
This reverts commit 999087337e.
2021-06-16 20:09:49 +03:00
pokamest db543b62ba Macos build fix 2021-06-14 03:48:46 -07:00
Sike 999087337e Added threads suspend, Edited suspendWcmSvc() func for Windows. Based on old SuspendProcess func. 2021-06-14 02:34:21 +06:00
pokamest 6788f0b7eb Wireguard deploy files 2021-06-12 12:02:46 +03:00
pokamest 2f6fb0d557 Wireguard protocol + refactoring 2021-06-12 11:59:36 +03:00
pokamest 8bdfe1741a Win Routes fix 2021-06-10 17:58:28 +03:00
pokamest 739781ece3 Saving files before refreshing line endings 2021-06-06 17:27:58 +03:00
pokamest 7e74b95976 Readme updated 2021-06-06 16:25:22 +03:00
pokamest 531695bd0b Windows x32 deploy files added 2021-06-06 16:18:01 +03:00
pokamest dd959e7b26 Custom routing fixes 2021-06-05 20:55:57 +03:00
pokamest c4235a60c8 Macos fixes 2021-06-05 01:18:28 -07:00
pokamest f75456060f build fix 2021-06-03 10:42:58 -07:00
pokamest 623aae3718 Macos build fix 2021-06-03 10:34:28 -07:00
pokamest 974832f7d9 Tiny fix 2021-06-03 20:27:46 +03:00
pokamest d13df65bfb Tiny fixes 2021-06-03 20:23:44 +03:00
pokamest 80ada3f241 Travis fix 2021-06-03 00:29:51 +03:00
pokamest aad3677d45 Travis fix 2021-06-02 22:34:29 +03:00
pokamest 8892d3c5d9 Travis fix 2021-06-02 21:35:44 +03:00
pokamest da08bef2f9 Travis fix 2021-06-02 20:46:59 +03:00
pokamest d79483e967 Travis fix 2021-06-02 20:25:00 +03:00
pokamest 906391f786 Travis fix 2021-06-02 19:24:50 +03:00
pokamest 48a4aa399b Travis fix 2021-06-02 19:05:26 +03:00
pokamest a8dd319a9d Travis fix 2021-06-02 18:54:39 +03:00
pokamest 815686cba6 Travis fix 2021-06-02 18:41:08 +03:00
pokamest 7232a14926 Travis fix 2021-06-02 17:56:01 +03:00
pokamest dd526959eb easyrsa fix 2021-06-02 17:51:04 +03:00
pokamest fe6f89c551 travis fix 2021-06-02 01:32:25 +03:00
pokamest 16c754e004 Disable openvpn log append 2021-06-02 00:54:47 +03:00
pokamest 8792a8673a gitignore fix 2021-06-02 00:53:44 +03:00
pokamest 9376df8703 deploy fixes 2021-06-02 00:49:42 +03:00
pokamest 435ee58d40 Macos fix: routes delete 2021-06-01 08:45:26 -07:00
pokamest 9dbe15a0e3 custom sitet pre release 2021-06-01 18:18:09 +03:00
pokamest 34b97bdc24 Macos fixes for route functions 2021-05-27 15:01:15 -07:00
pokamest 6c74f30d79 Custom sites reimplemented 2021-05-27 22:18:36 +03:00
pokamest 97e918ae72 ui fixes 2021-05-22 16:14:26 +03:00
pokamest d0c66a693b macos deploy script fixes 2021-05-21 05:33:40 -07:00
pokamest 0ea085cc02 - Crash fix if service not connected
- import fix
- disabled share button for readonly server
2021-05-20 15:59:58 +03:00
pokamest 7fd13faa59 cloak stop() fixed 2021-05-19 00:26:36 +03:00
pokamest d4c0e519d9 ui fixes 2021-05-19 00:15:40 +03:00
pokamest 4ba964db47 win7 support fixes
wizard added
2021-05-18 15:50:52 +03:00
pokamest 45e5ec76dd Windows 7 tap support improved 2021-05-14 23:30:13 +03:00
pokamest df27003998 win build fix 2021-05-14 23:29:09 +03:00
pokamest 9002568474 Macos cached config fix 2021-05-14 04:27:30 -07:00
pokamest 5c5411261a macos dns setup fixed 2021-05-13 08:23:56 -07:00
pokamest acf878c8dd Macos route add reimplemented using system call 2021-05-13 08:20:38 -07:00
pokamest 491a09b175 macos autostart fix 2021-05-12 13:07:22 -07:00
pokamest 51f7e6811e macos ui fix 2021-05-12 02:49:36 -07:00
pokamest eee6b8b10f main.cpp default font removed 2021-05-11 12:15:33 -07:00
pokamest dc4a1c6eca macos fix 2021-05-11 09:36:43 -07:00
pokamest 02810ff844 bug fixes 2021-05-11 17:04:04 +03:00
257 changed files with 12963 additions and 1421 deletions
+3 -1
View File
@@ -5,7 +5,9 @@ AmneziaVPN.dmg
AmneziaVPN.exe
AmneziaVPN_*.exe
deploy/build/*
winbuild.bat
deploy/build_32/*
deploy/build_64/*
winbuild*.bat
# Qt-es
/.qmake.cache
+75 -19
View File
@@ -10,18 +10,23 @@ jobs:
include:
- name: MacOS
os: osx
osx_image: xcode12.2
osx_image: xcode12.5
env:
- QT_VERSION=5.15.1
- QT_VERSION=5.15.2
- QIF_VERSION=4.1
- QT_BIN_DIR=$HOME/Qt/$QT_VERSION/clang_64/bin
- QIF_BIN_DIR=$QT_BIN_DIR/../../../Tools/QtInstallerFramework/$QIF_VERSION/bin
script:
- |
if [ ! -f $HOME/Qt/$QT_VERSION/clang_64/bin/qmake ]; then \
brew install p7zip && \
pip3 install aqtinstall requests py7zr && \
python3 -m pip install --upgrade pip && \
pip install -U aqtinstall requests py7zr && \
pip show aqtinstall && \
python3 -m aqt install --outputdir $HOME/Qt $QT_VERSION mac desktop clang_64 -m qtbase && \
python3 -m aqt tool --outputdir $HOME/Qt mac tools_ifw 4.0.1 qt.tools.ifw.40;
python3 -m aqt tool --outputdir $HOME/Qt mac tools_ifw $QIF_VERSION qt.tools.ifw.${QIF_VERSION/./};
fi
- bash deploy/build_macos.sh
@@ -35,40 +40,91 @@ jobs:
tags: true
branch: master
- name: Windows
- name: Windows_x64
os: windows
env:
- PATH=/c/Python39:/c/Python39/Scripts:$PATH
- QT_VERSION=5.14.2
- QIF_VERSION=4.1
- QT_BIN_DIR="c:\\Qt\\$QT_VERSION\\msvc2017_64\\bin"
- QIF_BIN_DIR="c:\\Qt\\Tools\\QtInstallerFramework\\${QIF_VERSION}\\bin"
- BUILD_ARCH=64
before_install:
- if [ ! -f /C/Qt/5.14.2/msvc2017/bin/qmake ]; then choco install python --version 3.9.1; fi
- if [ ! -f /C/Qt/$QT_VERSION/msvc2017_64/bin/qmake ]; then choco install python --version 3.9.1; fi
script:
- dir "C:\Program Files (x86)\Microsoft Visual Studio\2017\BuildTools\VC\Auxiliary\Build"
- dir "C:\Program Files (x86)\Microsoft Visual Studio\2017\BuildTools\Common7\Tools"
- |
if [ ! -f /C/Qt/5.14.2/msvc2017/bin/qmake ]; then \
pip3 install aqtinstall requests py7zr && \
python -m aqt install --outputdir /C/Qt 5.14.2 windows desktop win32_msvc2017 -m qtbase && \
python -m aqt tool --outputdir /C/Qt windows tools_ifw 4.0.1 qt.tools.ifw.40; \
if [ ! -f /C/Qt/$QT_VERSION/msvc2017_64/bin/qmake ]; then \
python -m pip install --upgrade pip && \
pip3 install -U aqtinstall requests py7zr && \
pip3 show aqtinstall && \
python -m aqt install --outputdir /C/Qt $QT_VERSION windows desktop win64_msvc2017_64 -m qtbase && \
python -m aqt tool --outputdir /C/Qt windows tools_ifw $QIF_VERSION qt.tools.ifw.${QIF_VERSION/./}; \
fi
- echo 'call "C:\Program Files (x86)\Microsoft Visual Studio\2017\BuildTools\Common7\Tools\VsDevCmd.bat"' > winbuild.bat
- echo -e "\r\n" >> winbuild.bat
- echo 'call "C:\Program Files (x86)\Microsoft Visual Studio\2017\BuildTools\VC\Auxiliary\Build\vcvarsamd64_x86.bat"' >> winbuild.bat
- echo -e "\r\n" >> winbuild.bat
- echo -e "set WIN_CERT_PW=$WIN_CERT_PW" >> winbuild.bat
- echo -e "\r\n" >> winbuild.bat
- echo -e "call deploy\\\build_windows.bat" >> winbuild.bat
- echo set BUILD_ARCH=$BUILD_ARCH > winbuild.bat
- echo set QT_BIN_DIR="$QT_BIN_DIR" >> winbuild.bat
- echo set QIF_BIN_DIR="$QIF_BIN_DIR" >> winbuild.bat
- echo call \""C:\\Program Files (x86)\\Microsoft Visual Studio\\2017\\BuildTools\\VC\\Auxiliary\\Build\\vcvars${BUILD_ARCH}.bat\"" >> winbuild.bat
- echo call \""C:\\Program Files (x86)\\Microsoft Visual Studio\\2017\\BuildTools\\Common7\\Tools\\VsDevCmd.bat\" -arch=amd64" >> winbuild.bat
- echo set WIN_CERT_PW=$WIN_CERT_PW >> winbuild.bat
- echo call deploy\\build_windows.bat >> winbuild.bat
- cmd //c winbuild.bat
deploy:
provider: releases
token: $GH_TOKEN
skip_cleanup: true
file:
- "AmneziaVPN.exe"
- "AmneziaVPN_x64.exe"
on:
tags: true
branch: master
- name: Windows_x32
os: windows
env:
- PATH=/c/Python39:/c/Python39/Scripts:$PATH
- QT_VERSION=5.14.2
- QIF_VERSION=4.1
- QT_BIN_DIR="c:\\Qt\\${QT_VERSION}\\msvc2017\\bin"
- QIF_BIN_DIR="c:\\Qt\\Tools\\QtInstallerFramework\\${QIF_VERSION}\\bin"
- BUILD_ARCH=32
before_install:
- if [ ! -f /C/Qt/$QT_VERSION/msvc2017/bin/qmake ]; then choco install python --version 3.9.1; fi
script:
- dir "C:\Program Files (x86)\Microsoft Visual Studio\2017\BuildTools\VC\Auxiliary\Build"
- dir "C:\Program Files (x86)\Microsoft Visual Studio\2017\BuildTools\Common7\Tools"
- |
if [ ! -f /C/Qt/$QT_VERSION/msvc2017/bin/qmake ]; then \
python -m pip install --upgrade pip && \
pip3 install -U aqtinstall requests py7zr && \
pip3 show aqtinstall && \
python -m aqt install --outputdir /C/Qt $QT_VERSION windows desktop win32_msvc2017 -m qtbase && \
python -m aqt tool --outputdir /C/Qt windows tools_ifw $QIF_VERSION qt.tools.ifw.${QIF_VERSION/./}; \
fi
- echo call \""C:\\Program Files (x86)\\Microsoft Visual Studio\\2017\\BuildTools\\Common7\\Tools\\VsDevCmd.bat\"" > winbuild.bat
- echo set BUILD_ARCH=$BUILD_ARCH >> winbuild.bat
- echo set QT_BIN_DIR="$QT_BIN_DIR" >> winbuild.bat
- echo set QIF_BIN_DIR="$QIF_BIN_DIR" >> winbuild.bat
- echo call \""C:\\Program Files (x86)\\Microsoft Visual Studio\\2017\\BuildTools\\VC\\Auxiliary\\Build\\vcvars${BUILD_ARCH}.bat\"" >> winbuild.bat
- echo set WIN_CERT_PW=$WIN_CERT_PW >> winbuild.bat
- echo call deploy\\build_windows.bat >> winbuild.bat
- cmd //c winbuild.bat
deploy:
provider: releases
token: $GH_TOKEN
skip_cleanup: true
file:
- "AmneziaVPN_x32.exe"
on:
tags: true
branch: master
+8 -2
View File
@@ -39,5 +39,11 @@ Look to the `build_macos.sh` and `build_windows.bat` scripts in `deploy` folder
GPL v.3
## Contacts
[https://t.me/amnezia_vpn](https://t.me/amnezia_vpn) - main support channel
[https://amnezia.org](https://amnezia.org) - our website
[https://t.me/amnezia_vpn_en](https://t.me/amnezia_vpn_en) - Telegram support channel (English)
[https://t.me/amnezia_vpn](https://t.me/amnezia_vpn) - Telegram support channel (Russian)
[https://signal.group/...](https://signal.group/#CjQKIB2gUf8QH_IXnOJMGQWMDjYz9cNfmRQipGWLFiIgc4MwEhAKBONrSiWHvoUFbbD0xwdh) - Signal channel
[https://amnezia.org](https://amnezia.org) - project website
## Donate
Bitcoin: bc1qn9rhsffuxwnhcuuu4qzrwp4upkrq94xnh8r26u
Buy coffee for AmneziaVPN : [https://ko-fi.com/amnezia_vpn](https://ko-fi.com/amnezia_vpn)
+8
View File
@@ -15,7 +15,9 @@ HEADERS += \
../ipc/ipc.h \
configurators/cloak_configurator.h \
configurators/shadowsocks_configurator.h \
configurators/ssh_configurator.h \
configurators/vpn_configurator.h \
configurators/wireguard_configurator.h \
core/defs.h \
core/errorstrings.h \
core/ipcclient.h \
@@ -29,11 +31,13 @@ HEADERS += \
protocols/openvpnovercloakprotocol.h \
protocols/protocols_defs.h \
protocols/shadowsocksvpnprotocol.h \
protocols/wireguardprotocol.h \
settings.h \
ui/Controls/SlidingStackedWidget.h \
ui/mainwindow.h \
ui/qautostart.h \
ui/server_widget.h \
ui/sites_model.h \
utils.h \
vpnconnection.h \
protocols/vpnprotocol.h \
@@ -42,7 +46,9 @@ HEADERS += \
SOURCES += \
configurators/cloak_configurator.cpp \
configurators/shadowsocks_configurator.cpp \
configurators/ssh_configurator.cpp \
configurators/vpn_configurator.cpp \
configurators/wireguard_configurator.cpp \
core/errorstrings.cpp \
core/ipcclient.cpp \
configurators/openvpn_configurator.cpp \
@@ -55,11 +61,13 @@ SOURCES += \
protocols/openvpnovercloakprotocol.cpp \
protocols/protocols_defs.cpp \
protocols/shadowsocksvpnprotocol.cpp \
protocols/wireguardprotocol.cpp \
settings.cpp \
ui/Controls/SlidingStackedWidget.cpp \
ui/mainwindow.cpp \
ui/qautostart.cpp \
ui/server_widget.cpp \
ui/sites_model.cpp \
utils.cpp \
vpnconnection.cpp \
protocols/vpnprotocol.cpp \
@@ -38,6 +38,7 @@ QString CloakConfigurator::genCloakConfig(const ServerCredentials &credentials,
// transfer params to protocol runner
config.insert(config_key::transport_proto, "$OPENVPN_TRANSPORT_PROTO");
config.insert(config_key::remote, credentials.hostName);
config.insert(config_key::port, "$CLOAK_SERVER_PORT");
QString textCfg = ServerController::replaceVars(QJsonDocument(config).toJson(),
ServerController::genVarsForScript(credentials, container, containerConfig));
+42 -36
View File
@@ -5,19 +5,17 @@
#include <QTemporaryDir>
#include <QDebug>
#include <QTemporaryFile>
#include <utils.h>
#include "core/server_defs.h"
#include "protocols/protocols_defs.h"
#include "core/scripts_registry.h"
#include "utils.h"
QString OpenVpnConfigurator::getEasyRsaShPath()
{
#ifdef Q_OS_WIN
// easyrsa sh path should looks like
// "/Program Files (x86)/AmneziaVPN/easyrsa/easyrsa"
QString easyRsaShPath = QDir::toNativeSeparators(QApplication::applicationDirPath()) + "\\easyrsa\\easyrsa";
easyRsaShPath = "\"" + easyRsaShPath + "\"";
qDebug().noquote() << "EasyRsa sh path" << easyRsaShPath;
return easyRsaShPath;
@@ -34,7 +32,7 @@ QProcessEnvironment OpenVpnConfigurator::prepareEnv()
#ifdef Q_OS_WIN
pathEnvVar.clear();
pathEnvVar.prepend(QDir::toNativeSeparators(QApplication::applicationDirPath()) + "\\cygwin;");
pathEnvVar.prepend(QDir::toNativeSeparators(QApplication::applicationDirPath()) + "\\openvpn\\i386;");
pathEnvVar.prepend(QDir::toNativeSeparators(QApplication::applicationDirPath()) + "\\openvpn;");
#else
pathEnvVar.prepend(QDir::toNativeSeparators(QApplication::applicationDirPath()) + "/Contents/MacOS");
#endif
@@ -52,7 +50,7 @@ ErrorCode OpenVpnConfigurator::initPKI(const QString &path)
#ifdef Q_OS_WIN
p.setProcessEnvironment(prepareEnv());
p.setProgram("cmd.exe");
p.setNativeArguments(QString("/C \"ash.exe %1\"").arg(getEasyRsaShPath() + " init-pki"));
p.setNativeArguments(QString("/C \"ash.exe \"%1\" %2\"").arg(getEasyRsaShPath()).arg("init-pki"));
qDebug().noquote() << "EasyRsa tmp path" << path;
qDebug().noquote() << "EasyRsa args" << p.nativeArguments();
#else
@@ -81,7 +79,10 @@ ErrorCode OpenVpnConfigurator::genReq(const QString &path, const QString &client
#ifdef Q_OS_WIN
p.setProcessEnvironment(prepareEnv());
p.setProgram("cmd.exe");
p.setNativeArguments(QString("/C \"ash.exe %1\"").arg(getEasyRsaShPath() + " gen-req " + clientId + " nopass"));
p.setNativeArguments(QString("/C \"ash.exe \"%1\" %2 %3 %4\"")
.arg(getEasyRsaShPath())
.arg("gen-req").arg(clientId).arg("nopass"));
qDebug().noquote() << "EasyRsa args" << p.nativeArguments();
#else
p.setArguments(QStringList() << "gen-req" << clientId << "nopass");
@@ -203,14 +204,21 @@ QString OpenVpnConfigurator::genOpenVpnConfig(const ServerCredentials &credentia
config.replace("$OPENVPN_CA_CERT", connData.caCert);
config.replace("$OPENVPN_CLIENT_CERT", connData.clientCert);
config.replace("$OPENVPN_PRIV_KEY", connData.privKey);
config.replace("$OPENVPN_TA_KEY", connData.taKey);
if (config.contains("$OPENVPN_TA_KEY")) {
config.replace("$OPENVPN_TA_KEY", connData.taKey);
}
else {
config.replace("<tls-auth>", "");
config.replace("</tls-auth>", "");
}
#ifdef Q_OS_MAC
config.replace("block-outside-dns", "");
#endif
//qDebug().noquote() << config;
return processConfigWithLocalSettings(config);
return config;
}
QString OpenVpnConfigurator::processConfigWithLocalSettings(QString config)
@@ -219,45 +227,43 @@ QString OpenVpnConfigurator::processConfigWithLocalSettings(QString config)
config.replace("$PRIMARY_DNS", m_settings().primaryDns());
config.replace("$SECONDARY_DNS", m_settings().secondaryDns());
if (m_settings().customRouting()) {
if (m_settings().routeMode() != Settings::VpnAllSites) {
config.replace("redirect-gateway def1 bypass-dhcp", "");
}
else {
if(!config.contains("redirect-gateway def1 bypass-dhcp")) {
config.append("redirect-gateway def1 bypass-dhcp\n");
}
}
#ifdef Q_OS_MAC
config.replace("block-outside-dns", "");
QString dnsConf = QString(
"\nscript-security 2\n"
"up %1/update-resolv-conf.sh\n"
"down %1/update-resolv-conf.sh\n").
arg(qApp->applicationDirPath());
config.append(dnsConf);
#endif
return config;
}
QString OpenVpnConfigurator::convertOpenSShKey(const QString &key)
QString OpenVpnConfigurator::processConfigWithExportSettings(QString config)
{
QProcess p;
p.setProcessChannelMode(QProcess::MergedChannels);
config.replace("$PRIMARY_DNS", m_settings().primaryDns());
config.replace("$SECONDARY_DNS", m_settings().secondaryDns());
QTemporaryFile tmp;
#ifdef QT_DEBUG
tmp.setAutoRemove(false);
#endif
tmp.open();
tmp.write(key.toUtf8());
tmp.close();
if(!config.contains("redirect-gateway def1 bypass-dhcp")) {
config.append("redirect-gateway def1 bypass-dhcp\n");
}
// ssh-keygen -p -P "" -N "" -m pem -f id_ssh
#ifdef Q_OS_WIN
p.setProcessEnvironment(prepareEnv());
p.setProgram("cmd.exe");
p.setNativeArguments(QString("/C \"ssh-keygen.exe -p -P \"\" -N \"\" -m pem -f \"%1\"\"").arg(tmp.fileName()));
#else
p.setProgram("ssh-keygen");
p.setArguments(QStringList() << "-p" << "-P" << "" << "-N" << "" << "-m" << "pem" << "-f" << tmp.fileName());
#ifdef Q_OS_MAC
config.replace("block-outside-dns", "");
#endif
p.start();
p.waitForFinished();
qDebug().noquote() << "OpenVpnConfigurator::convertOpenSShKey" << p.exitCode() << p.exitStatus() << p.readAll();
tmp.open();
return tmp.readAll();
return config;
}
ErrorCode OpenVpnConfigurator::signCert(DockerContainer container,
+1 -2
View File
@@ -26,8 +26,7 @@ public:
const QJsonObject &containerConfig, ErrorCode *errorCode = nullptr);
static QString processConfigWithLocalSettings(QString config);
static QString convertOpenSShKey(const QString &key);
static QString processConfigWithExportSettings(QString config);
static ErrorCode signCert(DockerContainer container,
const ServerCredentials &credentials, QString clientId);
@@ -32,6 +32,6 @@ QString ShadowSocksConfigurator::genShadowSocksConfig(const ServerCredentials &c
QString textCfg = ServerController::replaceVars(QJsonDocument(config).toJson(),
ServerController::genVarsForScript(credentials, container, containerConfig));
qDebug().noquote() << textCfg;
//qDebug().noquote() << textCfg;
return textCfg;
}
+95
View File
@@ -0,0 +1,95 @@
#include "ssh_configurator.h"
#include <QApplication>
#include <QProcess>
#include <QString>
#include <QTemporaryDir>
#include <QDebug>
#include <QTemporaryFile>
#include <QThread>
#include <QObject>
#include <QTextEdit>
#include <QPlainTextEdit>
#include <qtimer.h>
#include "core/server_defs.h"
#include "utils.h"
using namespace QSsh;
QString SshConfigurator::convertOpenSShKey(const QString &key)
{
QProcess p;
p.setProcessChannelMode(QProcess::MergedChannels);
QTemporaryFile tmp;
#ifdef QT_DEBUG
tmp.setAutoRemove(false);
#endif
tmp.open();
tmp.write(key.toUtf8());
tmp.close();
// ssh-keygen -p -P "" -N "" -m pem -f id_ssh
#ifdef Q_OS_WIN
p.setProcessEnvironment(prepareEnv());
p.setProgram("cmd.exe");
p.setNativeArguments(QString("/C \"ssh-keygen.exe -p -P \"\" -N \"\" -m pem -f \"%1\"\"").arg(tmp.fileName()));
#else
p.setProgram("ssh-keygen");
p.setArguments(QStringList() << "-p" << "-P" << "" << "-N" << "" << "-m" << "pem" << "-f" << tmp.fileName());
#endif
p.start();
p.waitForFinished();
qDebug().noquote() << "OpenVpnConfigurator::convertOpenSShKey" << p.exitCode() << p.exitStatus() << p.readAll();
tmp.open();
return tmp.readAll();
}
void SshConfigurator::openSshTerminal(const ServerCredentials &credentials)
{
QProcess *p = new QProcess();
p->setReadChannelMode(QProcess::SeparateChannels);
#ifdef Q_OS_WIN
p->setProcessEnvironment(prepareEnv());
p->setProgram(qApp->applicationDirPath() + "\\cygwin\\putty.exe");
if (credentials.password.contains("PRIVATE KEY")) {
// todo: connect by key
// p->setNativeArguments(QString("%1@%2")
// .arg(credentials.userName).arg(credentials.hostName).arg(credentials.password));
}
else {
p->setNativeArguments(QString("%1@%2 -pw %3")
.arg(credentials.userName).arg(credentials.hostName).arg(credentials.password));
}
#else
p->setProgram("/bin/bash");
#endif
p->startDetached();
}
QProcessEnvironment SshConfigurator::prepareEnv()
{
QProcessEnvironment env = QProcessEnvironment::systemEnvironment();
QString pathEnvVar = env.value("PATH");
#ifdef Q_OS_WIN
pathEnvVar.clear();
pathEnvVar.prepend(QDir::toNativeSeparators(QApplication::applicationDirPath()) + "\\cygwin;");
pathEnvVar.prepend(QDir::toNativeSeparators(QApplication::applicationDirPath()) + "\\openvpn;");
#else
pathEnvVar.prepend(QDir::toNativeSeparators(QApplication::applicationDirPath()) + "/Contents/MacOS");
#endif
env.insert("PATH", pathEnvVar);
//qDebug().noquote() << "ENV PATH" << pathEnvVar;
return env;
}
+20
View File
@@ -0,0 +1,20 @@
#ifndef SSH_CONFIGURATOR_H
#define SSH_CONFIGURATOR_H
#include <QObject>
#include <QProcessEnvironment>
#include "core/defs.h"
#include "settings.h"
#include "core/servercontroller.h"
class SshConfigurator
{
public:
static QProcessEnvironment prepareEnv();
static QString convertOpenSShKey(const QString &key);
static void openSshTerminal(const ServerCredentials &credentials);
};
#endif // SSH_CONFIGURATOR_H
@@ -0,0 +1,178 @@
#include "wireguard_configurator.h"
#include <QApplication>
#include <QProcess>
#include <QString>
#include <QTemporaryDir>
#include <QDebug>
#include <QTemporaryFile>
#include "sftpdefs.h"
#include "core/server_defs.h"
#include "protocols/protocols_defs.h"
#include "core/scripts_registry.h"
#include "utils.h"
QProcessEnvironment WireguardConfigurator::prepareEnv()
{
QProcessEnvironment env = QProcessEnvironment::systemEnvironment();
QString pathEnvVar = env.value("PATH");
#ifdef Q_OS_WIN
pathEnvVar.clear();
pathEnvVar.prepend(QDir::toNativeSeparators(QApplication::applicationDirPath()) + "\\wireguard;");
#else
pathEnvVar.prepend(QDir::toNativeSeparators(QApplication::applicationDirPath()) + "/Contents/MacOS");
#endif
env.insert("PATH", pathEnvVar);
qDebug().noquote() << "ENV PATH" << pathEnvVar;
return env;
}
WireguardConfigurator::ConnectionData WireguardConfigurator::genClientKeys()
{
ConnectionData connData;
QString program;
#ifdef Q_OS_WIN
program = QDir::toNativeSeparators(QApplication::applicationDirPath()) + "\\wireguard\\wg.exe";
#else
program = QDir::toNativeSeparators(QApplication::applicationDirPath()) + "/Contents/MacOS/wg";
#endif
// Priv
{
QProcess p;
p.setProcessEnvironment(prepareEnv());
p.setProcessChannelMode(QProcess::MergedChannels);
p.setProgram(program);
p.setArguments(QStringList() << "genkey");
p.start();
p.waitForFinished();
connData.clientPrivKey = QString(p.readAll());
connData.clientPrivKey.replace("\r", "");
connData.clientPrivKey.replace("\n", "");
}
// Pub
{
QProcess p;
p.setProcessEnvironment(prepareEnv());
p.setProcessChannelMode(QProcess::MergedChannels);
p.setProgram(program);
p.setArguments(QStringList() << "pubkey");
p.start();
p.write(connData.clientPrivKey.toUtf8());
p.closeWriteChannel();
p.waitForFinished();
connData.clientPubKey = QString(p.readAll());
connData.clientPubKey.replace("\r", "");
connData.clientPubKey.replace("\n", "");
}
return connData;
}
WireguardConfigurator::ConnectionData WireguardConfigurator::prepareWireguardConfig(const ServerCredentials &credentials,
DockerContainer container, ErrorCode *errorCode)
{
WireguardConfigurator::ConnectionData connData = WireguardConfigurator::genClientKeys();
connData.host = credentials.hostName;
if (connData.clientPrivKey.isEmpty() || connData.clientPubKey.isEmpty()) {
if (errorCode) *errorCode = ErrorCode::EasyRsaExecutableMissing;
return connData;
}
ErrorCode e = ErrorCode::NoError;
connData.serverPubKey = ServerController::getTextFileFromContainer(container, credentials, amnezia::protocols::wireguard::serverPublicKeyPath, &e);
connData.serverPubKey.replace("\n", "");
if (e) {
if (errorCode) *errorCode = e;
return connData;
}
connData.pskKey = ServerController::getTextFileFromContainer(container, credentials, amnezia::protocols::wireguard::serverPskKeyPath, &e);
connData.pskKey.replace("\n", "");
if (e) {
if (errorCode) *errorCode = e;
return connData;
}
QString configPart = QString(
"[Peer]\n"
"PublicKey = %1\n"
"PresharedKey = %2\n"
"AllowedIPs = $WIREGUARD_SUBNET_IP/$WIREGUARD_SUBNET_CIDR\n\n").
arg(connData.clientPubKey).
arg(connData.pskKey);
configPart = ServerController::replaceVars(configPart, ServerController::genVarsForScript(credentials, container));
qDebug().noquote() << "Adding wg conf part to server" << configPart;
e = ServerController::uploadTextFileToContainer(container, credentials, configPart,
protocols::wireguard::serverConfigPath, QSsh::SftpOverwriteMode::SftpAppendToExisting);
if (e) {
if (errorCode) *errorCode = e;
return connData;
}
e = ServerController::runScript(ServerController::sshParams(credentials),
ServerController::replaceVars("sudo docker exec -i $CONTAINER_NAME bash -c 'wg syncconf wg0 <(wg-quick strip /opt/amnezia/wireguard/wg0.conf)'",
ServerController::genVarsForScript(credentials, container)));
return connData;
}
Settings &WireguardConfigurator::m_settings()
{
static Settings s;
return s;
}
QString WireguardConfigurator::genWireguardConfig(const ServerCredentials &credentials,
DockerContainer container, const QJsonObject &containerConfig, ErrorCode *errorCode)
{
QString config = ServerController::replaceVars(amnezia::scriptData(ProtocolScriptType::wireguard_template, container),
ServerController::genVarsForScript(credentials, container, containerConfig));
ConnectionData connData = prepareWireguardConfig(credentials, container, errorCode);
if (errorCode && *errorCode) {
return "";
}
config.replace("$WIREGUARD_CLIENT_PRIVATE_KEY", connData.clientPrivKey);
config.replace("$WIREGUARD_SERVER_PUBLIC_KEY", connData.serverPubKey);
config.replace("$WIREGUARD_PSK", connData.pskKey);
qDebug().noquote() << config;
return config;
}
QString WireguardConfigurator::processConfigWithLocalSettings(QString config)
{
// TODO replace DNS if it already set
config.replace("$PRIMARY_DNS", m_settings().primaryDns());
config.replace("$SECONDARY_DNS", m_settings().secondaryDns());
return config;
}
QString WireguardConfigurator::processConfigWithExportSettings(QString config)
{
config.replace("$PRIMARY_DNS", m_settings().primaryDns());
config.replace("$SECONDARY_DNS", m_settings().secondaryDns());
return config;
}
@@ -0,0 +1,41 @@
#ifndef WIREGUARD_CONFIGURATOR_H
#define WIREGUARD_CONFIGURATOR_H
#include <QObject>
#include <QProcessEnvironment>
#include "core/defs.h"
#include "settings.h"
#include "core/servercontroller.h"
class WireguardConfigurator
{
public:
struct ConnectionData {
QString clientPrivKey; // client private key
QString clientPubKey; // client public key
QString serverPubKey; // tls-auth key
QString pskKey; // preshared key
QString host; // host ip
};
static QString genWireguardConfig(const ServerCredentials &credentials, DockerContainer container,
const QJsonObject &containerConfig, ErrorCode *errorCode = nullptr);
static QString processConfigWithLocalSettings(QString config);
static QString processConfigWithExportSettings(QString config);
private:
static QProcessEnvironment prepareEnv();
static ConnectionData prepareWireguardConfig(const ServerCredentials &credentials,
DockerContainer container, ErrorCode *errorCode = nullptr);
static ConnectionData genClientKeys();
static Settings &m_settings();
};
#endif // WIREGUARD_CONFIGURATOR_H
+5 -1
View File
@@ -13,7 +13,7 @@ struct ServerCredentials
QString password;
int port = 22;
bool isValid() { return !hostName.isEmpty() && !userName.isEmpty() && !password.isEmpty() && port > 0; }
bool isValid() const { return !hostName.isEmpty() && !userName.isEmpty() && !password.isEmpty() && port > 0; }
};
enum ErrorCode
@@ -44,6 +44,7 @@ enum ErrorCode
OpenVpnConfigMissing,
OpenVpnManagementServerError,
EasyRsaError,
ConfigMissing,
// Distro errors
OpenVpnExecutableMissing,
@@ -51,10 +52,12 @@ enum ErrorCode
ShadowSocksExecutableMissing,
CloakExecutableMissing,
AmneziaServiceConnectionFailed,
ExecutableMissing,
// VPN errors
OpenVpnAdaptersInUseError,
OpenVpnUnknownError,
OpenVpnTapAdapterError,
// 3rd party utils errors
OpenVpnExecutableCrashed,
@@ -68,6 +71,7 @@ const char key_openvpn_config_data[] = "openvpn_config_data";
const char key_openvpn_config_path[] = "openvpn_config_path";
const char key_shadowsocks_config_data[] = "shadowsocks_config_data";
const char key_cloak_config_data[] = "cloak_config_data";
const char key_wireguard_config_data[] = "wireguard_config_data";
}
+1
View File
@@ -42,6 +42,7 @@ QString errorString(ErrorCode code){
// VPN errors
case (OpenVpnAdaptersInUseError): return QObject::tr("Can't connect: another VPN connection is active");
case (OpenVpnTapAdapterError): return QObject::tr("Can't setup OpenVPN TAP network adapter");
case(InternalError):
default:
+1 -1
View File
@@ -48,7 +48,7 @@ QSharedPointer<IpcProcessInterfaceReplica> IpcClient::CreatePrivilegedProcess()
qWarning() << "IpcProcessInterfaceReplica replica is not connected!";
}
connect(pd->ipcProcess.data(), &IpcProcessInterfaceReplica::destroyed, pd->ipcProcess.data(), [pd](){
QObject::connect(pd->ipcProcess.data(), &IpcProcessInterfaceReplica::destroyed, pd->ipcProcess.data(), [pd](){
pd->replicaNode->deleteLater();
});
}
+1
View File
@@ -36,6 +36,7 @@ QString amnezia::scriptName(ProtocolScriptType type)
case ProtocolScriptType::configure_container: return QLatin1String("configure_container.sh");
case ProtocolScriptType::container_startup: return QLatin1String("start.sh");
case ProtocolScriptType::openvpn_template: return QLatin1String("template.ovpn");
case ProtocolScriptType::wireguard_template: return QLatin1String("template.conf");
}
}
+2 -1
View File
@@ -23,7 +23,8 @@ enum ProtocolScriptType {
run_container,
configure_container,
container_startup,
openvpn_template
openvpn_template,
wireguard_template
};
+84 -122
View File
@@ -120,7 +120,8 @@ ErrorCode ServerController::runScript(const SshConnectionParameters &sshParams,
}
ErrorCode ServerController::uploadTextFileToContainer(DockerContainer container,
const ServerCredentials &credentials, const QString &file, const QString &path)
const ServerCredentials &credentials, const QString &file, const QString &path,
QSsh::SftpOverwriteMode overwriteMode)
{
ErrorCode e = ErrorCode::NoError;
QString tmpFileName = QString("/tmp/%1.tmp").arg(Utils::getRandomString(16));
@@ -132,11 +133,29 @@ ErrorCode ServerController::uploadTextFileToContainer(DockerContainer container,
stdOut += data + "\n";
};
e = runScript(sshParams(credentials),
replaceVars(QString("sudo docker cp %1 $CONTAINER_NAME:/%2").arg(tmpFileName).arg(path),
genVarsForScript(credentials, container)), cbReadStd, cbReadStd);
if (overwriteMode == QSsh::SftpOverwriteMode::SftpOverwriteExisting) {
e = runScript(sshParams(credentials),
replaceVars(QString("sudo docker cp %1 $CONTAINER_NAME:/%2").arg(tmpFileName).arg(path),
genVarsForScript(credentials, container)), cbReadStd, cbReadStd);
if (e) return e;
}
else if (overwriteMode == QSsh::SftpOverwriteMode::SftpAppendToExisting) {
e = runScript(sshParams(credentials),
replaceVars(QString("sudo docker cp %1 $CONTAINER_NAME:/%2").arg(tmpFileName).arg(tmpFileName),
genVarsForScript(credentials, container)), cbReadStd, cbReadStd);
if (e) return e;
e = runScript(sshParams(credentials),
replaceVars(QString("sudo docker exec -i $CONTAINER_NAME sh -c \"cat %1 >> %2\"").arg(tmpFileName).arg(path),
genVarsForScript(credentials, container)), cbReadStd, cbReadStd);
if (e) return e;
}
else return ErrorCode::NotImplementedError;
if (e) return e;
if (stdOut.contains("Error: No such container:")) {
return ErrorCode::ServerContainerMissingError;
}
@@ -199,15 +218,16 @@ QString ServerController::getTextFileFromContainer(DockerContainer container,
if (errorCode) *errorCode = fromSshProcessExitStatus(exitStatus);
}
if (errorCode) *errorCode = ErrorCode::NoError;
return proc->readAllStandardOutput();
}
ErrorCode ServerController::checkOpenVpnServer(DockerContainer container, const ServerCredentials &credentials)
{
QString caCert = ServerController::getTextFileFromContainer(container,
credentials, amnezia::protocols::openvpn::caCertPath);
credentials, protocols::openvpn::caCertPath);
QString taKey = ServerController::getTextFileFromContainer(container,
credentials, amnezia::protocols::openvpn::taKeyPath);
credentials, protocols::openvpn::taKeyPath);
if (!caCert.isEmpty() && !taKey.isEmpty()) {
return ErrorCode::NoError;
@@ -217,7 +237,8 @@ ErrorCode ServerController::checkOpenVpnServer(DockerContainer container, const
}
}
ErrorCode ServerController::uploadFileToHost(const ServerCredentials &credentials, const QByteArray &data, const QString &remotePath)
ErrorCode ServerController::uploadFileToHost(const ServerCredentials &credentials, const QByteArray &data, const QString &remotePath,
QSsh::SftpOverwriteMode overwriteMode)
{
SshConnection *client = connectToHost(sshParams(credentials));
if (client->state() != SshConnection::State::Connected) {
@@ -343,46 +364,33 @@ ErrorCode ServerController::removeContainer(const ServerCredentials &credentials
ErrorCode ServerController::setupContainer(const ServerCredentials &credentials, DockerContainer container, const QJsonObject &config)
{
qDebug().noquote() << "ServerController::setupContainer" << containerToString(container);
qDebug().noquote() << QJsonDocument(config).toJson();
//qDebug().noquote() << QJsonDocument(config).toJson();
ErrorCode e = ErrorCode::NoError;
// e = runScript(sshParams(credentials),
// replaceVars(amnezia::scriptData(SharedScriptType::install_docker),
// genVarsForScript(credentials)));
// if (e) return e;
e = installDockerWorker(credentials, container);
if (e) return e;
qDebug().noquote() << "ServerController::setupContainer installDockerWorker finished";
e = prepareHostWorker(credentials, container, config);
if (e) return e;
qDebug().noquote() << "ServerController::setupContainer prepareHostWorker finished";
removeContainer(credentials, container);
qDebug().noquote() << "ServerController::setupContainer removeContainer finished";
e = buildContainerWorker(credentials, container, config);
if (e) return e;
qDebug().noquote() << "ServerController::setupContainer buildContainerWorker finished";
e = runContainerWorker(credentials, container, config);
if (e) return e;
qDebug().noquote() << "ServerController::setupContainer runContainerWorker finished";
e = configureContainerWorker(credentials, container, config);
if (e) return e;
qDebug().noquote() << "ServerController::setupContainer configureContainerWorker finished";
return startupContainerWorker(credentials, container, config);
// if (container == DockerContainer::OpenVpn) {
// return setupOpenVpnServer(credentials, config);
// }
// else if (container == DockerContainer::OpenVpnOverShadowSocks) {
// return setupShadowSocksServer(credentials, config);
// }
// else if (container == DockerContainer::OpenVpnOverCloak) {
// return setupOpenVpnOverCloakServer(credentials, config);
// }
// return ErrorCode::NoError;
}
ErrorCode ServerController::updateContainer(const ServerCredentials &credentials, DockerContainer container,
@@ -438,33 +446,6 @@ bool ServerController::isReinstallContainerRequred(DockerContainer container, co
return false;
}
//ErrorCode ServerController::setupOpenVpnServer(const ServerCredentials &credentials, const QJsonObject &config)
//{
// return ErrorCode::NotImplementedError;
//}
//ErrorCode ServerController::setupOpenVpnOverCloakServer(const ServerCredentials &credentials, const QJsonObject &config)
//{
// ErrorCode e = ErrorCode::NoError;
// DockerContainer container = DockerContainer::OpenVpnOverCloak;
// e = prepareHostWorker(credentials, container, config);
// if (e) return e;
// removeContainer(credentials, container);
// e = buildContainerWorker(credentials, container, config);
// if (e) return e;
// e = runContainerWorker(credentials, container, config);
// if (e) return e;
// e = configureContainerWorker(credentials, container, config);
// if (e) return e;
// return startupContainerWorker(credentials, container, config);
//}
ErrorCode ServerController::installDockerWorker(const ServerCredentials &credentials, DockerContainer container)
{
QString stdOut;
@@ -515,9 +496,23 @@ ErrorCode ServerController::buildContainerWorker(const ServerCredentials &creden
ErrorCode ServerController::runContainerWorker(const ServerCredentials &credentials, DockerContainer container, const QJsonObject &config)
{
return runScript(sshParams(credentials),
QString stdOut;
auto cbReadStdOut = [&](const QString &data, QSharedPointer<QSsh::SshRemoteProcess> proc) {
stdOut += data + "\n";
};
auto cbReadStdErr = [&](const QString &data, QSharedPointer<QSsh::SshRemoteProcess> proc) {
stdOut += data + "\n";
};
ErrorCode e = runScript(sshParams(credentials),
replaceVars(amnezia::scriptData(ProtocolScriptType::run_container, container),
genVarsForScript(credentials, container, config)));
genVarsForScript(credentials, container, config)),
cbReadStdOut, cbReadStdErr);
if (stdOut.contains("address already in use")) return ErrorCode::ServerPortAlreadyAllocatedError;
if (stdOut.contains("is already in use by container")) return ErrorCode::ServerPortAlreadyAllocatedError;
return e;
}
ErrorCode ServerController::configureContainerWorker(const ServerCredentials &credentials, DockerContainer container, const QJsonObject &config)
@@ -540,62 +535,12 @@ ErrorCode ServerController::startupContainerWorker(const ServerCredentials &cred
genVarsForScript(credentials, container, config)));
}
//ErrorCode ServerController::setupShadowSocksServer(const ServerCredentials &credentials, const QJsonObject &config)
//{
// return ErrorCode::NotImplementedError;
//// // Setup openvpn part
//// QString scriptData;
//// QString scriptFileName = ":/server_scripts/setup_shadowsocks_server.sh";
//// QFile file(scriptFileName);
//// if (! file.open(QIODevice::ReadOnly)) return ErrorCode::InternalError;
//// scriptData = file.readAll();
//// if (scriptData.isEmpty()) return ErrorCode::InternalError;
//// QString stdOut;
//// auto cbReadStdOut = [&](const QString &data, QSharedPointer<QSsh::SshRemoteProcess> proc) {
//// stdOut += data + "\n";
//// if (data.contains("Automatically restart Docker daemon?")) {
//// proc->write("yes\n");
//// }
//// };
//// auto cbReadStdErr = [&](const QString &data, QSharedPointer<QSsh::SshRemoteProcess> proc) {
//// stdOut += data + "\n";
//// };
//// ErrorCode e = runScript(genVarsForScript(credentials, DockerContainer::ShadowSocks), sshParams(credentials), scriptData, cbReadStdOut, cbReadStdErr);
//// if (e) return e;
//// // Create ss config
//// QJsonObject ssConfig;
//// ssConfig.insert("server", "0.0.0.0");
//// ssConfig.insert("server_port", amnezia::protocols::shadowsocks::ssRemotePort());
//// ssConfig.insert("local_port", amnezia::protocols::shadowsocks::ssContainerPort());
//// ssConfig.insert("password", QString(QCryptographicHash::hash(credentials.password.toUtf8(), QCryptographicHash::Sha256).toHex()));
//// ssConfig.insert("timeout", 60);
//// ssConfig.insert("method", amnezia::protocols::shadowsocks::ssEncryption());
//// QString configData = QJsonDocument(ssConfig).toJson();
//// QString sSConfigPath = "/opt/amneziavpn_data/ssConfig.json";
//// configData.replace("\"", "\\\"");
//// //qDebug().noquote() << configData;
//// uploadTextFileToContainer(DockerContainer::ShadowSocks, credentials, configData, sSConfigPath);
//// // Start ss
//// QString script = QString("sudo docker exec -d %1 sh -c \"ss-server -c %2\"").
//// arg(amnezia::containerToString(DockerContainer::ShadowSocks)).arg(sSConfigPath);
//// e = runScript(genVarsForScript(credentials, DockerContainer::ShadowSocks), sshParams(credentials), script);
// // return e;
//}
ServerController::Vars ServerController::genVarsForScript(const ServerCredentials &credentials, DockerContainer container, const QJsonObject &config)
{
const QJsonObject &openvpnConfig = config.value(config_key::openvpn).toObject();
const QJsonObject &cloakConfig = config.value(config_key::cloak).toObject();
const QJsonObject &ssConfig = config.value(config_key::shadowsocks).toObject();
const QJsonObject &wireguarConfig = config.value(config_key::wireguard).toObject();
//
Vars vars;
@@ -603,30 +548,46 @@ ServerController::Vars ServerController::genVarsForScript(const ServerCredential
vars.append({{"$REMOTE_HOST", credentials.hostName}});
// OpenVPN vars
vars.append({{"$VPN_SUBNET_IP", openvpnConfig.value(config_key::subnet_address).toString(amnezia::protocols::vpnDefaultSubnetAddress) }});
vars.append({{"$VPN_SUBNET_MASK_VAL", openvpnConfig.value(config_key::subnet_mask_val).toString(amnezia::protocols::vpnDefaultSubnetMaskVal) }});
vars.append({{"$VPN_SUBNET_MASK", openvpnConfig.value(config_key::subnet_mask).toString(amnezia::protocols::vpnDefaultSubnetMask) }});
vars.append({{"$OPENVPN_SUBNET_IP", openvpnConfig.value(config_key::subnet_address).toString(protocols::openvpn::defaultSubnetAddress) }});
vars.append({{"$OPENVPN_SUBNET_CIDR", openvpnConfig.value(config_key::subnet_cidr).toString(protocols::openvpn::defaultSubnetCidr) }});
vars.append({{"$OPENVPN_SUBNET_MASK", openvpnConfig.value(config_key::subnet_mask).toString(protocols::openvpn::defaultSubnetMask) }});
vars.append({{"$OPENVPN_PORT", openvpnConfig.value(config_key::port).toString(amnezia::protocols::openvpn::defaultPort) }});
vars.append({{"$OPENVPN_TRANSPORT_PROTO", openvpnConfig.value(config_key::transport_proto).toString(amnezia::protocols::openvpn::defaultTransportProto) }});
vars.append({{"$OPENVPN_PORT", openvpnConfig.value(config_key::port).toString(protocols::openvpn::defaultPort) }});
vars.append({{"$OPENVPN_TRANSPORT_PROTO", openvpnConfig.value(config_key::transport_proto).toString(protocols::openvpn::defaultTransportProto) }});
bool isNcpDisabled = openvpnConfig.value(config_key::ncp_disable).toBool(amnezia::protocols::openvpn::defaultNcpDisable);
bool isNcpDisabled = openvpnConfig.value(config_key::ncp_disable).toBool(protocols::openvpn::defaultNcpDisable);
vars.append({{"$OPENVPN_NCP_DISABLE", isNcpDisabled ? protocols::openvpn::ncpDisableString : "" }});
vars.append({{"$OPENVPN_CIPHER", openvpnConfig.value(config_key::cipher).toString(amnezia::protocols::openvpn::defaultCipher) }});
vars.append({{"$OPENVPN_HASH", openvpnConfig.value(config_key::hash).toString(amnezia::protocols::openvpn::defaultHash) }});
vars.append({{"$OPENVPN_CIPHER", openvpnConfig.value(config_key::cipher).toString(protocols::openvpn::defaultCipher) }});
vars.append({{"$OPENVPN_HASH", openvpnConfig.value(config_key::hash).toString(protocols::openvpn::defaultHash) }});
bool isTlsAuth = openvpnConfig.value(config_key::tls_auth).toBool(protocols::openvpn::defaultTlsAuth);
vars.append({{"$OPENVPN_TLS_AUTH", isTlsAuth ? protocols::openvpn::tlsAuthString : "" }});
if (!isTlsAuth) {
// erase $OPENVPN_TA_KEY, so it will not set in OpenVpnConfigurator::genOpenVpnConfig
vars.append({{"$OPENVPN_TA_KEY", "" }});
}
// ShadowSocks vars
vars.append({{"$SHADOWSOCKS_SERVER_PORT", ssConfig.value(config_key::port).toString(amnezia::protocols::shadowsocks::defaultPort) }});
vars.append({{"$SHADOWSOCKS_LOCAL_PORT", ssConfig.value(config_key::local_port).toString(amnezia::protocols::shadowsocks::defaultLocalProxyPort) }});
vars.append({{"$SHADOWSOCKS_CIPHER", ssConfig.value(config_key::cipher).toString(amnezia::protocols::shadowsocks::defaultCipher) }});
vars.append({{"$SHADOWSOCKS_SERVER_PORT", ssConfig.value(config_key::port).toString(protocols::shadowsocks::defaultPort) }});
vars.append({{"$SHADOWSOCKS_LOCAL_PORT", ssConfig.value(config_key::local_port).toString(protocols::shadowsocks::defaultLocalProxyPort) }});
vars.append({{"$SHADOWSOCKS_CIPHER", ssConfig.value(config_key::cipher).toString(protocols::shadowsocks::defaultCipher) }});
vars.append({{"$CONTAINER_NAME", amnezia::containerToString(container)}});
vars.append({{"$DOCKERFILE_FOLDER", "/opt/amnezia/" + amnezia::containerToString(container)}});
// Cloak vars
vars.append({{"$CLOAK_SERVER_PORT", config.value(config_key::port).toString(protocols::cloak::defaultPort) }});
vars.append({{"$CLOAK_SERVER_PORT", cloakConfig.value(config_key::port).toString(protocols::cloak::defaultPort) }});
vars.append({{"$FAKE_WEB_SITE_ADDRESS", cloakConfig.value(config_key::site).toString(protocols::cloak::defaultRedirSite) }});
// Wireguard vars
vars.append({{"$WIREGUARD_SUBNET_IP", openvpnConfig.value(config_key::subnet_address).toString(protocols::wireguard::defaultSubnetAddress) }});
vars.append({{"$WIREGUARD_SUBNET_CIDR", openvpnConfig.value(config_key::subnet_cidr).toString(protocols::wireguard::defaultSubnetCidr) }});
vars.append({{"$WIREGUARD_SUBNET_MASK", openvpnConfig.value(config_key::subnet_mask).toString(protocols::wireguard::defaultSubnetMask) }});
vars.append({{"$WIREGUARD_SERVER_PORT", wireguarConfig.value(config_key::port).toString(protocols::wireguard::defaultPort) }});
QString serverIp = Utils::getIPAddress(credentials.hostName);
if (!serverIp.isEmpty()) {
vars.append({{"$SERVER_IP_ADDRESS", serverIp}});
@@ -730,5 +691,6 @@ QString ServerController::replaceVars(const QString &script, const Vars &vars)
//qDebug() << "Replacing" << var.first << var.second;
s.replace(var.first, var.second);
}
//qDebug().noquote() << script;
return s;
}
+7 -8
View File
@@ -8,6 +8,7 @@
#include "defs.h"
#include "protocols/protocols_defs.h"
#include "sftpdefs.h"
using namespace amnezia;
@@ -35,10 +36,12 @@ public:
static ErrorCode checkOpenVpnServer(DockerContainer container, const ServerCredentials &credentials);
static ErrorCode uploadFileToHost(const ServerCredentials &credentials, const QByteArray &data, const QString &remotePath);
static ErrorCode uploadFileToHost(const ServerCredentials &credentials, const QByteArray &data,
const QString &remotePath, QSsh::SftpOverwriteMode overwriteMode = QSsh::SftpOverwriteMode::SftpOverwriteExisting);
static ErrorCode uploadTextFileToContainer(DockerContainer container,
const ServerCredentials &credentials, const QString &file, const QString &path);
const ServerCredentials &credentials, const QString &file, const QString &path,
QSsh::SftpOverwriteMode overwriteMode = QSsh::SftpOverwriteMode::SftpOverwriteExisting);
static QString getTextFileFromContainer(DockerContainer container,
const ServerCredentials &credentials, const QString &path, ErrorCode *errorCode = nullptr);
@@ -54,15 +57,11 @@ public:
static Vars genVarsForScript(const ServerCredentials &credentials, DockerContainer container = DockerContainer::None, const QJsonObject &config = QJsonObject());
static QString checkSshConnection(const ServerCredentials &credentials, ErrorCode *errorCode = nullptr);
private:
static QSsh::SshConnection *connectToHost(const QSsh::SshConnectionParameters &sshParams);
private:
static ErrorCode installDockerWorker(const ServerCredentials &credentials, DockerContainer container);
//static ErrorCode setupOpenVpnServer(const ServerCredentials &credentials, const QJsonObject &config = QJsonObject());
//static ErrorCode setupOpenVpnOverCloakServer(const ServerCredentials &credentials, const QJsonObject &config = QJsonObject());
// static ErrorCode setupShadowSocksServer(const ServerCredentials &credentials, const QJsonObject &config = QJsonObject());
static ErrorCode prepareHostWorker(const ServerCredentials &credentials, DockerContainer container, const QJsonObject &config = QJsonObject());
static ErrorCode buildContainerWorker(const ServerCredentials &credentials, DockerContainer container, const QJsonObject &config = QJsonObject());
static ErrorCode runContainerWorker(const ServerCredentials &credentials, DockerContainer container, const QJsonObject &config = QJsonObject());
+2 -1
View File
@@ -4,6 +4,7 @@
#define APPLICATION_NAME "AmneziaVPN"
#define SERVICE_NAME "AmneziaVPN-service"
#define ORGANIZATION_NAME "AmneziaVPN.ORG"
#define APP_VERSION "1.6.0.0"
#define APP_MAJOR_VERSION "1.8.0"
#define APP_VERSION "1.8.0.0"
#endif // DEFINES_H
Binary file not shown.

After

Width:  |  Height:  |  Size: 150 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 215 B

After

Width:  |  Height:  |  Size: 324 B

+12 -5
View File
@@ -68,18 +68,25 @@ int main(int argc, char *argv[])
parser.addHelpOption();
parser.addVersionOption();
QCommandLineOption c_autostart {{"a", "autostart"}, "System autostart"};
parser.addOption(c_autostart);
parser.process(app);
if (!Debug::init()) {
qWarning() << "Initialization of debug subsystem failed";
}
QFont f("Lato Regular", 10);
f.setStyleStrategy(QFont::PreferAntialias);
app.setFont(f);
app.setQuitOnLastWindowClosed(false);
MainWindow mainWindow;
mainWindow.show();
#ifdef Q_OS_WIN
if (parser.isSet("a")) mainWindow.showOnStartup();
else mainWindow.show();
#else
mainWindow.showOnStartup();
#endif
if (app.isPrimary()) {
QObject::connect(&app, &SingleApplication::instanceStarted, &mainWindow, [&](){
+4 -4
View File
@@ -3,11 +3,11 @@ LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
IDI_ICON1 ICON "../images/app.ico"
#define VER_FILEVERSION 1,6,0,0
#define VER_FILEVERSION_STR "1.6.0.0\0"
#define VER_FILEVERSION 1,7,0,0
#define VER_FILEVERSION_STR "1.7.0.0\0"
#define VER_PRODUCTVERSION 1,6,0,0
#define VER_PRODUCTVERSION_STR "1.6.0.0\0"
#define VER_PRODUCTVERSION 1,7,0,0
#define VER_PRODUCTVERSION_STR "1.7.0.0\0"
#define VER_COMPANYNAME_STR "AmneziaVPN"
#define VER_FILEDESCRIPTION_STR "AmneziaVPN"
@@ -38,7 +38,7 @@ ErrorCode OpenVpnOverCloakProtocol::start()
QStringList args = QStringList() << "-c" << m_cloakCfgFile.fileName()
<< "-s" << m_cloakConfig.value(config_key::remote).toString()
<< "-p" << amnezia::protocols::cloak::defaultPort
<< "-p" << m_cloakConfig.value(config_key::port).toString(amnezia::protocols::cloak::defaultPort)
<< "-l" << amnezia::protocols::openvpn::defaultPort;
if (m_cloakConfig.value(config_key::transport_proto).toString() == protocols::UDP) {
@@ -57,9 +57,9 @@ ErrorCode OpenVpnOverCloakProtocol::start()
qDebug().noquote() << "ck-client:" << m_ckProcess.readAllStandardOutput();
});
connect(&m_ckProcess, QOverload<int, QProcess::ExitStatus>::of(&QProcess::finished), this, [this](int exitCode, QProcess::ExitStatus exitStatus){
m_errorHandlerConnection = connect(&m_ckProcess, QOverload<int, QProcess::ExitStatus>::of(&QProcess::finished), this, [this](int exitCode, QProcess::ExitStatus exitStatus){
qDebug().noquote() << "OpenVpnOverCloakProtocol finished, exitCode, exiStatus" << exitCode << exitStatus;
setConnectionState(VpnProtocol::ConnectionState::Disconnected);
setConnectionState(VpnProtocol::Disconnected);
if (exitStatus != QProcess::NormalExit){
emit protocolError(amnezia::ErrorCode::CloakExecutableCrashed);
stop();
@@ -83,6 +83,7 @@ ErrorCode OpenVpnOverCloakProtocol::start()
void OpenVpnOverCloakProtocol::stop()
{
disconnect(m_errorHandlerConnection);
OpenVpnProtocol::stop();
qDebug() << "OpenVpnOverCloakProtocol::stop()";
@@ -25,6 +25,7 @@ private:
private:
QProcess m_ckProcess;
QTemporaryFile m_cloakCfgFile;
QMetaObject::Connection m_errorHandlerConnection;
};
#endif // OPENVPNOVERCLOAKPROTOCOL_H
+31 -57
View File
@@ -5,12 +5,16 @@
#include <QTcpSocket>
#include "debug.h"
#include "openvpnprotocol.h"
#include "defines.h"
#include "utils.h"
#include "openvpnprotocol.h"
OpenVpnProtocol::OpenVpnProtocol(const QJsonObject &configuration, QObject* parent) :
VpnProtocol(configuration, parent)
{
Utils::initializePath(defaultConfigPath());
readOpenVpnConfiguration(configuration);
connect(&m_managementServer, &ManagementServer::readyRead, this, &OpenVpnProtocol::onReadyReadDataFromManagementServer);
}
@@ -22,22 +26,33 @@ OpenVpnProtocol::~OpenVpnProtocol()
QThread::msleep(200);
}
QString OpenVpnProtocol::defaultConfigFileName()
{
qDebug() << "OpenVpnProtocol::defaultConfigFileName" << defaultConfigPath() + QString("/%1.ovpn").arg(APPLICATION_NAME);
return defaultConfigPath() + QString("/%1.ovpn").arg(APPLICATION_NAME);
}
QString OpenVpnProtocol::defaultConfigPath()
{
return QStandardPaths::writableLocation(QStandardPaths::AppDataLocation) + "/config";
}
void OpenVpnProtocol::stop()
{
qDebug() << "OpenVpnProtocol::stop()";
// TODO: need refactoring
// sendTermSignal() will even return true while server connected ???
if ((m_connectionState == VpnProtocol::ConnectionState::Preparing) ||
(m_connectionState == VpnProtocol::ConnectionState::Connecting) ||
(m_connectionState == VpnProtocol::ConnectionState::Connected) ||
(m_connectionState == VpnProtocol::ConnectionState::Reconnecting)) {
if ((m_connectionState == VpnProtocol::Preparing) ||
(m_connectionState == VpnProtocol::Connecting) ||
(m_connectionState == VpnProtocol::Connected) ||
(m_connectionState == VpnProtocol::Reconnecting)) {
if (!sendTermSignal()) {
killOpenVpnProcess();
}
m_managementServer.stop();
qApp->processEvents();
setConnectionState(VpnProtocol::ConnectionState::Disconnecting);
setConnectionState(VpnProtocol::Disconnecting);
}
}
@@ -54,7 +69,7 @@ ErrorCode OpenVpnProtocol::checkAndSetupTapDriver()
QRemoteObjectPendingReply<bool> resultInstall = IpcClient::Interface()->checkAndInstallDriver();
resultInstall.waitForFinished();
if (!resultInstall.returnValue()) return ErrorCode::OpenVpnUnknownError;
if (!resultInstall.returnValue()) return ErrorCode::OpenVpnTapAdapterError;
}
return ErrorCode::NoError;
}
@@ -81,7 +96,7 @@ void OpenVpnProtocol::readOpenVpnConfiguration(const QJsonObject &configuration)
QFileInfo file(m_configFileName);
if (file.fileName().isEmpty()) {
m_configFileName = Utils::defaultVpnConfigFileName();
m_configFileName = defaultConfigFileName();
}
qDebug().noquote() << QString("Set config file: '%1'").arg(configPath());
@@ -125,9 +140,9 @@ void OpenVpnProtocol::updateRouteGateway(QString line)
QString OpenVpnProtocol::openVpnExecPath() const
{
#ifdef Q_OS_WIN
return Utils::executable(QString("openvpn/%1/openvpn").arg(QSysInfo::buildCpuArchitecture()), true);
return Utils::executable("openvpn/openvpn", true);
#else
return Utils::executable(QString("/openvpn"), true);
return Utils::executable("/openvpn", true);
#endif
}
@@ -174,7 +189,7 @@ ErrorCode OpenVpnProtocol::start()
QStringList arguments({"--config" , configPath(),
"--management", m_managementHost, QString::number(m_managementPort),
"--management-client",
"--log-append", vpnLogFileNamePath
"--log", vpnLogFileNamePath
});
m_openVpnProcess->setArguments(arguments);
@@ -233,14 +248,14 @@ void OpenVpnProtocol::onReadyReadDataFromManagementServer()
if (line.contains("CONNECTED,SUCCESS")) {
sendByteCount();
stopTimeoutTimer();
setConnectionState(VpnProtocol::ConnectionState::Connected);
setConnectionState(VpnProtocol::Connected);
continue;
} else if (line.contains("EXITING,SIGTER")) {
//openVpnStateSigTermHandler();
setConnectionState(VpnProtocol::ConnectionState::Disconnecting);
setConnectionState(VpnProtocol::Disconnecting);
continue;
} else if (line.contains("RECONNECTING")) {
setConnectionState(VpnProtocol::ConnectionState::Reconnecting);
setConnectionState(VpnProtocol::Reconnecting);
continue;
}
}
@@ -288,52 +303,11 @@ void OpenVpnProtocol::updateVpnGateway(const QString &line)
for (const QString &l : params) {
if (l.contains("ifconfig")) {
if (l.split(" ").size() == 3) {
m_vpnAddress = l.split(" ").at(1);
m_vpnLocalAddress = l.split(" ").at(1);
m_vpnGateway = l.split(" ").at(2);
qDebug() << QString("Set vpn address %1, gw %2").arg(m_vpnAddress).arg(vpnGateway());
qDebug() << QString("Set vpn local address %1, gw %2").arg(m_vpnLocalAddress).arg(vpnGateway());
}
}
}
// QProcess ipconfig;
// ipconfig.start("ipconfig", QStringList() << "/all");
// ipconfig.waitForStarted();
// ipconfig.waitForFinished();
// QString d = ipconfig.readAll();
// d.replace("\r", "");
// //qDebug().noquote() << d;
// QStringList adapters = d.split(":\n");
// bool isTapV9Present = false;
// QString tapV9;
// for (int i = 0; i < adapters.size(); ++i) {
// if (adapters.at(i).contains("TAP-Windows Adapter V9")) {
// isTapV9Present = true;
// tapV9 = adapters.at(i);
// break;
// }
// }
// if (!isTapV9Present) {
// m_vpnGateway = "";
// }
// QStringList lines = tapV9.split("\n");
// for (int i = 0; i < lines.size(); ++i) {
// if (!lines.at(i).contains("DHCP")) continue;
// QRegularExpression re("(: )([\\d\\.]+)($)");
// QRegularExpressionMatch match = re.match(lines.at(i));
// if (match.hasMatch()) {
// qDebug().noquote() << "Current VPN Gateway IP Address: " << match.captured(0);
// m_vpnGateway = match.captured(2);
// return;
// }
// else continue;
// }
// m_vpnGateway = "";
}
+2
View File
@@ -22,6 +22,8 @@ public:
void stop() override;
ErrorCode checkAndSetupTapDriver();
static QString defaultConfigFileName();
static QString defaultConfigPath();
protected slots:
void onReadyReadDataFromManagementServer();
+20 -4
View File
@@ -29,13 +29,14 @@ constexpr char transport_proto[] = "transport_proto";
constexpr char cipher[] = "cipher";
constexpr char hash[] = "hash";
constexpr char ncp_disable[] = "ncp_disable";
constexpr char tls_auth[] = "tls_auth";
constexpr char site[] = "site";
constexpr char block_outside_dns[] = "block_outside_dns";
constexpr char subnet_address[] = "subnet_address";
constexpr char subnet_mask[] = "subnet_mask";
constexpr char subnet_mask_val[] = "subnet_mask_val";
constexpr char subnet_cidr[] = "subnet_cidr";
// proto config keys
constexpr char last_config[] = "last_config";
@@ -54,14 +55,16 @@ constexpr char amnezia_wireguard[] = "amnezia-wireguard";
namespace protocols {
constexpr char vpnDefaultSubnetAddress[] = "10.8.0.0";
constexpr char vpnDefaultSubnetMask[] = "255.255.255.0";
constexpr char vpnDefaultSubnetMaskVal[] = "24";
constexpr char UDP[] = "udp"; // case sens
constexpr char TCP[] = "tcp";
namespace openvpn {
constexpr char defaultSubnetAddress[] = "10.8.0.0";
constexpr char defaultSubnetMask[] = "255.255.255.0";
constexpr char defaultSubnetCidr[] = "24";
constexpr char caCertPath[] = "/opt/amnezia/openvpn/pki/ca.crt";
constexpr char clientCertPath[] = "/opt/amnezia/openvpn/pki/issued";
constexpr char taKeyPath[] = "/opt/amnezia/openvpn/ta.key";
@@ -72,7 +75,9 @@ constexpr char defaultCipher[] = "AES-256-GCM";
constexpr char defaultHash[] = "SHA512";
constexpr bool defaultBlockOutsideDns = true;
constexpr bool defaultNcpDisable = false;
constexpr bool defaultTlsAuth = true;
constexpr char ncpDisableString[] = "ncp-disable";
constexpr char tlsAuthString[] = "tls-auth /opt/amnezia/openvpn/ta.key 0";
}
@@ -93,6 +98,17 @@ constexpr char defaultCipher[] = "chacha20-ietf-poly1305";
}
namespace wireguard {
constexpr char defaultSubnetAddress[] = "10.8.1.0";
constexpr char defaultSubnetMask[] = "255.255.255.0";
constexpr char defaultSubnetCidr[] = "24";
constexpr char defaultPort[] = "51820";
constexpr char serverConfigPath[] = "/opt/amnezia/wireguard/wg0.conf";
constexpr char serverPublicKeyPath[] = "/opt/amnezia/wireguard/wireguard_server_public_key.key";
constexpr char serverPskKeyPath[] = "/opt/amnezia/wireguard/wireguard_psk.key";
}
} // namespace protocols
+1 -1
View File
@@ -53,7 +53,7 @@ ErrorCode ShadowSocksVpnProtocol::start()
connect(&m_ssProcess, QOverload<int, QProcess::ExitStatus>::of(&QProcess::finished), this, [this](int exitCode, QProcess::ExitStatus exitStatus){
qDebug().noquote() << "ShadowSocksVpnProtocol finished, exitCode, exiStatus" << exitCode << exitStatus;
setConnectionState(VpnProtocol::ConnectionState::Disconnected);
setConnectionState(VpnProtocol::Disconnected);
if (exitStatus != QProcess::NormalExit){
emit protocolError(amnezia::ErrorCode::ShadowSocksExecutableCrashed);
stop();
+1
View File
@@ -3,6 +3,7 @@
#include "vpnprotocol.h"
#include "core/errorstrings.h"
#include "protocols/protocols_defs.h"
VpnProtocol::VpnProtocol(const QJsonObject &configuration, QObject* parent)
: QObject(parent),
+1 -1
View File
@@ -55,7 +55,7 @@ protected:
ConnectionState m_connectionState;
QString m_routeGateway;
QString m_vpnAddress;
QString m_vpnLocalAddress;
QString m_vpnGateway;
QJsonObject m_rawConfig;
+232
View File
@@ -0,0 +1,232 @@
#include <QCoreApplication>
#include <QFileInfo>
#include <QProcess>
#include <QRegularExpression>
#include <QTcpSocket>
#include <QThread>
#include "debug.h"
#include "wireguardprotocol.h"
#include "utils.h"
WireguardProtocol::WireguardProtocol(const QJsonObject &configuration, QObject* parent) :
VpnProtocol(configuration, parent)
{
//m_configFile.setFileTemplate(QDir::tempPath() + QDir::separator() + serviceName() + ".conf");
m_configFile.setFileName(QDir::tempPath() + QDir::separator() + serviceName() + ".conf");
readWireguardConfiguration(configuration);
}
WireguardProtocol::~WireguardProtocol()
{
qDebug() << "WireguardProtocol::~WireguardProtocol()";
WireguardProtocol::stop();
QThread::msleep(200);
}
void WireguardProtocol::stop()
{
if (!QFileInfo::exists(wireguardExecPath())) {
qCritical() << "Wireguard executable missing!";
setLastError(ErrorCode::ExecutableMissing);
return;
}
m_wireguardStopProcess = IpcClient::CreatePrivilegedProcess();
if (!m_wireguardStopProcess) {
qCritical() << "IpcProcess replica is not created!";
setLastError(ErrorCode::AmneziaServiceConnectionFailed);
return;
}
m_wireguardStopProcess->waitForSource(1000);
if (!m_wireguardStopProcess->isInitialized()) {
qWarning() << "IpcProcess replica is not connected!";
setLastError(ErrorCode::AmneziaServiceConnectionFailed);
return;
}
m_wireguardStopProcess->setProgram(wireguardExecPath());
QStringList arguments({"/uninstalltunnelservice", serviceName(), });
m_wireguardStopProcess->setArguments(arguments);
qDebug() << arguments.join(" ");
connect(m_wireguardStopProcess.data(), &IpcProcessInterfaceReplica::errorOccurred, this, [this](QProcess::ProcessError error) {
qDebug() << "WireguardProtocol::WireguardProtocol errorOccurred" << error;
setConnectionState(ConnectionState::Disconnected);
});
connect(m_wireguardStopProcess.data(), &IpcProcessInterfaceReplica::stateChanged, this, [this](QProcess::ProcessState newState) {
qDebug() << "WireguardProtocol::WireguardProtocol Stop stateChanged" << newState;
});
m_wireguardStopProcess->start();
setConnectionState(VpnProtocol::Disconnected);
}
void WireguardProtocol::readWireguardConfiguration(const QJsonObject &configuration)
{
if (configuration.contains(config::key_wireguard_config_data)) {
if (!m_configFile.open(QIODevice::WriteOnly | QIODevice::Truncate)) {
qCritical() << "Failed to save wireguard config to" << m_configFile.fileName();
return;
}
m_isConfigLoaded = true;
m_configFile.write(configuration.value(config::key_wireguard_config_data).toString().toUtf8());
m_configFile.close();
m_configFileName = m_configFile.fileName();
qDebug().noquote() << QString("Set config data") << m_configFileName;
qDebug().noquote() << QString("Set config data") << configuration.value(config::key_wireguard_config_data).toString().toUtf8();
}
// else if (configuration.contains(config::key_wireguard_config_path)) {
// m_configFileName = configuration.value(config::key_wireguard_config_path).toString();
// QFileInfo file(m_configFileName);
// if (file.fileName().isEmpty()) {
// m_configFileName = defaultConfigFileName();
// }
// qDebug().noquote() << QString("Set config file: '%1'").arg(configPath());
// }
}
//bool WireguardProtocol::openVpnProcessIsRunning() const
//{
// return Utils::processIsRunning("openvpn");
//}
QString WireguardProtocol::configPath() const
{
return m_configFileName;
}
void WireguardProtocol::updateRouteGateway(QString line)
{
// TODO: fix for macos
line = line.split("ROUTE_GATEWAY", QString::SkipEmptyParts).at(1);
if (!line.contains("/")) return;
m_routeGateway = line.split("/", QString::SkipEmptyParts).first();
m_routeGateway.replace(" ", "");
qDebug() << "Set VPN route gateway" << m_routeGateway;
}
QString WireguardProtocol::wireguardExecPath() const
{
#ifdef Q_OS_WIN
return Utils::executable("wireguard/wireguard", true);
#else
return Utils::executable("/wireguard", true);
#endif
}
ErrorCode WireguardProtocol::start()
{
if (!m_isConfigLoaded) {
setLastError(ErrorCode::ConfigMissing);
return lastError();
}
//qDebug() << "Start OpenVPN connection";
WireguardProtocol::stop();
if (!QFileInfo::exists(wireguardExecPath())) {
setLastError(ErrorCode::ExecutableMissing);
return lastError();
}
if (!QFileInfo::exists(configPath())) {
setLastError(ErrorCode::ConfigMissing);
return lastError();
}
setConnectionState(ConnectionState::Connecting);
m_wireguardStartProcess = IpcClient::CreatePrivilegedProcess();
if (!m_wireguardStartProcess) {
//qWarning() << "IpcProcess replica is not created!";
setLastError(ErrorCode::AmneziaServiceConnectionFailed);
return ErrorCode::AmneziaServiceConnectionFailed;
}
m_wireguardStartProcess->waitForSource(1000);
if (!m_wireguardStartProcess->isInitialized()) {
qWarning() << "IpcProcess replica is not connected!";
setLastError(ErrorCode::AmneziaServiceConnectionFailed);
return ErrorCode::AmneziaServiceConnectionFailed;
}
m_wireguardStartProcess->setProgram(wireguardExecPath());
QStringList arguments({"/installtunnelservice", configPath(), });
m_wireguardStartProcess->setArguments(arguments);
qDebug() << arguments.join(" ");
connect(m_wireguardStartProcess.data(), &IpcProcessInterfaceReplica::errorOccurred, this, [this](QProcess::ProcessError error) {
qDebug() << "WireguardProtocol::WireguardProtocol errorOccurred" << error;
setConnectionState(ConnectionState::Disconnected);
});
connect(m_wireguardStartProcess.data(), &IpcProcessInterfaceReplica::stateChanged, this, [this](QProcess::ProcessState newState) {
qDebug() << "WireguardProtocol::WireguardProtocol stateChanged" << newState;
});
connect(m_wireguardStartProcess.data(), &IpcProcessInterfaceReplica::finished, this, [this]() {
setConnectionState(ConnectionState::Connected);
});
connect(m_wireguardStartProcess.data(), &IpcProcessInterfaceReplica::readyRead, this, [this]() {
QRemoteObjectPendingReply<QByteArray> reply = m_wireguardStartProcess->readAll();
reply.waitForFinished(1000);
qDebug() << "WireguardProtocol::WireguardProtocol readyRead" << reply.returnValue();
});
connect(m_wireguardStartProcess.data(), &IpcProcessInterfaceReplica::readyReadStandardOutput, this, [this]() {
QRemoteObjectPendingReply<QByteArray> reply = m_wireguardStartProcess->readAllStandardOutput();
reply.waitForFinished(1000);
qDebug() << "WireguardProtocol::WireguardProtocol readAllStandardOutput" << reply.returnValue();
});
connect(m_wireguardStartProcess.data(), &IpcProcessInterfaceReplica::readyReadStandardError, this, [this]() {
QRemoteObjectPendingReply<QByteArray> reply = m_wireguardStartProcess->readAllStandardError();
reply.waitForFinished(1000);
qDebug() << "WireguardProtocol::WireguardProtocol readAllStandardError" << reply.returnValue();
});
m_wireguardStartProcess->start();
return ErrorCode::NoError;
}
void WireguardProtocol::updateVpnGateway(const QString &line)
{
// // line looks like
// // PUSH: Received control message: 'PUSH_REPLY,route 10.8.0.1,topology net30,ping 10,ping-restart 120,ifconfig 10.8.0.6 10.8.0.5,peer-id 0,cipher AES-256-GCM'
// QStringList params = line.split(",");
// for (const QString &l : params) {
// if (l.contains("ifconfig")) {
// if (l.split(" ").size() == 3) {
// m_vpnLocalAddress = l.split(" ").at(1);
// m_vpnGateway = l.split(" ").at(2);
// qDebug() << QString("Set vpn local address %1, gw %2").arg(m_vpnLocalAddress).arg(vpnGateway());
// }
// }
// }
}
QString WireguardProtocol::serviceName() const
{
return "AmneziaVPN.WireGuard0";
}
+46
View File
@@ -0,0 +1,46 @@
#ifndef WIREGUARDPROTOCOL_H
#define WIREGUARDPROTOCOL_H
#include <QObject>
#include <QProcess>
#include <QString>
#include <QTemporaryFile>
#include <QTimer>
#include "vpnprotocol.h"
#include "core/ipcclient.h"
class WireguardProtocol : public VpnProtocol
{
Q_OBJECT
public:
explicit WireguardProtocol(const QJsonObject& configuration, QObject* parent = nullptr);
virtual ~WireguardProtocol() override;
ErrorCode start() override;
void stop() override;
private:
QString configPath() const;
QString wireguardExecPath() const;
//bool openVpnProcessIsRunning() const;
void readWireguardConfiguration(const QJsonObject &configuration);
void updateRouteGateway(QString line);
void updateVpnGateway(const QString &line);
QString serviceName() const;
private:
QString m_configFileName;
QFile m_configFile;
QSharedPointer<IpcProcessInterfaceReplica> m_wireguardStartProcess;
QSharedPointer<IpcProcessInterfaceReplica> m_wireguardStopProcess;
bool m_isConfigLoaded = false;
};
#endif // WIREGUARDPROTOCOL_H
+6
View File
@@ -61,5 +61,11 @@
<file>server_scripts/openvpn_shadowsocks/run_container.sh</file>
<file>server_scripts/openvpn_shadowsocks/start.sh</file>
<file>server_scripts/openvpn_shadowsocks/template.ovpn</file>
<file>images/folder.png</file>
<file>server_scripts/wireguard/configure_container.sh</file>
<file>server_scripts/wireguard/Dockerfile</file>
<file>server_scripts/wireguard/run_container.sh</file>
<file>server_scripts/wireguard/start.sh</file>
<file>server_scripts/wireguard/template.conf</file>
</qresource>
</RCC>
+6 -5
View File
@@ -1,6 +1,7 @@
pm_apt="/usr/bin/apt-get"; pm_yum="/usr/bin/yum"; if [[ -f "$pm_apt" ]]; then pm=$pm_apt; else pm=$pm_yum; fi; if [[ ! -f "/usr/bin/sudo" ]]; then $pm update -y -q; $pm install -y -q sudo; fi
pm_apt="/usr/bin/apt-get"; pm_yum="/usr/bin/yum"; if [[ -f "$pm_apt" ]]; then pm=$pm_apt; else pm=$pm_yum; fi; sudo $pm update -y -q
pm_apt="/usr/bin/apt-get"; pm_yum="/usr/bin/yum"; if [[ -f "$pm_apt" ]]; then pm=$pm_apt; else pm=$pm_yum; fi; sudo $pm install -y -q curl
pm_apt="/usr/bin/apt-get"; pm_yum="/usr/bin/yum"; if [[ -f "$pm_apt" ]]; then sudo export DEBIAN_FRONTEND=noninteractive; sudo $pm_apt install -y -q docker.io; else sudo $pm_yum install -y -q docker; fi
pm_apt="/usr/bin/apt-get"; pm_yum="/usr/bin/yum";\
if [[ -f "$pm_apt" ]]; then pm=$pm_apt; docker_pkg="docker.io"; else pm=$pm_yum; docker_pkg="docker"; fi;\
if [[ ! -f "/usr/bin/sudo" ]]; then $pm update -y -q; $pm install -y -q sudo; fi;\
docker_service=$(systemctl list-units --full -all | grep docker.service);\
if [[ -f "$pm_apt" ]]; then export DEBIAN_FRONTEND=noninteractive; fi;\
if [[ -z "$docker_service" ]]; then sudo $pm update -y -q; sudo $pm install -y -q curl $docker_pkg; fi;\
sudo systemctl start docker
@@ -7,7 +7,7 @@ ca /opt/amnezia/openvpn/ca.crt \\n\
cert /opt/amnezia/openvpn/AmneziaReq.crt \\n\
key /opt/amnezia/openvpn/AmneziaReq.key \\n\
dh /opt/amnezia/openvpn/dh.pem \\n\
server $VPN_SUBNET_IP $VPN_SUBNET_MASK \\n\
server $OPENVPN_SUBNET_IP $OPENVPN_SUBNET_MASK \\n\
ifconfig-pool-persist ipp.txt \\n\
duplicate-cn \\n\
keepalive 10 120 \\n\
@@ -23,5 +23,5 @@ status openvpn-status.log \\n\
verb 1 \\n\
tls-server \\n\
tls-version-min 1.2 \\n\
tls-auth /opt/amnezia/openvpn/ta.key 0" >>/opt/amnezia/openvpn/server.conf'
$OPENVPN_TLS_AUTH" >/opt/amnezia/openvpn/server.conf'
+3 -2
View File
@@ -3,6 +3,7 @@
# This scripts copied from Amnezia client to Docker container to /opt/amnezia and launched every time container starts
echo "Container startup"
ifconfig eth0:0 $SERVER_IP_ADDRESS netmask 255.255.255.255 up
if [ ! -c /dev/net/tun ]; then mkdir -p /dev/net; mknod /dev/net/tun c 10 200; fi
@@ -12,10 +13,10 @@ iptables -A FORWARD -i tun0 -j ACCEPT
iptables -A OUTPUT -o tun0 -j ACCEPT
# Allow forwarding traffic only from the VPN.
iptables -A FORWARD -i tun0 -o eth0 -s $VPN_SUBNET_IP/$VPN_SUBNET_MASK_VAL -j ACCEPT
iptables -A FORWARD -i tun0 -o eth0 -s $OPENVPN_SUBNET_IP/$OPENVPN_SUBNET_CIDR -j ACCEPT
iptables -A FORWARD -m state --state ESTABLISHED,RELATED -j ACCEPT
iptables -t nat -A POSTROUTING -s $VPN_SUBNET_IP/$VPN_SUBNET_MASK_VAL -o eth0 -j MASQUERADE
iptables -t nat -A POSTROUTING -s $OPENVPN_SUBNET_IP/$OPENVPN_SUBNET_CIDR -o eth0 -j MASQUERADE
# kill daemons in case of restart
killall -KILL openvpn
@@ -16,6 +16,10 @@ RUN chmod a+x /opt/amnezia/start.sh
RUN curl -L https://github.com/cbeuw/Cloak/releases/download/v2.5.3/ck-server-linux-amd64-v2.5.3 > /usr/bin/ck-server
RUN chmod a+x /usr/bin/ck-server
RUN curl -L https://github.com/shadowsocks/shadowsocks-rust/releases/download/v1.10.9/shadowsocks-v1.10.9.x86_64-unknown-linux-musl.tar.xz > /usr/bin/ss.tar.xz
RUN tar -Jxvf /usr/bin/ss.tar.xz -C /usr/bin/
RUN chmod a+x /usr/bin/ssserver
# Tune network
RUN echo -e " \n\
fs.file-max = 51200 \n\
@@ -7,7 +7,7 @@ ca /opt/amnezia/openvpn/ca.crt \\n\
cert /opt/amnezia/openvpn/AmneziaReq.crt \\n\
key /opt/amnezia/openvpn/AmneziaReq.key \\n\
dh /opt/amnezia/openvpn/dh.pem \\n\
server $VPN_SUBNET_IP $VPN_SUBNET_MASK \\n\
server $OPENVPN_SUBNET_IP $OPENVPN_SUBNET_MASK \\n\
ifconfig-pool-persist ipp.txt \\n\
duplicate-cn \\n\
keepalive 10 120 \\n\
@@ -23,7 +23,7 @@ status openvpn-status.log \\n\
verb 1 \\n\
tls-server \\n\
tls-version-min 1.2 \\n\
tls-auth /opt/amnezia/openvpn/ta.key 0" >>/opt/amnezia/openvpn/server.conf'
$OPENVPN_TLS_AUTH" >/opt/amnezia/openvpn/server.conf'
# Cloak config
sudo docker exec -i $CONTAINER_NAME bash -c '\
@@ -37,9 +37,13 @@ echo $CLOAK_PRIVATE_KEY > /opt/amnezia/cloak/cloak_private.key; \
echo -e "{\\n\
\"ProxyBook\": {\\n\
\"openvpn\": [\\n\
\"$OPENVPN_TRANSPORT_PROTO\",\\n\
\"localhost:$OPENVPN_PORT\"\\n\
]\\n\
\"$OPENVPN_TRANSPORT_PROTO\",\\n\
\"localhost:$OPENVPN_PORT\"\\n\
],\\n\
\"shadowsocks\": [\\n\
\"tcp\",\\n\
\"localhost:$SHADOWSOCKS_SERVER_PORT\"\\n\
]\\n\
},\\n\
\"BypassUID\": [\\n\
\"$CLOAK_BYPASS_UID\"\\n\
@@ -51,3 +55,17 @@ echo -e "{\\n\
\"DatabasePath\": \"userinfo.db\",\\n\
\"StreamTimeout\": 300\\n\
}" >/opt/amnezia/cloak/ck-config.json'
# ShadowSocks config
sudo docker exec -i $CONTAINER_NAME bash -c '\
mkdir -p /opt/amnezia/shadowsocks; \
cd /opt/amnezia/shadowsocks || exit 1; \
SHADOWSOCKS_PASSWORD=$(openssl rand -base64 32 | tr "=" "A" | tr "+" "A" | tr "/" "A") && echo $SHADOWSOCKS_PASSWORD > /opt/amnezia/shadowsocks/shadowsocks.key; \
echo -e "{\\n\
\"local_port\": 8585,\\n\
\"method\": \"$SHADOWSOCKS_CIPHER\",\\n\
\"password\": \"$SHADOWSOCKS_PASSWORD\",\\n\
\"server\": \"0.0.0.0\",\\n\
\"server_port\": $SHADOWSOCKS_SERVER_PORT,\\n\
\"timeout\": 60\\n\
}" >/opt/amnezia/shadowsocks/ss-config.json'
+5 -2
View File
@@ -3,6 +3,7 @@
# This scripts copied from Amnezia client to Docker container to /opt/amnezia and launched every time container starts
echo "Container startup"
ifconfig eth0:0 $SERVER_IP_ADDRESS netmask 255.255.255.255 up
if [ ! -c /dev/net/tun ]; then mkdir -p /dev/net; mknod /dev/net/tun c 10 200; fi
@@ -12,17 +13,19 @@ iptables -A FORWARD -i tun0 -j ACCEPT
iptables -A OUTPUT -o tun0 -j ACCEPT
# Allow forwarding traffic only from the VPN.
iptables -A FORWARD -i tun0 -o eth0 -s $VPN_SUBNET_IP/$VPN_SUBNET_MASK_VAL -j ACCEPT
iptables -A FORWARD -i tun0 -o eth0 -s $OPENVPN_SUBNET_IP/$OPENVPN_SUBNET_CIDR -j ACCEPT
iptables -A FORWARD -m state --state ESTABLISHED,RELATED -j ACCEPT
iptables -t nat -A POSTROUTING -s $VPN_SUBNET_IP/$VPN_SUBNET_MASK_VAL -o eth0 -j MASQUERADE
iptables -t nat -A POSTROUTING -s $OPENVPN_SUBNET_IP/$OPENVPN_SUBNET_CIDR -o eth0 -j MASQUERADE
# kill daemons in case of restart
killall -KILL openvpn
killall -KILL ck-server
killall -KILL ssserver
# start daemons if configured
if [ -f /opt/amnezia/openvpn/ca.crt ]; then (openvpn --config /opt/amnezia/openvpn/server.conf --daemon); fi
if [ -f /opt/amnezia/shadowsocks/ss-config.json ]; then (ssserver -c /opt/amnezia/shadowsocks/ss-config.json &); fi
if [ -f /opt/amnezia/cloak/ck-config.json ]; then (ck-server -c /opt/amnezia/cloak/ck-config.json &); fi
tail -f /dev/null
@@ -7,7 +7,7 @@ ca /opt/amnezia/openvpn/ca.crt \\n\
cert /opt/amnezia/openvpn/AmneziaReq.crt \\n\
key /opt/amnezia/openvpn/AmneziaReq.key \\n\
dh /opt/amnezia/openvpn/dh.pem \\n\
server $VPN_SUBNET_IP $VPN_SUBNET_MASK \\n\
server $OPENVPN_SUBNET_IP $OPENVPN_SUBNET_MASK \\n\
ifconfig-pool-persist ipp.txt \\n\
duplicate-cn \\n\
keepalive 10 120 \\n\
@@ -23,9 +23,9 @@ status openvpn-status.log \\n\
verb 1 \\n\
tls-server \\n\
tls-version-min 1.2 \\n\
tls-auth /opt/amnezia/openvpn/ta.key 0" >>/opt/amnezia/openvpn/server.conf'
$OPENVPN_TLS_AUTH" >/opt/amnezia/openvpn/server.conf'
# Cloak config
# ShadowSocks config
sudo docker exec -i $CONTAINER_NAME bash -c '\
mkdir -p /opt/amnezia/shadowsocks; \
cd /opt/amnezia/shadowsocks || exit 1; \
@@ -3,6 +3,7 @@
# This scripts copied from Amnezia client to Docker container to /opt/amnezia and launched every time container starts
echo "Container startup"
ifconfig eth0:0 $SERVER_IP_ADDRESS netmask 255.255.255.255 up
if [ ! -c /dev/net/tun ]; then mkdir -p /dev/net; mknod /dev/net/tun c 10 200; fi
@@ -12,10 +13,10 @@ iptables -A FORWARD -i tun0 -j ACCEPT
iptables -A OUTPUT -o tun0 -j ACCEPT
# Allow forwarding traffic only from the VPN.
iptables -A FORWARD -i tun0 -o eth0 -s $VPN_SUBNET_IP/$VPN_SUBNET_MASK_VAL -j ACCEPT
iptables -A FORWARD -i tun0 -o eth0 -s $OPENVPN_SUBNET_IP/$OPENVPN_SUBNET_CIDR -j ACCEPT
iptables -A FORWARD -m state --state ESTABLISHED,RELATED -j ACCEPT
iptables -t nat -A POSTROUTING -s $VPN_SUBNET_IP/$VPN_SUBNET_MASK_VAL -o eth0 -j MASQUERADE
iptables -t nat -A POSTROUTING -s $OPENVPN_SUBNET_IP/$OPENVPN_SUBNET_CIDR -o eth0 -j MASQUERADE
# kill daemons in case of restart
killall -KILL openvpn
@@ -24,4 +25,5 @@ killall -KILL ssserver
# start daemons if configured
if [ -f /opt/amnezia/openvpn/ca.crt ]; then (openvpn --config /opt/amnezia/openvpn/server.conf --daemon); fi
if [ -f /opt/amnezia/shadowsocks/ss-config.json ]; then (ssserver -c /opt/amnezia/shadowsocks/ss-config.json &); fi
tail -f /dev/null
@@ -0,0 +1,46 @@
FROM alpine:latest
LABEL maintainer="AmneziaVPN"
#Install required packages
RUN apk add --no-cache curl wireguard-tools dumb-init
RUN apk --update upgrade --no-cache
RUN mkdir -p /opt/amnezia
RUN echo -e "#!/bin/bash\ntail -f /dev/null" > /opt/amnezia/start.sh
RUN chmod a+x /opt/amnezia/start.sh
# Tune network
RUN echo -e " \n\
fs.file-max = 51200 \n\
\n\
net.core.rmem_max = 67108864 \n\
net.core.wmem_max = 67108864 \n\
net.core.netdev_max_backlog = 250000 \n\
net.core.somaxconn = 4096 \n\
\n\
net.ipv4.tcp_syncookies = 1 \n\
net.ipv4.tcp_tw_reuse = 1 \n\
net.ipv4.tcp_tw_recycle = 0 \n\
net.ipv4.tcp_fin_timeout = 30 \n\
net.ipv4.tcp_keepalive_time = 1200 \n\
net.ipv4.ip_local_port_range = 10000 65000 \n\
net.ipv4.tcp_max_syn_backlog = 8192 \n\
net.ipv4.tcp_max_tw_buckets = 5000 \n\
net.ipv4.tcp_fastopen = 3 \n\
net.ipv4.tcp_mem = 25600 51200 102400 \n\
net.ipv4.tcp_rmem = 4096 87380 67108864 \n\
net.ipv4.tcp_wmem = 4096 65536 67108864 \n\
net.ipv4.tcp_mtu_probing = 1 \n\
net.ipv4.tcp_congestion_control = hybla \n\
# for low-latency network, use cubic instead \n\
# net.ipv4.tcp_congestion_control = cubic \n\
" | sed -e 's/^\s\+//g' | tee -a /etc/sysctl.conf && \
mkdir -p /etc/security && \
echo -e " \n\
* soft nofile 51200 \n\
* hard nofile 51200 \n\
" | sed -e 's/^\s\+//g' | tee -a /etc/security/limits.conf
ENTRYPOINT [ "dumb-init", "/opt/amnezia/start.sh" ]
CMD [ "" ]
@@ -0,0 +1,13 @@
# Wireguard config
sudo docker exec -i $CONTAINER_NAME bash -c '\
mkdir -p /opt/amnezia/wireguard; \
cd /opt/amnezia/wireguard || exit 1; \
WIREGUARD_SERVER_PRIVATE_KEY=$(wg genkey) && echo $WIREGUARD_SERVER_PRIVATE_KEY > /opt/amnezia/wireguard/wireguard_server_private_key.key; \
WIREGUARD_SERVER_PUBLIC_KEY=$(echo $WIREGUARD_SERVER_PRIVATE_KEY | wg pubkey) && echo $WIREGUARD_SERVER_PUBLIC_KEY > /opt/amnezia/wireguard/wireguard_server_public_key.key; \
WIREGUARD_PSK=$(wg genpsk) && echo $WIREGUARD_PSK > /opt/amnezia/wireguard/wireguard_psk.key; \
echo -e "\
[Interface]\\n\
PrivateKey = $WIREGUARD_SERVER_PRIVATE_KEY \\n\
Address = $WIREGUARD_SUBNET_IP/$WIREGUARD_SUBNET_CIDR \\n\
ListenPort = $WIREGUARD_SERVER_PORT \\n\
" >/opt/amnezia/wireguard/wg0.conf'
@@ -0,0 +1,15 @@
# Run container
sudo docker run -d \
--restart always \
--privileged \
--cap-add=NET_ADMIN \
--cap-add=SYS_MODULE \
-p $WIREGUARD_SERVER_PORT:$WIREGUARD_SERVER_PORT/udp \
-v /lib/modules:/lib/modules \
--sysctl="net.ipv4.conf.all.src_valid_mark=1" \
--name $CONTAINER_NAME \
$CONTAINER_NAME
# Prevent to route packets outside of the container in case if server behind of the NAT
#sudo docker exec -i $CONTAINER_NAME sh -c "ifconfig eth0:0 $SERVER_IP_ADDRESS netmask 255.255.255.255 up"
+25
View File
@@ -0,0 +1,25 @@
#!/bin/bash
# This scripts copied from Amnezia client to Docker container to /opt/amnezia and launched every time container starts
echo "Container startup"
#ifconfig eth0:0 $SERVER_IP_ADDRESS netmask 255.255.255.255 up
# kill daemons in case of restart
wg-quick down /opt/amnezia/wireguard/wg0.conf
# start daemons if configured
if [ -f /opt/amnezia/wireguard/wg0.conf ]; then (wg-quick up /opt/amnezia/wireguard/wg0.conf); fi
# Allow traffic on the TUN interface.
iptables -A INPUT -i wg0 -j ACCEPT
iptables -A FORWARD -i wg0 -j ACCEPT
iptables -A OUTPUT -o wg0 -j ACCEPT
# Allow forwarding traffic only from the VPN.
iptables -A FORWARD -i wg0 -o eth0 -s $WIREGUARD_SUBNET_IP/$WIREGUARD_SUBNET_MASK_CIDR -j ACCEPT
iptables -A FORWARD -m state --state ESTABLISHED,RELATED -j ACCEPT
iptables -t nat -A POSTROUTING -s $WIREGUARD_SUBNET_IP/$OPENVPN_SUBNET_CIDR -o eth0 -j MASQUERADE
tail -f /dev/null
@@ -0,0 +1,11 @@
[Interface]
Address = 10.8.1.2/32
DNS = 1.1.1.1, 1.0.0.1
PrivateKey = $WIREGUARD_CLIENT_PRIVATE_KEY
[Peer]
PublicKey = $WIREGUARD_SERVER_PUBLIC_KEY
PresharedKey = $WIREGUARD_PSK
AllowedIPs = 0.0.0.0/0, ::/0
Endpoint = $SERVER_IP_ADDRESS:$WIREGUARD_SERVER_PORT
PersistentKeepalive = 25
+113
View File
@@ -1,5 +1,6 @@
#include "defines.h"
#include "settings.h"
#include "utils.h"
#include <QDebug>
#include "protocols/protocols_defs.h"
@@ -205,6 +206,118 @@ QString Settings::nextAvailableServerName() const
return tr("Server") + " " + QString::number(i);
}
QString Settings::routeModeString(RouteMode mode) const
{
switch (mode) {
case VpnAllSites:
return "AllSites";
case VpnOnlyForwardSites:
return "ForwardSites";
case VpnAllExceptSites:
return "ExceptSites";
}
}
void Settings::addVpnSite(RouteMode mode, const QString &site, const QString &ip)
{
QVariantMap sites = vpnSites(mode);
if (sites.contains(site) && ip.isEmpty()) return;
sites.insert(site, ip);
setVpnSites(mode, sites);
}
QStringList Settings::getVpnIps(RouteMode mode) const
{
QStringList ips;
const QVariantMap &m = vpnSites(mode);
for (auto i = m.constBegin(); i != m.constEnd(); ++i) {
if (Utils::checkIpSubnetFormat(i.key())) {
ips.append(i.key());
}
else if (Utils::checkIpSubnetFormat(i.value().toString())) {
ips.append(i.value().toString());
}
}
ips.removeDuplicates();
return ips;
}
void Settings::removeVpnSite(RouteMode mode, const QString &site)
{
QVariantMap sites = vpnSites(mode);
if (!sites.contains(site)) return;
sites.remove(site);
setVpnSites(mode, sites);
}
void Settings::addVpnIps(RouteMode mode, const QStringList &ips)
{
QVariantMap sites = vpnSites(mode);
for (const QString &ip : ips) {
if (ip.isEmpty()) continue;
sites.insert(ip, "");
}
setVpnSites(mode, sites);
}
void Settings::removeVpnSites(RouteMode mode, const QStringList &sites)
{
QVariantMap sitesMap = vpnSites(mode);
for (const QString &site : sites) {
if (site.isEmpty()) continue;
sitesMap.remove(site);
}
setVpnSites(mode, sitesMap);
}
//void Settings::addVpnForwardSite(const QString &site, const QString &ip)
//{
// auto sites = vpnForwardSites();
// QStringList l = sites.value(site).toStringList();
// if (!l.contains(ip)) {
// l.append(ip);
// setVpnForwardSites(sites);
// }
//}
//QStringList Settings::getVpnForwardIps() const
//{
// QStringList ips;
// const QVariantMap &m = vpnForwardSites();
// for (const QVariant &v : m) {
// ips.append(v.toStringList());
// }
// ips.removeDuplicates();
// return ips;
//}
//void Settings::addVpnExceptSite(const QString &site, const QString &ip)
//{
// auto sites = vpnExceptSites();
// QStringList l = sites.value(site).toStringList();
// if (!l.contains(ip)) {
// l.append(ip);
// setVpnExceptSites(sites);
// }
//}
//QStringList Settings::getVpnExceptIps() const
//{
// QStringList ips;
// const QVariantMap &m = vpnExceptSites();
// for (const QVariant &v : m) {
// ips.append(v.toStringList());
// }
// ips.removeDuplicates();
// return ips;
//}
QString Settings::primaryDns() const { return m_settings.value("Conf/primaryDns", cloudFlareNs1).toString(); }
QString Settings::secondaryDns() const { return m_settings.value("Conf/secondaryDns", cloudFlareNs2).toString(); }
+25 -24
View File
@@ -23,19 +23,6 @@ class Settings : public QObject
public:
explicit Settings(QObject* parent = nullptr);
// QString userName() const { return m_settings.value("Server/userName", QString()).toString(); }
// void setUserName(const QString& login) { m_settings.setValue("Server/userName", login); }
// QString password() const { return m_settings.value("Server/password", QString()).toString(); }
// void setPassword(const QString& password) { m_settings.setValue("Server/password", password); }
// QString serverName() const { return m_settings.value("Server/serverName", QString()).toString(); }
// void setServerName(const QString& serverName) { m_settings.setValue("Server/serverName", serverName); }
// int serverPort() const { return m_settings.value("Server/serverPort", 22).toInt(); }
// void setServerPort(int serverPort = 22) { m_settings.setValue("Server/serverPort", serverPort); }
ServerCredentials defaultServerCredentials() const;
ServerCredentials serverCredentials(int index) const;
//void setServerCredentials(const ServerCredentials &credentials);
@@ -74,19 +61,33 @@ public:
QString nextAvailableServerName() const;
// App settings section
bool isAutoConnect() const { return m_settings.value("Conf/autoConnect", QString()).toBool(); }
bool isAutoConnect() const { return m_settings.value("Conf/autoConnect", false).toBool(); }
void setAutoConnect(bool enabled) { m_settings.setValue("Conf/autoConnect", enabled); }
bool customRouting() const { return m_settings.value("Conf/customRouting", false).toBool(); }
void setCustomRouting(bool customRouting) { m_settings.setValue("Conf/customRouting", customRouting); }
bool isStartMinimized() const { return m_settings.value("Conf/startMinimized", false).toBool(); }
void setStartMinimized(bool enabled) { m_settings.setValue("Conf/startMinimized", enabled); }
// list of sites to pass blocking added by user
QStringList customSites() { return m_settings.value("Conf/customSites").toStringList(); }
void setCustomSites(const QStringList &customSites) { m_settings.setValue("Conf/customSites", customSites); }
enum RouteMode {
VpnAllSites,
VpnOnlyForwardSites,
VpnAllExceptSites
};
Q_ENUM (RouteMode)
QString routeModeString(RouteMode mode) const;
RouteMode routeMode() const { return static_cast<RouteMode>(m_settings.value("Conf/routeMode", 0).toInt()); }
void setRouteMode(RouteMode mode) { m_settings.setValue("Conf/routeMode", mode); }
QVariantMap vpnSites(RouteMode mode) const { return m_settings.value("Conf/" + routeModeString(mode)).toMap(); }
void setVpnSites(RouteMode mode, const QVariantMap &sites) { m_settings.setValue("Conf/"+ routeModeString(mode), sites); m_settings.sync(); }
void addVpnSite(RouteMode mode, const QString &site, const QString &ip= "");
QStringList getVpnIps(RouteMode mode) const;
void removeVpnSite(RouteMode mode, const QString &site);
void addVpnIps(RouteMode mode, const QStringList &ip);
void removeVpnSites(RouteMode mode, const QStringList &sites);
// list of ips to pass blocking generated from customSites
QStringList customIps() { return m_settings.value("Conf/customIps").toStringList(); }
void setCustomIps(const QStringList &customIps) { m_settings.setValue("Conf/customIps", customIps); }
QString primaryDns() const;
QString secondaryDns() const;
@@ -100,8 +101,8 @@ public:
static const char cloudFlareNs1[];
static const char cloudFlareNs2[];
static constexpr char openNicNs5[] = "94.103.153.176";
static constexpr char openNicNs13[] = "144.76.103.143";
// static constexpr char openNicNs5[] = "94.103.153.176";
// static constexpr char openNicNs13[] = "144.76.103.143";
public:
Binary file not shown.
File diff suppressed because it is too large Load Diff
@@ -121,6 +121,8 @@ void SlidingStackedWidget::slideInWgtImpl(QWidget * newwidget, enum t_direction
}
else m_active = true;
m_nextWidget = newwidget;
enum t_direction directionhint;
int now = currentIndex(); // currentIndex() is a function inherited from QStackedWidget
int next = indexOf(newwidget);
@@ -209,6 +211,18 @@ void SlidingStackedWidget::slideInWgtImpl(QWidget * newwidget, enum t_direction
// that we implement here below in animationDoneSlot.
}
void SlidingStackedWidget::setCurrentWidget(QWidget *w)
{
m_nextWidget = w;
QStackedWidget::setCurrentWidget(w);
}
QWidget *SlidingStackedWidget::nextWidget() const
{
if (m_nextWidget == nullptr) return currentWidget();
return m_nextWidget;
}
void SlidingStackedWidget::animationDoneSlot(void) {
// when ready, call the QStackedWidget slot setCurrentIndex(int)
setCurrentIndex(m_next); // this function is inherited from QStackedWidget
@@ -34,6 +34,9 @@ public:
SlidingStackedWidget(QWidget *parent);
~SlidingStackedWidget(void);
QWidget *nextWidget() const;
void setCurrentWidget(QWidget *w);
public slots:
// Some basic settings API
void setSpeed(int speed); // animation duration in milliseconds
@@ -77,6 +80,8 @@ protected:
QPropertyAnimation *animnow;
QPropertyAnimation *animnext;
QParallelAnimationGroup *animgroup;
QWidget *m_nextWidget = nullptr;
};
#endif // SLIDINGSTACKEDWIDGET_H
+697 -304
View File
File diff suppressed because it is too large Load Diff
+25 -8
View File
@@ -17,6 +17,7 @@
#include "protocols/vpnprotocol.h"
#include "settings.h"
#include "sites_model.h"
class VpnConnection;
@@ -40,11 +41,15 @@ public:
explicit MainWindow(QWidget *parent = nullptr);
~MainWindow();
enum Page {Start, NewServer, NewServer_2, Vpn, GeneralSettings, AppSettings, NetworkSettings,
ServerSettings, ServerVpnProtocols, ServersList, ShareConnection, Sites,
enum Page {Start, NewServer, NewServerProtocols, Vpn,
Wizard, WizardLow, WizardMedium, WizardHigh, WizardVpnMode, ServerConfiguring,
GeneralSettings, AppSettings, NetworkSettings, ServerSettings,
ServerVpnProtocols, ServersList, ShareConnection, Sites,
OpenVpnSettings, ShadowSocksSettings, CloakSettings};
Q_ENUM(Page)
void showOnStartup();
private slots:
void onBytesChanged(quint64 receivedBytes, quint64 sentBytes);
void onConnectionStateChanged(VpnProtocol::ConnectionState state);
@@ -52,14 +57,13 @@ private slots:
void onPushButtonConnectClicked(bool checked);
void onPushButtonNewServerConnect(bool);
void onPushButtonNewServerConnectConfigure(bool);
void installServer(const QMap<DockerContainer, QJsonObject> &containers);
void onPushButtonNewServerImport(bool);
void onPushButtonClearServer(bool);
void onPushButtonForgetServer(bool);
void onPushButtonAddCustomSitesClicked();
void onPushButtonDeleteCustomSiteClicked(const QString &siteToDelete);
void onTrayActionConnect(); // connect from context menu
void setTrayState(VpnProtocol::ConnectionState state);
@@ -79,7 +83,7 @@ private:
QWidget *getPageWidget(Page page);
Page currentPage();
bool installServer(ServerCredentials credentials, QList<DockerContainer> containers, QJsonArray configs,
bool installContainers(ServerCredentials credentials, const QMap<DockerContainer, QJsonObject> &containers,
QWidget *page, QProgressBar *progress, QPushButton *button, QLabel *info);
ErrorCode doInstallAction(const std::function<ErrorCode()> &action, QWidget *page, QProgressBar *progress, QPushButton *button, QLabel *info);
@@ -88,6 +92,13 @@ private:
void setTrayIcon(const QString &iconPath);
void setupUiConnections();
void setupNewServerConnections();
void setupWizardConnections();
void setupVpnPageConnections();
void setupSitesPageConnections();
void setupAppSettingsConnections();
void setupGeneralSettingsConnections();
void setupNetworkSettingsConnections();
void setupProtocolsPageConnections();
void setupNewServerPageConnections();
void setupServerSettingsPageConnections();
@@ -97,10 +108,10 @@ private:
void updateSitesPage();
void updateVpnPage();
void updateAppSettingsPage();
void updateGeneralSettingPage();
void updateServerPage();
void updateServersListPage();
void updateProtocolsPage();
void updateShareCodePage();
void updateOpenVpnPage(const QJsonObject &openvpnConfig, DockerContainer container, bool haveAuthData);
void updateShadowSocksPage(const QJsonObject &ssConfig, DockerContainer container, bool haveAuthData);
void updateCloakPage(const QJsonObject &ckConfig, DockerContainer container, bool haveAuthData);
@@ -108,7 +119,6 @@ private:
void updateSharingPage(int serverIndex, const ServerCredentials &credentials,
DockerContainer container);
void makeSitesListItem(QListWidget* listWidget, const QString &address);
void makeServersListItem(QListWidget* listWidget, const QJsonObject &server, bool isDefault, int index);
void updateQRCodeImage(const QString &text, QLabel *label);
@@ -117,11 +127,16 @@ private:
QJsonObject getShadowSocksConfigFromPage(QJsonObject oldConfig);
QJsonObject getCloakConfigFromPage(QJsonObject oldConfig);
QMap<DockerContainer, QJsonObject> getInstallConfigsFromProtocolsPage() const;
QMap<DockerContainer, QJsonObject> getInstallConfigsFromWizardPage() const;
private:
Ui::MainWindow *ui;
VpnConnection* m_vpnConnection;
Settings m_settings;
QMap<Settings::RouteMode, SitesModel *> sitesModels;
QAction* m_trayActionConnect;
QAction* m_trayActionDisconnect;
@@ -137,6 +152,8 @@ private:
bool canMove = false;
QPoint offset;
bool needToHideCustomTitlebar = false;
bool eventFilter(QObject *obj, QEvent *event) override;
void keyPressEvent(QKeyEvent* event) override;
void closeEvent(QCloseEvent *event) override;
@@ -151,7 +168,7 @@ private:
QStack<Page> pagesStack;
int selectedServerIndex = -1; // server index to use when proto settings page opened
DockerContainer selectedDockerContainer; // same
ServerCredentials installCredentials; // used to save cred between pages new_server and new_server_2
ServerCredentials installCredentials; // used to save cred between pages new_server and new_server_protocols and wizard
};
#endif // MAINWINDOW_H
+2136 -320
View File
File diff suppressed because it is too large Load Diff
+72
View File
@@ -0,0 +1,72 @@
#include "sites_model.h"
SitesModel::SitesModel(Settings::RouteMode mode, QObject *parent)
: m_mode(mode),
QAbstractTableModel(parent)
{
}
void SitesModel::resetCache()
{
beginResetModel();
m_ipsCache.clear();
m_cacheReady = false;
endResetModel();
}
QVariant SitesModel::headerData(int section, Qt::Orientation orientation, int role) const
{
// FIXME: Implement me!
return QVariant();
}
int SitesModel::rowCount(const QModelIndex &parent) const
{
if (!m_cacheReady) genCache();
return m_ipsCache.size();
}
int SitesModel::columnCount(const QModelIndex &parent) const
{
return 2;
}
QVariant SitesModel::data(const QModelIndex &index, int role) const
{
if (!index.isValid())
return QVariant();
if (!m_cacheReady) genCache();
if (role == Qt::DisplayRole){
if (m_ipsCache.isEmpty()) return QVariant();
if (index.column() == 0) {
return m_ipsCache.at(index.row()).first;
}
if (index.column() == 1) {
return m_ipsCache.at(index.row()).second;
}
}
// if (role == Qt::TextAlignmentRole && index.column() == 1) {
// return Qt::AlignRight;
// }
return QVariant();
}
void SitesModel::genCache() const
{
qDebug() << "SitesModel::genCache";
m_ipsCache.clear();
const QVariantMap &sites = m_settings.vpnSites(m_mode);
auto i = sites.constBegin();
while (i != sites.constEnd()) {
m_ipsCache.append(qMakePair(i.key(), i.value().toString()));
++i;
}
m_cacheReady= true;
}
+36
View File
@@ -0,0 +1,36 @@
#ifndef SITESMODEL_H
#define SITESMODEL_H
#include <QAbstractTableModel>
#include "settings.h"
class SitesModel : public QAbstractTableModel
{
Q_OBJECT
public:
explicit SitesModel(Settings::RouteMode mode, QObject *parent = nullptr);
void resetCache();
// Header:
QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const override;
// Basic functionality:
int rowCount(const QModelIndex &parent = QModelIndex()) const override;
int columnCount(const QModelIndex &parent = QModelIndex()) const override;
QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;
private:
void genCache() const;
private:
Settings::RouteMode m_mode;
Settings m_settings;
mutable QVector<QPair<QString, QString>> m_ipsCache;
mutable bool m_cacheReady = false;
};
#endif // SITESMODEL_H
+58 -20
View File
@@ -23,11 +23,6 @@ QString Utils::getRandomString(int len)
return randomString;
}
QString Utils::defaultVpnConfigFileName()
{
return configPath() + QString("/%1.ovpn").arg(APPLICATION_NAME);
}
QString Utils::systemLogPath()
{
#ifdef Q_OS_WIN
@@ -54,11 +49,6 @@ bool Utils::initializePath(const QString& path)
return true;
}
QString Utils::configPath()
{
return QStandardPaths::writableLocation(QStandardPaths::AppDataLocation) + "/config";
}
bool Utils::createEmptyFile(const QString& path)
{
QFile f(path);
@@ -139,19 +129,27 @@ QString Utils::getStringBetween(const QString& s, const QString& a, const QStrin
return s.mid(ap, bp - ap).trimmed();
}
bool Utils::checkIPFormat(const QString& ip)
bool Utils::checkIPv4Format(const QString& ip)
{
if (ip.isEmpty()) return false;
int count = ip.count(".");
if(count != 3)
return false;
if(count != 3) return false;
QStringList list = ip.trimmed().split(".");
foreach(QString it, list) {
if(it.toInt() <= 255 && it.toInt() >= 0)
continue;
return false;
}
return true;
QHostAddress addr(ip);
return (addr.protocol() == QAbstractSocket::NetworkLayerProtocol::IPv4Protocol);
}
bool Utils::checkIpSubnetFormat(const QString &ip)
{
if (!ip.contains("/")) return checkIPv4Format(ip);
QStringList parts = ip.split("/");
if (parts.size() != 2) return false;
bool ok;
int subnet = parts.at(1).toInt(&ok);
if (subnet >= 0 && subnet <= 32 && ok) return checkIPv4Format(parts.at(0));
else return false;
}
void Utils::killProcessByName(const QString &name)
@@ -164,6 +162,46 @@ void Utils::killProcessByName(const QString &name)
#endif
}
QString Utils::netMaskFromIpWithSubnet(const QString ip)
{
if (!ip.contains("/")) return "255.255.255.255";
bool ok;
int prefix = ip.split("/").at(1).toInt(&ok);
if (!ok) return "255.255.255.255";
unsigned long mask = (0xFFFFFFFF << (32 - prefix)) & 0xFFFFFFFF;
return QString("%1.%2.%3.%4")
.arg(mask >> 24)
.arg((mask >> 16) & 0xFF)
.arg((mask >> 8) & 0xFF)
.arg( mask & 0xFF);
}
QString Utils::ipAddressFromIpWithSubnet(const QString ip)
{
if (ip.count(".") != 3) return "";
return ip.split("/").first();
}
QStringList Utils::summarizeRoutes(const QStringList &ips, const QString cidr)
{
// QMap<int, int>
// QHostAddress
// QMap<QString, QStringList> subnets; // <"a.b", <list subnets>>
// for (const QString &ip : ips) {
// if (ip.count(".") != 3) continue;
// const QStringList &parts = ip.split(".");
// subnets[parts.at(0) + "." + parts.at(1)].append(ip);
// }
return QStringList();
}
#ifdef Q_OS_WIN
// Inspired from http://stackoverflow.com/a/15281070/1529139
// and http://stackoverflow.com/q/40059902/1529139
+10 -3
View File
@@ -13,8 +13,6 @@ class Utils {
public:
static QString getRandomString(int len);
static QString configPath();
static QString defaultVpnConfigFileName();
static QString executable(const QString& baseName, bool absPath);
static QString systemLogPath();
static bool createEmptyFile(const QString& path);
@@ -22,11 +20,15 @@ public:
static QString getIPAddress(const QString& host);
static QString getStringBetween(const QString& s, const QString& a, const QString& b);
static bool checkIPFormat(const QString& ip);
static bool checkIPv4Format(const QString& ip);
static bool checkIpSubnetFormat(const QString& ip);
static QRegExp ipAddressRegExp() { return QRegExp("^((25[0-5]|(2[0-4]|1[0-9]|[1-9]|)[0-9])(\\.(?!$)|$)){4}$"); }
static QRegExp ipAddressPortRegExp() { return QRegExp("^(?:(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])\\.){3}"
"(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])(\\:[0-9]{1,5}){0,1}$"); }
static QRegExp ipAddressWithSubnetRegExp() { return QRegExp("(?:(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])\\.){3}"
"(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])(\\/[0-9]{1,2}){0,1}"); }
static QRegExp ipNetwork24RegExp() { return QRegExp("^(?:(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])\\.){3}"
"0$"); }
@@ -35,6 +37,11 @@ public:
static bool processIsRunning(const QString& fileName);
static void killProcessByName(const QString &name);
static QString netMaskFromIpWithSubnet(const QString ip);
static QString ipAddressFromIpWithSubnet(const QString ip);
static QStringList summarizeRoutes(const QStringList &ips, const QString cidr);
#ifdef Q_OS_WIN
static bool signalCtrl(DWORD dwProcessId, DWORD dwCtrlEvent);
#endif
+102 -28
View File
@@ -6,7 +6,9 @@
#include <configurators/openvpn_configurator.h>
#include <configurators/cloak_configurator.h>
#include <configurators/shadowsocks_configurator.h>
#include <configurators/wireguard_configurator.h>
#include <core/servercontroller.h>
#include <protocols/wireguardprotocol.h>
#include "ipc.h"
#include "core/ipcclient.h"
@@ -40,25 +42,33 @@ void VpnConnection::onBytesChanged(quint64 receivedBytes, quint64 sentBytes)
void VpnConnection::onConnectionStateChanged(VpnProtocol::ConnectionState state)
{
if (IpcClient::Interface()) {
if (state == VpnProtocol::ConnectionState::Connected && IpcClient::Interface()){
if (state == VpnProtocol::Connected){
IpcClient::Interface()->flushDns();
if (m_settings.customRouting()) {
IpcClient::Interface()->routeDelete("0.0.0.0", m_vpnProtocol->vpnGateway());
IpcClient::Interface()->routeAddList(m_vpnProtocol->vpnGateway(),
QStringList() << m_settings.primaryDns() << m_settings.secondaryDns());
const QStringList &black_custom = m_settings.customIps();
qDebug() << "VpnConnection::onConnectionStateChanged :: adding custom routes, count:" << black_custom.size();
IpcClient::Interface()->routeAddList(m_vpnProtocol->vpnGateway(), black_custom);
if (m_settings.routeMode() != Settings::VpnAllSites) {
IpcClient::Interface()->routeDeleteList(m_vpnProtocol->vpnGateway(), QStringList() << "0.0.0.0");
//qDebug() << "VpnConnection::onConnectionStateChanged :: adding custom routes, count:" << forwardIps.size();
}
IpcClient::Interface()->routeAddList(m_vpnProtocol->vpnGateway(),
QStringList() << m_settings.primaryDns() << m_settings.secondaryDns());
if (m_settings.routeMode() == Settings::VpnOnlyForwardSites) {
IpcClient::Interface()->routeAddList(m_vpnProtocol->vpnGateway(), m_settings.getVpnIps(Settings::VpnOnlyForwardSites));
}
else if (m_settings.routeMode() == Settings::VpnAllExceptSites) {
IpcClient::Interface()->routeAddList(m_vpnProtocol->vpnGateway(), QStringList() << "0.0.0.0/1");
IpcClient::Interface()->routeAddList(m_vpnProtocol->vpnGateway(), QStringList() << "128.0.0.0/1");
IpcClient::Interface()->routeAddList(m_vpnProtocol->routeGateway(), QStringList() << remoteAddress());
IpcClient::Interface()->routeAddList(m_vpnProtocol->routeGateway(), m_settings.getVpnIps(Settings::VpnAllExceptSites));
}
}
else if (state == VpnProtocol::ConnectionState::Error) {
else if (state == VpnProtocol::Error) {
IpcClient::Interface()->flushDns();
if (m_settings.customRouting()) {
if (m_settings.routeMode() == Settings::VpnOnlyForwardSites) {
IpcClient::Interface()->clearSavedRoutes();
}
}
@@ -67,11 +77,45 @@ void VpnConnection::onConnectionStateChanged(VpnProtocol::ConnectionState state)
emit connectionStateChanged(state);
}
const QString &VpnConnection::remoteAddress() const
{
return m_remoteAddress;
}
QSharedPointer<VpnProtocol> VpnConnection::vpnProtocol() const
{
return m_vpnProtocol;
}
void VpnConnection::addRoutes(const QStringList &ips)
{
if (connectionState() == VpnProtocol::Connected && IpcClient::Interface()) {
if (m_settings.routeMode() == Settings::VpnOnlyForwardSites) {
IpcClient::Interface()->routeAddList(m_vpnProtocol->vpnGateway(), ips);
}
else if (m_settings.routeMode() == Settings::VpnAllExceptSites) {
IpcClient::Interface()->routeAddList(m_vpnProtocol->routeGateway(), ips);
}
}
}
void VpnConnection::deleteRoutes(const QStringList &ips)
{
if (connectionState() == VpnProtocol::Connected && IpcClient::Interface()) {
if (m_settings.routeMode() == Settings::VpnOnlyForwardSites) {
IpcClient::Interface()->routeDeleteList(vpnProtocol()->vpnGateway(), ips);
}
else if (m_settings.routeMode() == Settings::VpnAllExceptSites) {
IpcClient::Interface()->routeDeleteList(m_vpnProtocol->routeGateway(), ips);
}
}
}
void VpnConnection::flushDns()
{
if (IpcClient::Interface()) IpcClient::Interface()->flushDns();
}
ErrorCode VpnConnection::lastError() const
{
if (!m_vpnProtocol.data()) {
@@ -105,7 +149,10 @@ QString VpnConnection::createVpnConfigurationForProto(int serverIndex,
QString configData;
if (lastVpnConfig.contains(proto)) {
configData = OpenVpnConfigurator::processConfigWithLocalSettings(lastVpnConfig.value(proto));
configData = lastVpnConfig.value(proto);
if (proto == Protocol::OpenVpn) {
configData = OpenVpnConfigurator::processConfigWithLocalSettings(configData);
}
qDebug() << "VpnConnection::createVpnConfiguration: using saved config for" << protoToString(proto);
}
else {
@@ -113,6 +160,7 @@ QString VpnConnection::createVpnConfigurationForProto(int serverIndex,
if (proto == Protocol::OpenVpn) {
configData = OpenVpnConfigurator::genOpenVpnConfig(credentials,
container, containerConfig, &e);
configData = OpenVpnConfigurator::processConfigWithLocalSettings(configData);
}
else if (proto == Protocol::Cloak) {
configData = CloakConfigurator::genCloakConfig(credentials,
@@ -122,6 +170,10 @@ QString VpnConnection::createVpnConfigurationForProto(int serverIndex,
configData = ShadowSocksConfigurator::genShadowSocksConfig(credentials,
container, containerConfig, &e);
}
else if (proto == Protocol::WireGuard) {
configData = WireguardConfigurator::genWireguardConfig(credentials,
container, containerConfig, &e);
}
if (errorCode && e) {
*errorCode = e;
@@ -160,7 +212,7 @@ ErrorCode VpnConnection::createVpnConfiguration(int serverIndex,
return errorCode;
}
QFile file(Utils::defaultVpnConfigFileName());
QFile file(OpenVpnProtocol::defaultConfigFileName());
if (file.open(QIODevice::WriteOnly | QIODevice::Truncate)){
QTextStream stream(&file);
stream << openVpnConfigData << endl;
@@ -189,17 +241,29 @@ ErrorCode VpnConnection::createVpnConfiguration(int serverIndex,
m_vpnConfiguration.insert(config::key_cloak_config_data, cloakConfigData);
}
if (container == DockerContainer::WireGuard) {
QString wgConfigData = createVpnConfigurationForProto(
serverIndex, credentials, container, containerConfig, Protocol::WireGuard, &errorCode);
m_vpnConfiguration.insert(config::key_wireguard_config_data, wgConfigData);
}
//qDebug().noquote() << "VPN config" << QJsonDocument(m_vpnConfiguration).toJson();
return ErrorCode::NoError;
}
ErrorCode VpnConnection::connectToVpn(int serverIndex, const ServerCredentials &credentials, DockerContainer container, const QJsonObject &containerConfig)
ErrorCode VpnConnection::connectToVpn(int serverIndex,
const ServerCredentials &credentials, DockerContainer container, const QJsonObject &containerConfig)
{
qDebug() << "СonnectToVpn, CustomRouting is" << m_settings.customRouting();
qDebug() << QString("СonnectToVpn, Server index is %1, container is %2, route mode is")
.arg(serverIndex).arg(containerToString(container)) << m_settings.routeMode();
m_remoteAddress = credentials.hostName;
emit connectionStateChanged(VpnProtocol::ConnectionState::Connecting);
emit connectionStateChanged(VpnProtocol::Connecting);
ServerController::setupServerFirewall(credentials);
if (credentials.isValid()) {
ServerController::setupServerFirewall(credentials);
}
if (m_vpnProtocol) {
disconnect(m_vpnProtocol.data(), &VpnProtocol::protocolError, this, &VpnConnection::vpnProtocolError);
@@ -210,45 +274,54 @@ ErrorCode VpnConnection::connectToVpn(int serverIndex, const ServerCredentials &
if (container == DockerContainer::None || container == DockerContainer::OpenVpn) {
ErrorCode e = createVpnConfiguration(serverIndex, credentials, DockerContainer::OpenVpn, containerConfig);
if (e) {
emit connectionStateChanged(VpnProtocol::ConnectionState::Error);
emit connectionStateChanged(VpnProtocol::Error);
return e;
}
m_vpnProtocol.reset(new OpenVpnProtocol(m_vpnConfiguration));
e = static_cast<OpenVpnProtocol *>(m_vpnProtocol.data())->checkAndSetupTapDriver();
if (e) {
emit connectionStateChanged(VpnProtocol::ConnectionState::Error);
emit connectionStateChanged(VpnProtocol::Error);
return e;
}
}
else if (container == DockerContainer::OpenVpnOverShadowSocks) {
ErrorCode e = createVpnConfiguration(serverIndex, credentials, DockerContainer::OpenVpnOverShadowSocks, containerConfig);
if (e) {
emit connectionStateChanged(VpnProtocol::ConnectionState::Error);
emit connectionStateChanged(VpnProtocol::Error);
return e;
}
m_vpnProtocol.reset(new ShadowSocksVpnProtocol(m_vpnConfiguration));
e = static_cast<OpenVpnProtocol *>(m_vpnProtocol.data())->checkAndSetupTapDriver();
if (e) {
emit connectionStateChanged(VpnProtocol::ConnectionState::Error);
emit connectionStateChanged(VpnProtocol::Error);
return e;
}
}
else if (container == DockerContainer::OpenVpnOverCloak) {
ErrorCode e = createVpnConfiguration(serverIndex, credentials, DockerContainer::OpenVpnOverCloak, containerConfig);
if (e) {
emit connectionStateChanged(VpnProtocol::ConnectionState::Error);
emit connectionStateChanged(VpnProtocol::Error);
return e;
}
m_vpnProtocol.reset(new OpenVpnOverCloakProtocol(m_vpnConfiguration));
e = static_cast<OpenVpnProtocol *>(m_vpnProtocol.data())->checkAndSetupTapDriver();
if (e) {
emit connectionStateChanged(VpnProtocol::ConnectionState::Error);
emit connectionStateChanged(VpnProtocol::Error);
return e;
}
}
else if (container == DockerContainer::WireGuard) {
ErrorCode e = createVpnConfiguration(serverIndex, credentials, DockerContainer::WireGuard, containerConfig);
if (e) {
emit connectionStateChanged(VpnProtocol::Error);
return e;
}
m_vpnProtocol.reset(new WireguardProtocol(m_vpnConfiguration));
}
connect(m_vpnProtocol.data(), &VpnProtocol::protocolError, this, &VpnConnection::vpnProtocolError);
connect(m_vpnProtocol.data(), SIGNAL(connectionStateChanged(VpnProtocol::ConnectionState)), this, SLOT(onConnectionStateChanged(VpnProtocol::ConnectionState)));
@@ -269,9 +342,10 @@ void VpnConnection::disconnectFromVpn()
{
qDebug() << "Disconnect from VPN";
IpcClient::Interface()->flushDns();
if (IpcClient::Interface()) {
IpcClient::Interface()->flushDns();
if (m_settings.customRouting()) {
// delete cached routes
IpcClient::Interface()->clearSavedRoutes();
}
@@ -283,7 +357,7 @@ void VpnConnection::disconnectFromVpn()
VpnProtocol::ConnectionState VpnConnection::connectionState()
{
if (!m_vpnProtocol) return VpnProtocol::ConnectionState::Disconnected;
if (!m_vpnProtocol) return VpnProtocol::Disconnected;
return m_vpnProtocol->connectionState();
}
+11 -2
View File
@@ -33,16 +33,23 @@ public:
ErrorCode createVpnConfiguration(int serverIndex,
const ServerCredentials &credentials, DockerContainer container, const QJsonObject &containerConfig);
ErrorCode connectToVpn(int serverIndex, const ServerCredentials &credentials, DockerContainer container, const QJsonObject &containerConfig);
ErrorCode connectToVpn(int serverIndex,
const ServerCredentials &credentials, DockerContainer container, const QJsonObject &containerConfig);
void disconnectFromVpn();
bool isConnected() const;
bool isDisconnected() const;
VpnProtocol::ConnectionState connectionState();
QSharedPointer<VpnProtocol> vpnProtocol() const;
void addRoutes(const QStringList &ips);
void deleteRoutes(const QStringList &ips);
void flushDns();
const QString &remoteAddress() const;
signals:
void bytesChanged(quint64 receivedBytes, quint64 sentBytes);
void connectionStateChanged(VpnProtocol::ConnectionState state);
@@ -60,6 +67,8 @@ protected:
private:
Settings m_settings;
QJsonObject m_vpnConfiguration;
QJsonObject m_routeMode;
QString m_remoteAddress;
};
+6 -4
View File
@@ -28,10 +28,12 @@ QMAKE_STASH_FILE=$PROJECT_DIR/.qmake_stash
DMG_FILENAME=$PROJECT_DIR/${APP_NAME}_unsigned.dmg
# Seacrh Qt
if [ -z "${QT_VERSION+x}" ]; then export QT_VERSION=5.15.2; fi
if [ -z "${QT_VERSION+x}" ]; then
QT_VERSION=5.15.2;
QIF_VERSION=4.1
QT_BIN_DIR=$HOME/Qt/$QT_VERSION/clang_64/bin
QIF_BIN_DIR=$QT_BIN_DIR/../../../Tools/QtInstallerFramework/4.0/bin
QIF_BIN_DIR=$QT_BIN_DIR/../../../Tools/QtInstallerFramework/$QIF_VERSION/bin
fi
echo "Using Qt in $QT_BIN_DIR"
echo "Using QIF in $QIF_BIN_DIR"
@@ -115,7 +117,7 @@ if [ "${MAC_CERT_PW+x}" ]; then
/usr/bin/codesign --deep --force --verbose --timestamp -o runtime --sign "Developer ID Application: Privacy Technologies OU (X7UJ388FXK)" $DMG_FILENAME
/usr/bin/codesign --verify -vvvv $DMG_FILENAME || true
spctl -a -vvvv $DMG_FILENAME || true
#xcrun altool --notarize-app -f $DMG_FILENAME -t osx --primary-bundle-id $APP_DOMAIN -u $APPLE_DEV_EMAIL
#xcrun altool --notarize-app -f $DMG_FILENAME -t osx --primary-bundle-id $APP_DOMAIN -u $APPLE_DEV_EMAIL -p $APPLE_DEV_PASSWORD
#xcrun stapler staple $DMG_FILENAME
#xcrun stapler validate $DMG_FILENAME
fi
+160
View File
@@ -0,0 +1,160 @@
#!/bin/bash
echo "Build script started ..."
set -o errexit -o nounset
# Hold on to current directory
PROJECT_DIR=$(pwd)
DEPLOY_DIR=$PROJECT_DIR/deploy
mkdir -p $DEPLOY_DIR/build
BUILD_DIR=$DEPLOY_DIR/build
echo "Project dir: ${PROJECT_DIR}"
echo "Build dir: ${BUILD_DIR}"
APP_NAME=AmneziaVPN
APP_FILENAME=$APP_NAME.app
APP_DOMAIN=org.amneziavpn.package
PLIST_NAME=$APP_NAME.plist
OUT_APP_DIR=$BUILD_DIR/client
BUNDLE_DIR=$OUT_APP_DIR/$APP_FILENAME
DEPLOY_DATA_DIR=$PROJECT_DIR/deploy/data/macos
INSTALLER_DATA_DIR=$BUILD_DIR/installer/packages/$APP_DOMAIN/data
INSTALLER_BUNDLE_DIR=$BUILD_DIR/installer/$APP_FILENAME
PRO_FILE_PATH=$PROJECT_DIR/$APP_NAME.pro
QMAKE_STASH_FILE=$PROJECT_DIR/.qmake_stash
DMG_FILENAME=$PROJECT_DIR/${APP_NAME}_unsigned.dmg
# Seacrh Qt
if [ -z "${QT_VERSION+x}" ]; then
QT_VERSION=5.15.2;
QIF_VERSION=4.1
QT_BIN_DIR=$HOME/Qt/$QT_VERSION/clang_64/bin
QIF_BIN_DIR=$QT_BIN_DIR/../../../Tools/QtInstallerFramework/$QIF_VERSION/bin
fi
echo "Using Qt in $QT_BIN_DIR"
echo "Using QIF in $QIF_BIN_DIR"
# Checking env
$QT_BIN_DIR/qmake -v
make -v
clang -v
# Build App
echo "Building App..."
cd $BUILD_DIR
$QT_BIN_DIR/qmake $PROJECT_DIR/AmneziaVPN.pro 'CONFIG+=release CONFIG+=x86_64'
make -j `sysctl -n hw.ncpu`
# Build and run tests here
echo "____________________________________"
echo "............Deploy.................."
echo "____________________________________"
# Package
echo "Packaging ..."
#cd $DEPLOY_DIR
$QT_BIN_DIR/macdeployqt $OUT_APP_DIR/$APP_FILENAME -always-overwrite
cp -av $BUILD_DIR/service/server/$APP_NAME-service.app/Contents/macOS/$APP_NAME-service $BUNDLE_DIR/Contents/macOS
cp -Rv $PROJECT_DIR/deploy/data/macos/* $BUNDLE_DIR/Contents/macOS
rm -f $BUNDLE_DIR/Contents/macOS/post_install.sh $BUNDLE_DIR/Contents/macOS/post_uninstall.sh
if [ "${MAC_CERT_PW+x}" ]; then
CERTIFICATE_P12=$DEPLOY_DIR/PrivacyTechAppleCertDeveloperId.p12
WWDRCA=$DEPLOY_DIR/WWDRCA.cer
KEYCHAIN=amnezia.build.keychain
TEMP_PASS=tmp_pass
security create-keychain -p $TEMP_PASS $KEYCHAIN || true
security default-keychain -s $KEYCHAIN
security unlock-keychain -p $TEMP_PASS $KEYCHAIN
security default-keychain
security list-keychains
security import $WWDRCA -k $KEYCHAIN -T /usr/bin/codesign || true
security import $CERTIFICATE_P12 -k $KEYCHAIN -P $MAC_CERT_PW -T /usr/bin/codesign || true
security set-key-partition-list -S apple-tool:,apple: -k $TEMP_PASS $KEYCHAIN
security find-identity -p codesigning
echo "Signing App bundle..."
/usr/bin/codesign --deep --force --verbose --timestamp -o runtime --sign "Developer ID Application: Privacy Technologies OU (X7UJ388FXK)" $BUNDLE_DIR
/usr/bin/codesign --verify -vvvv $BUNDLE_DIR || true
spctl -a -vvvv $BUNDLE_DIR || true
echo "Notatizing App bundle..."
/usr/bin/ditto -c -k --keepParent $BUNDLE_DIR $PROJECT_DIR/Bundle_to_notarize.zip
xcrun altool --notarize-app -f $PROJECT_DIR/Bundle_to_notarize.zip -t osx --primary-bundle-id "$APP_DOMAIN" -u "$APPLE_DEV_EMAIL" -p $APPLE_DEV_PASSWORD
rm $PROJECT_DIR/Bundle_to_notarize.zip
sleep 600
xcrun stapler staple $BUNDLE_DIR
xcrun stapler validate $BUNDLE_DIR
spctl -a -vvvv $BUNDLE_DIR || true
fi
echo "Packaging installer..."
mkdir -p $INSTALLER_DATA_DIR
cp -av $PROJECT_DIR/deploy/installer $BUILD_DIR
cp -av $DEPLOY_DATA_DIR/post_install.sh $INSTALLER_DATA_DIR/post_install.sh
cp -av $DEPLOY_DATA_DIR/post_uninstall.sh $INSTALLER_DATA_DIR/post_uninstall.sh
cp -av $DEPLOY_DATA_DIR/$PLIST_NAME $INSTALLER_DATA_DIR/$PLIST_NAME
chmod a+x $INSTALLER_DATA_DIR/post_install.sh $INSTALLER_DATA_DIR/post_uninstall.sh
cd $BUNDLE_DIR
tar czf $INSTALLER_DATA_DIR/$APP_NAME.tar.gz ./
echo "Building installer..."
$QIF_BIN_DIR/binarycreator --offline-only -v -c $BUILD_DIR/installer/config/macos.xml -p $BUILD_DIR/installer/packages -f $INSTALLER_BUNDLE_DIR
if [ "${MAC_CERT_PW+x}" ]; then
echo "Signing installer bundle..."
security unlock-keychain -p $TEMP_PASS $KEYCHAIN
/usr/bin/codesign --deep --force --verbose --timestamp -o runtime --sign "Developer ID Application: Privacy Technologies OU (X7UJ388FXK)" $INSTALLER_BUNDLE_DIR
/usr/bin/codesign --verify -vvvv $INSTALLER_BUNDLE_DIR || true
echo "Notatizing installer bundle..."
/usr/bin/ditto -c -k --keepParent $INSTALLER_BUNDLE_DIR $PROJECT_DIR/Installer_bundle_to_notarize.zip
xcrun altool --notarize-app -f $PROJECT_DIR/Installer_bundle_to_notarize.zip -t osx --primary-bundle-id "$APP_DOMAIN" -u "$APPLE_DEV_EMAIL" -p $APPLE_DEV_PASSWORD
rm $PROJECT_DIR/Installer_bundle_to_notarize.zip
sleep 600
xcrun stapler staple $INSTALLER_BUNDLE_DIR
xcrun stapler validate $INSTALLER_BUNDLE_DIR
spctl -a -vvvv $INSTALLER_BUNDLE_DIR || true
fi
echo "Building DMG installer..."
hdiutil create -volname $APP_NAME -srcfolder $BUILD_DIR/installer/$APP_NAME.app -ov -format UDZO $DMG_FILENAME
if [ "${MAC_CERT_PW+x}" ]; then
echo "Signing DMG installer..."
security unlock-keychain -p $TEMP_PASS $KEYCHAIN
/usr/bin/codesign --deep --force --verbose --timestamp -o runtime --sign "Developer ID Application: Privacy Technologies OU (X7UJ388FXK)" $DMG_FILENAME
/usr/bin/codesign --verify -vvvv $DMG_FILENAME || true
echo "Notatizing DMG installer..."
xcrun altool --notarize-app -f $DMG_FILENAME -t osx --primary-bundle-id $APP_DOMAIN -u $APPLE_DEV_EMAIL -p $APPLE_DEV_PASSWORD
sleep 600
xcrun stapler staple $DMG_FILENAME
xcrun stapler validate $DMG_FILENAME
fi
echo "Finished, artifact is $DMG_FILENAME"
# restore keychain
security default-keychain -s login.keychain
+15 -16
View File
@@ -4,9 +4,6 @@ CHCP 1252
REM %VAR:"=% mean dequoted %VAR%
set QT_BIN_DIR="c:\Qt\5.14.2\msvc2017\bin"
set QIF_BIN_DIR="c:\Qt\Tools\QtInstallerFramework\4.0\bin"
set PATH=%QT_BIN_DIR:"=%;%PATH%
echo "Using Qt in %QT_BIN_DIR%"
@@ -16,9 +13,9 @@ REM Hold on to current directory
set PROJECT_DIR=%cd%
set SCRIPT_DIR=%PROJECT_DIR:"=%\deploy
set WORK_DIR=%SCRIPT_DIR:"=%\build_%BUILD_ARCH:"=%
rmdir /Q /S %WORK_DIR%
mkdir %SCRIPT_DIR:"=%\build
set WORK_DIR=%SCRIPT_DIR:"=%\build
mkdir %WORK_DIR%
set APP_NAME=AmneziaVPN
@@ -26,23 +23,23 @@ set APP_FILENAME=%APP_NAME:"=%.exe
set APP_DOMAIN=org.amneziavpn.package
set RELEASE_DIR=%WORK_DIR:"=%
set OUT_APP_DIR=%RELEASE_DIR:"=%\client\release
set DEPLOY_DATA_DIR=%SCRIPT_DIR:"=%\data\windows
set DEPLOY_DATA_DIR=%SCRIPT_DIR:"=%\data\windows\x%BUILD_ARCH:"=%
set INSTALLER_DATA_DIR=%RELEASE_DIR:"=%\installer\packages\%APP_DOMAIN:"=%\data
set PRO_FILE_PATH=%PROJECT_DIR:"=%\%APP_NAME:"=%.pro
set QMAKE_STASH_FILE=%PROJECT_DIR:"=%\.qmake_stash
set TARGET_FILENAME=%PROJECT_DIR:"=%\%APP_NAME:"=%.exe
set TARGET_FILENAME=%PROJECT_DIR:"=%\%APP_NAME:"=%_x%BUILD_ARCH:"=%.exe
echo "Environment:"
echo "APP_FILENAME: %APP_FILENAME%"
echo "PROJECT_DIR: %PROJECT_DIR%"
echo "SCRIPT_DIR: %SCRIPT_DIR%"
echo "SCRIPT_DIR: %SCRIPT_DIR%"
echo "RELEASE_DIR: %RELEASE_DIR%"
echo "OUT_APP_DIR: %OUT_APP_DIR%"
echo "DEPLOY_DATA_DIR: %DEPLOY_DATA_DIR%"
echo "DEPLOY_DATA_DIR: %DEPLOY_DATA_DIR%"
echo "INSTALLER_DATA_DIR: %INSTALLER_DATA_DIR%"
echo "PRO_FILE_PATH: %PRO_FILE_PATH%"
echo "PRO_FILE_PATH: %PRO_FILE_PATH%"
echo "QMAKE_STASH_FILE: %QMAKE_STASH_FILE%"
echo "TARGET_FILENAME: %TARGET_FILENAME%"
echo "TARGET_FILENAME: %TARGET_FILENAME%"
rem Signing staff
powershell Set-ExecutionPolicy -ExecutionPolicy Unrestricted -Scope LocalMachine
@@ -60,7 +57,7 @@ Del %TARGET_FILENAME%
nmake /?
cd %PROJECT_DIR%
"%QT_BIN_DIR:"=%\qmake" -spec win32-msvc -o deploy\build\Makefile
"%QT_BIN_DIR:"=%\qmake" -spec win32-msvc -o "%WORK_DIR:"=%\Makefile"
cd %WORK_DIR%
set CL=/MP
@@ -84,11 +81,11 @@ signtool sign /v /sm /s My /n "Privacy Technologies OU" /fd sha256 /tr http://ti
signtool sign /v /sm /s My /n "Privacy Technologies OU" /fd sha256 /tr http://timestamp.comodoca.com/?td=sha256 /td sha256 *.dll
echo "Copying deploy data..."
xcopy %DEPLOY_DATA_DIR% %OUT_APP_DIR% /s /e /y /i /f
xcopy %DEPLOY_DATA_DIR% %OUT_APP_DIR% /s /e /y /i /f
cd %SCRIPT_DIR%
xcopy %SCRIPT_DIR:"=%\installer %RELEASE_DIR:"=%\installer /s /e /y /i /f
xcopy %SCRIPT_DIR:"=%\installer %RELEASE_DIR:"=%\installer /s /e /y /i /f
mkdir %INSTALLER_DATA_DIR%
echo "Deploy finished, content:"
@@ -102,8 +99,10 @@ cd "%RELEASE_DIR:"=%\installer"
echo "Creating installer..."
"%QIF_BIN_DIR:"=%\binarycreator" --offline-only -v -c config\windows.xml -p packages -f %TARGET_FILENAME%
timeout 5
cd %PROJECT_DIR%
signtool sign /v /sm /s My /n "Privacy Technologies OU" /fd sha256 /tr http://timestamp.comodoca.com/?td=sha256 /td sha256 %TARGET_FILENAME%
signtool sign /v /sm /s My /n "Privacy Technologies OU" /fd sha256 /tr http://timestamp.comodoca.com/?td=sha256 /td sha256 "%TARGET_FILENAME%"
echo "Finished, see %TARGET_FILENAME%"
exit 0
exit 0
+1 -1
View File
@@ -29,4 +29,4 @@ launchctl load $LAUNCH_DAEMONS_PLIST_NAME
echo "`date` Service status: $?" >> $LOG_FILE
echo "`date` Script finished" >> $LOG_FILE
rm -- "$0"
#rm -- "$0"
+74
View File
@@ -0,0 +1,74 @@
#!/bin/bash
# Mac name-resolution updater based on @cl's script here:
# https://blog.netnerds.net/2011/10/openvpn-update-client-dns-on-mac-os-x-using-from-the-command-line/
# Openvpn envar parsing taken from the script in debian's openvpn package.
# Smushed together and improved by @andrewgdotcom.
# Parses DHCP options from openvpn to update resolv.conf
# To use set as 'up' and 'down' script in your openvpn *.conf:
# up /etc/openvpn/update-resolv-conf
# down /etc/openvpn/update-resolv-conf
[ "$script_type" ] || exit 0
[ "$dev" ] || exit 0
PATH=$PATH:/usr/sbin/
NMSRVRS=()
SRCHS=()
# Get adapter list
IFS=$'\n' read -d '' -ra adapters < <(networksetup -listallnetworkservices |grep -v denotes) || true
split_into_parts()
{
part1="$1"
part2="$2"
part3="$3"
}
update_all_dns()
{
for adapter in "${adapters[@]}"
do
echo updating dns for $adapter
# set dns server to the vpn dns server
if [[ "${SRCHS[@]}" ]]; then
networksetup -setsearchdomains "$adapter" "${SRCHS[@]}"
fi
if [[ "${NMSRVRS[@]}" ]]; then
networksetup -setdnsservers "$adapter" "${NMSRVRS[@]}"
fi
done
}
clear_all_dns()
{
for adapter in "${adapters[@]}"
do
echo updating dns for $adapter
networksetup -setdnsservers "$adapter" empty
networksetup -setsearchdomains "$adapter" empty
done
}
case "$script_type" in
up)
for optionvarname in ${!foreign_option_*} ; do
option="${!optionvarname}"
echo "$option"
split_into_parts $option
if [ "$part1" = "dhcp-option" ] ; then
if [ "$part2" = "DNS" ] ; then
NMSRVRS=(${NMSRVRS[@]} $part3)
elif [ "$part2" = "DOMAIN" ] ; then
SRCHS=(${SRCHS[@]} $part3)
fi
fi
done
update_all_dns
;;
down)
clear_all_dns
;;
esac
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.

Some files were not shown because too many files have changed in this diff Show More