Merge branch 'dev' of github.com:amnezia-vpn/desktop-client into Linux_libs_deps

This commit is contained in:
leetthewire 2022-09-01 17:45:39 +04:00
commit 53c916ea4f
113 changed files with 4138 additions and 1437 deletions

3
.gitmodules vendored
View file

@ -25,3 +25,6 @@
[submodule "client/3rd/CocoaLumberjack"] [submodule "client/3rd/CocoaLumberjack"]
path = client/3rd/CocoaLumberjack path = client/3rd/CocoaLumberjack
url = https://github.com/CocoaLumberjack/CocoaLumberjack.git url = https://github.com/CocoaLumberjack/CocoaLumberjack.git
[submodule "client/3rd/qtkeychain"]
path = client/3rd/qtkeychain
url = https://github.com/frankosterfeld/qtkeychain.git

View file

@ -10,8 +10,9 @@ jobs:
os: osx os: osx
osx_image: xcode13.4 osx_image: xcode13.4
language: cpp language: cpp
env: env:
- PATH=/usr/local/opt/ccache/libexec:$PATH
- QT_VERSION=5.15.2 - QT_VERSION=5.15.2
- QIF_VERSION=4.4 - QIF_VERSION=4.4
- QT_BIN_DIR=$HOME/Qt/$QT_VERSION/clang_64/bin - QT_BIN_DIR=$HOME/Qt/$QT_VERSION/clang_64/bin
@ -19,8 +20,8 @@ jobs:
install: install:
- | - |
if [ ! -f $HOME/Qt/$QT_VERSION/clang_64/bin/qmake ]; then \ if [ ! -f $QT_BIN_DIR/qmake ]; then \
brew install p7zip && \ brew install p7zip ccache && \
python3 -m pip install --upgrade pip && \ python3 -m pip install --upgrade pip && \
pip install -U aqtinstall requests py7zr && \ pip install -U aqtinstall requests py7zr && \
pip show aqtinstall && \ pip show aqtinstall && \
@ -31,6 +32,9 @@ jobs:
script: script:
- bash deploy/build_macos.sh - bash deploy/build_macos.sh
after_script:
- ccache --show-stats
deploy: deploy:
provider: releases provider: releases
token: $GH_TOKEN token: $GH_TOKEN
@ -41,6 +45,12 @@ jobs:
tags: true tags: true
branch: master branch: master
cache:
- ccache
- directories:
- $HOME/Qt
- $HOME/Library/Caches/Homebrew
# ------------------------------------------------------ # ------------------------------------------------------
- name: Windows_x64 - name: Windows_x64
os: windows os: windows
@ -87,6 +97,11 @@ jobs:
tags: true tags: true
branch: master branch: master
cache:
directories:
- /C/Qt
- $MSVC_PATH
# ------------------------------------------------------ # ------------------------------------------------------
- name: Windows_x32 - name: Windows_x32
os: windows os: windows
@ -133,9 +148,25 @@ jobs:
tags: true tags: true
branch: master branch: master
cache:
directories:
- /C/Qt
- $MSVC_PATH
# ------------------------------------------------------ # ------------------------------------------------------
- name: Linux - name: Linux
os: linux os: linux
dist: focal
addons:
apt:
packages:
- p7zip
- python3
- python3-pip
- libgl-dev
- mesa-common-dev
- libpulse-dev
env: env:
- QT_VERSION=5.15.2 - QT_VERSION=5.15.2
@ -145,19 +176,21 @@ jobs:
install: install:
- | - |
if [ ! -f $HOME/Qt/$QT_VERSION/gcc_64/bin/qmake ]; then \ if [ ! -f $QT_BIN_DIR/qmake ]; then \
sudo apt-get update && \ python3 -m pip install --user $(whoami) --upgrade pip && \
sudo apt install -yy p7zip python3 python3-pip && \ export PATH=$HOME/.local/bin:$PATH && \
python3 -m pip install --upgrade pip && \ python3 -m pip install -U aqtinstall requests py7zr && \
pip install -U aqtinstall requests py7zr && \ python3 -m pip show aqtinstall && \
pip show aqtinstall && \ python3 -m aqt install-qt linux desktop $QT_VERSION gcc_64 -m all -O $HOME/Qt && \
python3 -m aqt install-qt linux desktop $QT_VERSION clang_64 -m all -O $HOME/Qt && \
python3 -m aqt install-tool linux desktop tools_ifw -O $HOME/Qt ; \ python3 -m aqt install-tool linux desktop tools_ifw -O $HOME/Qt ; \
fi fi
script: script:
- bash deploy/build_linux.sh - bash deploy/build_linux.sh
after_script:
- ccache --show-stats
deploy: deploy:
provider: releases provider: releases
token: $GH_TOKEN token: $GH_TOKEN
@ -168,28 +201,42 @@ jobs:
tags: true tags: true
branch: master branch: master
cache:
- ccache
- directories:
- $HOME/Qt
# ------------------------------------------------------ # ------------------------------------------------------
- name: Android - name: Android
os: linux os: linux
language: android language: android
dist: xenial
components: addons:
# Uncomment the lines below if you want to apt:
# use the latest revision of Android SDK Tools packages:
# - tools - p7zip
# - platform-tools - python3
- python3-pip
# The BuildTools version used by your project android:
- build-tools-30.0.2 components:
# Uncomment the lines below if you want to
# use the latest revision of Android SDK Tools
# - tools
# - platform-tools
# The SDK version used to compile your project # The BuildTools version used by your project
- android-30 - build-tools-30.0.2
# Additional components # The SDK version used to compile your project
- extra - android-30
- extra-google-google_play_services
- extra-google-m2repository # Additional components
- extra-android-m2repository - extra
- extra-google-google_play_services
- extra-google-m2repository
- extra-android-m2repository
env: env:
- QT_VERSION=5.15.2 - QT_VERSION=5.15.2
@ -199,12 +246,10 @@ jobs:
install: install:
- | - |
if [ ! -f $HOME/Qt/$QT_VERSION/android/bin/qmake ]; then \ if [ ! -f $QT_BIN_DIR/qmake ]; then \
sudo apt-get update && \ export PATH=$HOME/.local/bin:$PATH && \
sudo apt install -yy p7zip python3 python3-pip && \ python3 -m pip install -U aqtinstall requests py7zr && \
python3 -m pip install --upgrade pip && \ python3 -m pip show aqtinstall && \
pip install -U aqtinstall requests py7zr && \
pip show aqtinstall && \
python3 -m aqt install-qt linux android $QT_VERSION android_armv7 -m all -O $HOME/Qt && \ python3 -m aqt install-qt linux android $QT_VERSION android_armv7 -m all -O $HOME/Qt && \
python3 -m aqt install-qt linux android $QT_VERSION android_arm64_v8a -m all -O $HOME/Qt && \ python3 -m aqt install-qt linux android $QT_VERSION android_arm64_v8a -m all -O $HOME/Qt && \
python3 -m aqt install-qt linux android $QT_VERSION android_x86_64 -m all -O $HOME/Qt && \ python3 -m aqt install-qt linux android $QT_VERSION android_x86_64 -m all -O $HOME/Qt && \
@ -224,6 +269,9 @@ jobs:
script: script:
- bash deploy/build_android.sh - bash deploy/build_android.sh
after_script:
- ccache --show-stats
deploy: deploy:
provider: releases provider: releases
token: $GH_TOKEN token: $GH_TOKEN
@ -234,20 +282,54 @@ jobs:
tags: true tags: true
branch: master branch: master
cache:
- ccache
- directories:
- $HOME/Qt
- $HOME/.gradle/caches/
- $HOME/.gradle/wrapper/
- $HOME/.android/build-cache
- $ANDROID_NDK_HOME
# ------------------------------------------------------
- name: iOS
os: osx
osx_image: xcode13.4
language: cpp
env:
- PATH=/usr/local/opt/ccache/libexec:~/go/bin:$PATH
- QT_VERSION=5.15.2
- QT_BIN_DIR=$HOME/Qt/$QT_VERSION/ios/bin
- QT_IOS_BIN=$QT_BIN_DIR
install:
- |
if [ ! -f $QT_BIN_DIR/qmake ]; then \
brew install p7zip ccache && \
python3 -m pip install --upgrade pip && \
pip install -U aqtinstall requests py7zr && \
pip show aqtinstall && \
aqt install-qt mac ios $QT_VERSION -m all -O $HOME/Qt ; \
fi
- brew install golang
- go install golang.org/x/mobile/cmd/gomobile@latest
- gomobile init
script:
- bash deploy/build_ios.sh
after_script:
- ccache --show-stats
cache:
- ccache
- directories:
- $HOME/Qt
- $HOME/Library/Caches/Homebrew
before_cache: before_cache:
- if [ "${TRAVIS_OS_NAME}" = "osx" ]; then brew cleanup; fi - if [ "${TRAVIS_OS_NAME}" = "osx" ]; then brew cleanup; fi
# Cache only .git files under "/usr/local/Homebrew" so "brew update" does not take 5min every build # Cache only .git files under "/usr/local/Homebrew" so "brew update" does not take 5min every build
- if [ "${TRAVIS_OS_NAME}" = "osx" ]; then find /usr/local/Homebrew \! -regex ".+\.git.+" -delete; fi - if [ "${TRAVIS_OS_NAME}" = "osx" ]; then find /usr/local/Homebrew \! -regex ".+\.git.+" -delete; fi
cache:
directories:
- $HOME/Qt
- /C/Qt
- $HOME/Library/Caches/Homebrew
- $HOME/.gradle/caches/
- $HOME/.gradle/wrapper/
- $HOME/.android/build-cache
- $ANDROID_NDK_HOME
- $MSVC_PATH

View file

@ -0,0 +1,18 @@
INCLUDEPATH += $$PWD
HEADERS += \
$$PWD/include/QAead.h \
$$PWD/include/QBlockCipher.h \
$$PWD/include/QCryptoError.h \
$$PWD/include/QRsa.h \
$$PWD/include/QSimpleCrypto_global.h \
$$PWD/include/QX509.h \
$$PWD/include/QX509Store.h
SOURCES += \
$$PWD/sources/QAead.cpp \
$$PWD/sources/QBlockCipher.cpp \
$$PWD/sources/QCryptoError.cpp \
$$PWD/sources/QRsa.cpp \
$$PWD/sources/QX509.cpp \
$$PWD/sources/QX509Store.cpp

View file

@ -0,0 +1,87 @@
/**
* Copyright 2021 BrutalWizard (https://github.com/bru74lw1z4rd). All Rights Reserved.
*
* Licensed under the Apache License 2.0 (the "License"). You may not use
* this file except in compliance with the License. You can obtain a copy
* in the file LICENSE in the source distribution
**/
#ifndef QAEAD_H
#define QAEAD_H
#include "QSimpleCrypto_global.h"
#include <QObject>
#include <memory>
#include <openssl/aes.h>
#include <openssl/err.h>
#include <openssl/evp.h>
#include <openssl/rand.h>
#include "QCryptoError.h"
// clang-format off
namespace QSimpleCrypto
{
class QSIMPLECRYPTO_EXPORT QAead {
public:
QAead();
///
/// \brief encryptAesGcm - Function encrypts data with Gcm algorithm.
/// \param data - Data that will be encrypted.
/// \param key - AES key.
/// \param iv - Initialization vector.
/// \param tag - Authorization tag.
/// \param aad - Additional authenticated data. Must be nullptr, if not used.
/// \param cipher - Can be used with OpenSSL EVP_CIPHER (gcm) - 128, 192, 256. Example: EVP_aes_256_gcm().
/// \return Returns encrypted data or "", if error happened.
///
QByteArray encryptAesGcm(QByteArray data, QByteArray key, QByteArray iv, QByteArray* tag, QByteArray aad = "", const EVP_CIPHER* cipher = EVP_aes_256_gcm());
///
/// \brief decryptAesGcm - Function decrypts data with Gcm algorithm.
/// \param data - Data that will be decrypted
/// \param key - AES key
/// \param iv - Initialization vector
/// \param tag - Authorization tag
/// \param aad - Additional authenticated data. Must be nullptr, if not used
/// \param cipher - Can be used with OpenSSL EVP_CIPHER (gcm) - 128, 192, 256. Example: EVP_aes_256_gcm()
/// \return Returns decrypted data or "", if error happened.
///
QByteArray decryptAesGcm(QByteArray data, QByteArray key, QByteArray iv, QByteArray* tag, QByteArray aad = "", const EVP_CIPHER* cipher = EVP_aes_256_gcm());
///
/// \brief encryptAesCcm - Function encrypts data with Ccm algorithm.
/// \param data - Data that will be encrypted.
/// \param key - AES key.
/// \param iv - Initialization vector.
/// \param tag - Authorization tag.
/// \param aad - Additional authenticated data. Must be nullptr, if not used.
/// \param cipher - Can be used with OpenSSL EVP_CIPHER (ccm) - 128, 192, 256. Example: EVP_aes_256_ccm().
/// \return Returns encrypted data or "", if error happened.
///
QByteArray encryptAesCcm(QByteArray data, QByteArray key, QByteArray iv, QByteArray* tag, QByteArray aad = "", const EVP_CIPHER* cipher = EVP_aes_256_ccm());
///
/// \brief decryptAesCcm - Function decrypts data with Ccm algorithm.
/// \param data - Data that will be decrypted.
/// \param key - AES key.
/// \param iv - Initialization vector.
/// \param tag - Authorization tag.
/// \param aad - Additional authenticated data. Must be nullptr, if not used.
/// \param cipher - Can be used with OpenSSL EVP_CIPHER (ccm) - 128, 192, 256. Example: EVP_aes_256_ccm().
/// \return Returns decrypted data or "", if error happened.
///
QByteArray decryptAesCcm(QByteArray data, QByteArray key, QByteArray iv, QByteArray* tag, QByteArray aad = "", const EVP_CIPHER* cipher = EVP_aes_256_ccm());
///
/// \brief error - Error handler class.
///
QCryptoError error;
};
} // namespace QSimpleCrypto
#endif // QAEAD_H

View file

@ -0,0 +1,84 @@
/**
* Copyright 2021 BrutalWizard (https://github.com/bru74lw1z4rd). All Rights Reserved.
*
* Licensed under the Apache License 2.0 (the "License"). You may not use
* this file except in compliance with the License. You can obtain a copy
* in the file LICENSE in the source distribution
**/
#ifndef QBLOCKCIPHER_H
#define QBLOCKCIPHER_H
#include "QSimpleCrypto_global.h"
#include <QObject>
#include <memory>
#include <openssl/aes.h>
#include <openssl/err.h>
#include <openssl/evp.h>
#include <openssl/rand.h>
#include "QCryptoError.h"
// clang-format off
namespace QSimpleCrypto
{
class QSIMPLECRYPTO_EXPORT QBlockCipher {
#define Aes128Rounds 10
#define Aes192Rounds 12
#define Aes256Rounds 14
public:
QBlockCipher();
///
/// \brief generateRandomBytes - Function generates random bytes by size.
/// \param size - Size of generated bytes.
/// \return Returns random bytes.
///
QByteArray generateRandomBytes(const int& size);
QByteArray generateSecureRandomBytes(const int& size);
///
/// \brief encryptAesBlockCipher - Function encrypts data with Aes Block Cipher algorithm.
/// \param data - Data that will be encrypted.
/// \param key - AES key.
/// \param iv - Initialization vector.
/// \param password - Encryption password.
/// \param salt - Random delta.
/// \param rounds - Transformation rounds.
/// \param chiper - Can be used with OpenSSL EVP_CIPHER (ecb, cbc, cfb, ofb, ctr) - 128, 192, 256. Example: EVP_aes_256_cbc().
/// \param md - Hash algroitm (OpenSSL EVP_MD). Example: EVP_sha512().
/// \return Returns decrypted data or "", if error happened.
///
QByteArray encryptAesBlockCipher(QByteArray data, QByteArray key,
QByteArray iv = "", const int& rounds = Aes256Rounds,
const EVP_CIPHER* cipher = EVP_aes_256_cbc(), const EVP_MD* md = EVP_sha512());
///
/// \brief decryptAesBlockCipher - Function decrypts data with Aes Block Cipher algorithm.
/// \param data - Data that will be decrypted.
/// \param key - AES key.
/// \param iv - Initialization vector.
/// \param password - Decryption password.
/// \param salt - Random delta.
/// \param rounds - Transformation rounds.
/// \param chiper - Can be used with OpenSSL EVP_CIPHER (ecb, cbc, cfb, ofb, ctr) - 128, 192, 256. Example: EVP_aes_256_cbc().
/// \param md - Hash algroitm (OpenSSL EVP_MD). Example: EVP_sha512().
/// \return Returns decrypted data or "", if error happened.
///
QByteArray decryptAesBlockCipher(QByteArray data, QByteArray key,
QByteArray iv = "", const int& rounds = Aes256Rounds,
const EVP_CIPHER* cipher = EVP_aes_256_cbc(), const EVP_MD* md = EVP_sha512());
///
/// \brief error - Error handler class.
///
QCryptoError error;
};
} // namespace QSimpleCrypto
#endif // QBLOCKCIPHER_H

View file

@ -0,0 +1,45 @@
#ifndef QCRYPTOERROR_H
#define QCRYPTOERROR_H
#include <QObject>
#include "QSimpleCrypto_global.h"
/// TODO: Add Special error code for each error.
// clang-format off
namespace QSimpleCrypto
{
class QSIMPLECRYPTO_EXPORT QCryptoError : public QObject {
Q_OBJECT
public:
explicit QCryptoError(QObject* parent = nullptr);
///
/// \brief setError - Sets error information
/// \param errorCode - Error code.
/// \param errorSummary - Error summary.
///
inline void setError(const quint8 errorCode, const QString& errorSummary)
{
m_currentErrorCode = errorCode;
m_errorSummary = errorSummary;
}
///
/// \brief lastError - Returns last error.
/// \return Returns eror ID and error Text.
///
inline QPair<quint8, QString> lastError() const
{
return QPair<quint8, QString>(m_currentErrorCode, m_errorSummary);
}
private:
quint8 m_currentErrorCode;
QString m_errorSummary;
};
}
#endif // QCRYPTOERROR_H

View file

@ -0,0 +1,104 @@
/**
* Copyright 2021 BrutalWizard (https://github.com/bru74lw1z4rd). All Rights Reserved.
*
* Licensed under the Apache License 2.0 (the "License"). You may not use
* this file except in compliance with the License. You can obtain a copy
* in the file LICENSE in the source distribution
**/
#ifndef QRSA_H
#define QRSA_H
#include "QSimpleCrypto_global.h"
#include <QFile>
#include <QObject>
#include <memory>
#include <openssl/err.h>
#include <openssl/pem.h>
#include <openssl/rsa.h>
#include "QCryptoError.h"
// clang-format off
namespace QSimpleCrypto
{
class QSIMPLECRYPTO_EXPORT QRsa {
#define PublicEncrypt 0
#define PrivateEncrypt 1
#define PublicDecrypt 2
#define PrivateDecrypt 3
public:
QRsa();
///
/// \brief generateRsaKeys - Function generate Rsa Keys and returns them in OpenSSL structure.
/// \param bits - RSA key size.
/// \param rsaBigNumber - The exponent is an odd number, typically 3, 17 or 65537.
/// \return Returns 'OpenSSL RSA structure' or 'nullptr', if error happened. Returned value must be cleaned up with 'RSA_free()' to avoid memory leak.
///
RSA* generateRsaKeys(const int& bits, const int& rsaBigNumber);
///
/// \brief savePublicKey - Saves to file RSA public key.
/// \param rsa - OpenSSL RSA structure.
/// \param publicKeyFileName - Public key file name.
///
void savePublicKey(RSA *rsa, const QByteArray& publicKeyFileName);
///
/// \brief savePrivateKey - Saves to file RSA private key.
/// \param rsa - OpenSSL RSA structure.
/// \param privateKeyFileName - Private key file name.
/// \param password - Private key password.
/// \param cipher - Can be used with 'OpenSSL EVP_CIPHER' (ecb, cbc, cfb, ofb, ctr) - 128, 192, 256. Example: EVP_aes_256_cbc().
///
void savePrivateKey(RSA* rsa, const QByteArray& privateKeyFileName, QByteArray password = "", const EVP_CIPHER* cipher = nullptr);
///
/// \brief getPublicKeyFromFile - Gets RSA public key from a file.
/// \param filePath - File path to public key file.
/// \return Returns 'OpenSSL EVP_PKEY structure' or 'nullptr', if error happened. Returned value must be cleaned up with 'EVP_PKEY_free()' to avoid memory leak.
///
EVP_PKEY* getPublicKeyFromFile(const QByteArray& filePath);
///
/// \brief getPrivateKeyFromFile - Gets RSA private key from a file.
/// \param filePath - File path to private key file.
/// \param password - Private key password.
/// \return - Returns 'OpenSSL EVP_PKEY structure' or 'nullptr', if error happened. Returned value must be cleaned up with 'EVP_PKEY_free()' to avoid memory leak.
///
EVP_PKEY* getPrivateKeyFromFile(const QByteArray& filePath, const QByteArray& password = "");
///
/// \brief encrypt - Encrypt data with RSA algorithm.
/// \param plaintext - Text that must be encrypted.
/// \param rsa - OpenSSL RSA structure.
/// \param encryptType - Public or private encrypt type. (PUBLIC_ENCRYPT, PRIVATE_ENCRYPT).
/// \param padding - OpenSSL RSA padding can be used with: 'RSA_PKCS1_PADDING', 'RSA_NO_PADDING' and etc.
/// \return Returns encrypted data or "", if error happened.
///
QByteArray encrypt(QByteArray plainText, RSA* rsa, const int& encryptType = PublicEncrypt, const int& padding = RSA_PKCS1_PADDING);
///
/// \brief decrypt - Decrypt data with RSA algorithm.
/// \param cipherText - Text that must be decrypted.
/// \param rsa - OpenSSL RSA structure.
/// \param decryptType - Public or private type. (PUBLIC_DECRYPT, PRIVATE_DECRYPT).
/// \param padding - RSA padding can be used with: 'RSA_PKCS1_PADDING', 'RSA_NO_PADDING' and etc.
/// \return - Returns decrypted data or "", if error happened.
///
QByteArray decrypt(QByteArray cipherText, RSA* rsa, const int& decryptType = PrivateDecrypt, const int& padding = RSA_PKCS1_PADDING);
///
/// \brief error - Error handler class.
///
QCryptoError error;
};
} // namespace QSimpleCrypto
#endif // QRSA_H

View file

@ -0,0 +1,9 @@
#ifndef QSIMPLECRYPTO_GLOBAL_H
#define QSIMPLECRYPTO_GLOBAL_H
#include <QtCore/qglobal.h>
#include <stdexcept>
#define QSIMPLECRYPTO_EXPORT
#endif // QSIMPLECRYPTO_GLOBAL_H

View file

@ -0,0 +1,87 @@
/**
* Copyright 2021 BrutalWizard (https://github.com/bru74lw1z4rd). All Rights Reserved.
*
* Licensed under the Apache License 2.0 (the "License"). You may not use
* this file except in compliance with the License. You can obtain a copy
* in the file LICENSE in the source distribution
**/
#ifndef QX509_H
#define QX509_H
#include "QSimpleCrypto_global.h"
#include <QMap>
#include <QObject>
#include <memory>
#include <openssl/bio.h>
#include <openssl/err.h>
#include <openssl/pem.h>
#include <openssl/x509.h>
#include <openssl/x509_vfy.h>
#include "QCryptoError.h"
// clang-format off
namespace QSimpleCrypto
{
class QSIMPLECRYPTO_EXPORT QX509 {
#define oneYear 31536000L
#define x509LastVersion 2
public:
QX509();
///
/// \brief loadCertificateFromFile - Function load X509 from file and returns OpenSSL structure.
/// \param fileName - File path to certificate.
/// \return Returns OpenSSL X509 structure or nullptr, if error happened. Returned value must be cleaned up with 'X509_free' to avoid memory leak.
///
X509* loadCertificateFromFile(const QByteArray& fileName);
///
/// \brief signCertificate - Function signs X509 certificate and returns signed X509 OpenSSL structure.
/// \param endCertificate - Certificate that will be signed
/// \param caCertificate - CA certificate that will sign end certificate
/// \param caPrivateKey - CA certificate private key
/// \param fileName - With that name certificate will be saved. Leave "", if don't need to save it
/// \return Returns OpenSSL X509 structure or nullptr, if error happened.
///
X509* signCertificate(X509* endCertificate, X509* caCertificate, EVP_PKEY* caPrivateKey, const QByteArray& fileName = "");
///
/// \brief verifyCertificate - Function verifies X509 certificate and returns verified X509 OpenSSL structure.
/// \param x509 - OpenSSL X509. That certificate will be verified.
/// \param store - Trusted certificate must be added to X509_Store with 'addCertificateToStore(X509_STORE* ctx, X509* x509)'.
/// \return Returns OpenSSL X509 structure or nullptr, if error happened
///
X509* verifyCertificate(X509* x509, X509_STORE* store);
///
/// \brief generateSelfSignedCertificate - Function generatesand returns self signed X509.
/// \param rsa - OpenSSL RSA.
/// \param additionalData - Certificate information.
/// \param certificateFileName - With that name certificate will be saved. Leave "", if don't need to save it.
/// \param md - OpenSSL EVP_MD structure. Example: EVP_sha512().
/// \param serialNumber - X509 certificate serial number.
/// \param version - X509 certificate version.
/// \param notBefore - X509 start date.
/// \param notAfter - X509 end date.
/// \return Returns OpenSSL X509 structure or nullptr, if error happened. Returned value must be cleaned up with 'X509_free' to avoid memory leak.
///
X509* generateSelfSignedCertificate(const RSA* rsa, const QMap<QByteArray, QByteArray>& additionalData,
const QByteArray& certificateFileName = "", const EVP_MD* md = EVP_sha512(),
const long& serialNumber = 1, const long& version = x509LastVersion,
const long& notBefore = 0, const long& notAfter = oneYear);
///
/// \brief error - Error handler class.
///
QCryptoError error;
};
} // namespace QSimpleCrypto
#endif // QX509_H

View file

@ -0,0 +1,120 @@
/**
* Copyright 2021 BrutalWizard (https://github.com/bru74lw1z4rd). All Rights Reserved.
*
* Licensed under the Apache License 2.0 (the "License"). You may not use
* this file except in compliance with the License. You can obtain a copy
* in the file LICENSE in the source distribution
**/
#ifndef QX509STORE_H
#define QX509STORE_H
#include "QSimpleCrypto_global.h"
#include <QDir>
#include <QFile>
#include <QFileInfo>
#include <memory>
#include <openssl/err.h>
#include <openssl/x509_vfy.h>
#include <openssl/x509v3.h>
#include "QCryptoError.h"
// clang-format off
namespace QSimpleCrypto
{
class QSIMPLECRYPTO_EXPORT QX509Store {
public:
QX509Store();
///
/// \brief addCertificateToStore
/// \param store - OpenSSL X509_STORE.
/// \param x509 - OpenSSL X509.
/// \return Returns 'true' on success and 'false', if error happened.
///
bool addCertificateToStore(X509_STORE* store, X509* x509);
///
/// \brief addLookup
/// \param store - OpenSSL X509_STORE.
/// \param method - OpenSSL X509_LOOKUP_METHOD. Example: X509_LOOKUP_file.
/// \return Returns 'true' on success and 'false', if error happened.
///
bool addLookup(X509_STORE* store, X509_LOOKUP_METHOD* method);
///
/// \brief setCertificateDepth
/// \param store - OpenSSL X509_STORE.
/// \param depth - That is the maximum number of untrusted CA certificates that can appear in a chain. Example: 0.
/// \return Returns 'true' on success and 'false', if error happened.
///
bool setDepth(X509_STORE* store, const int& depth);
///
/// \brief setFlag
/// \param store - OpenSSL X509_STORE.
/// \param flag - The verification flags consists of zero or more of the following flags ored together. Example: X509_V_FLAG_CRL_CHECK.
/// \return Returns 'true' on success and 'false', if error happened.
///
bool setFlag(X509_STORE* store, const unsigned long& flag);
///
/// \brief setFlag
/// \param store - OpenSSL X509_STORE.
/// \param purpose - Verification purpose in param to purpose. Example: X509_PURPOSE_ANY.
/// \return Returns 'true' on success and 'false', if error happened.
///
bool setPurpose(X509_STORE* store, const int& purpose);
///
/// \brief setTrust
/// \param store - OpenSSL X509_STORE.
/// \param trust - Trust Level. Example: X509_TRUST_SSL_SERVER.
/// \return Returns 'true' on success and 'false', if error happened.
///
bool setTrust(X509_STORE* store, const int& trust);
///
/// \brief setDefaultPaths
/// \param store - OpenSSL X509_STORE.
/// \return Returns 'true' on success and 'false', if error happened.
///
bool setDefaultPaths(X509_STORE* store);
///
/// \brief loadLocations
/// \param store - OpenSSL X509_STORE.
/// \param fileName - File name. Example: "caCertificate.pem".
/// \param dirPath - Path to file. Example: "path/To/File".
/// \return Returns 'true' on success and 'false', if error happened.
///
bool loadLocations(X509_STORE* store, const QByteArray& fileName, const QByteArray& dirPath);
///
/// \brief loadLocations
/// \param store - OpenSSL X509_STORE.
/// \param file - Qt QFile that will be loaded.
/// \return Returns 'true' on success and 'false', if error happened.
///
bool loadLocations(X509_STORE* store, const QFile& file);
///
/// \brief loadLocations
/// \param store - OpenSSL X509_STORE.
/// \param fileInfo - Qt QFileInfo.
/// \return Returns 'true' on success and 'false', if error happened.
///
bool loadLocations(X509_STORE* store, const QFileInfo& fileInfo);
///
/// \brief error - Error handler class.
///
QCryptoError error;
};
}
#endif // QX509STORE_H

View file

@ -0,0 +1,364 @@
/**
* Copyright 2021 BrutalWizard (https://github.com/bru74lw1z4rd). All Rights Reserved.
*
* Licensed under the Apache License 2.0 (the "License"). You may not use
* this file except in compliance with the License. You can obtain a copy
* in the file LICENSE in the source distribution
**/
#include "include/QAead.h"
QSimpleCrypto::QAead::QAead()
{
}
///
/// \brief QSimpleCrypto::QAEAD::encryptAesGcm - Function encrypts data with Gcm algorithm.
/// \param data - Data that will be encrypted.
/// \param key - AES key.
/// \param iv - Initialization vector.
/// \param tag - Authorization tag.
/// \param aad - Additional authenticated data. Must be nullptr, if not used.
/// \param cipher - Can be used with OpenSSL EVP_CIPHER (gcm) - 128, 192, 256. Example: EVP_aes_256_gcm().
/// \return Returns encrypted data or "", if error happened.
///
QByteArray QSimpleCrypto::QAead::encryptAesGcm(QByteArray data, QByteArray key, QByteArray iv, QByteArray* tag, QByteArray aad, const EVP_CIPHER* cipher)
{
try {
/* Initialize EVP_CIPHER_CTX */
std::unique_ptr<EVP_CIPHER_CTX, void (*)(EVP_CIPHER_CTX*)> encryptionCipher { EVP_CIPHER_CTX_new(), EVP_CIPHER_CTX_free };
if (encryptionCipher == nullptr) {
throw std::runtime_error("Couldn't initialize \'encryptionCipher\'. EVP_CIPHER_CTX_new(). Error: " + QByteArray(ERR_error_string(ERR_get_error(), nullptr)));
}
/* Set data length */
int plainTextLength = data.size();
int cipherTextLength = 0;
/* Initialize cipherText. Here encrypted data will be stored */
std::unique_ptr<unsigned char[]> cipherText { new unsigned char[plainTextLength]() };
if (cipherText == nullptr) {
throw std::runtime_error("Couldn't allocate memory for 'ciphertext'.");
}
/* Initialize encryption operation. */
if (!EVP_EncryptInit_ex(encryptionCipher.get(), cipher, nullptr, reinterpret_cast<unsigned char*>(key.data()), reinterpret_cast<unsigned char*>(iv.data()))) {
throw std::runtime_error("Couldn't initialize encryption operation. EVP_EncryptInit_ex(). Error: " + QByteArray(ERR_error_string(ERR_get_error(), nullptr)));
}
/* Set IV length if default 12 bytes (96 bits) is not appropriate */
if (!EVP_CIPHER_CTX_ctrl(encryptionCipher.get(), EVP_CTRL_GCM_SET_IVLEN, iv.length(), nullptr)) {
throw std::runtime_error("Couldn't set IV length. EVP_CIPHER_CTX_ctrl(). Error: " + QByteArray(ERR_error_string(ERR_get_error(), nullptr)));
}
// /* Check if aad need to be used */
// if (aad.length() > 0) {
// /* Provide any AAD data. This can be called zero or more times as required */
// if (!EVP_EncryptUpdate(encryptionCipher.get(), nullptr, &cipherTextLength, reinterpret_cast<unsigned char*>(aad.data()), aad.length())) {
// throw std::runtime_error("Couldn't provide aad data. EVP_EncryptUpdate(). Error: " + QByteArray(ERR_error_string(ERR_get_error(), nullptr)));
// }
// }
/*
* Provide the message to be encrypted, and obtain the encrypted output.
* EVP_EncryptUpdate can be called multiple times if necessary
*/
if (!EVP_EncryptUpdate(encryptionCipher.get(), cipherText.get(), &cipherTextLength, reinterpret_cast<const unsigned char*>(data.data()), plainTextLength)) {
throw std::runtime_error("Couldn't provide message to be encrypted. EVP_EncryptUpdate(). Error: " + QByteArray(ERR_error_string(ERR_get_error(), nullptr)));
}
/*
* Finalize the encryption. Normally cipher text bytes may be written at
* this stage, but this does not occur in GCM mode
*/
if (!EVP_EncryptFinal_ex(encryptionCipher.get(), cipherText.get(), &plainTextLength)) {
throw std::runtime_error("Couldn't finalize encryption. EVP_EncryptFinal_ex(). Error: " + QByteArray(ERR_error_string(ERR_get_error(), nullptr)));
}
// /* Get tag */
// if (!EVP_CIPHER_CTX_ctrl(encryptionCipher.get(), EVP_CTRL_GCM_GET_TAG, tag->length(), reinterpret_cast<unsigned char*>(tag->data()))) {
// throw std::runtime_error("Couldn't get tag. EVP_CIPHER_CTX_ctrl(. Error: " + QByteArray(ERR_error_string(ERR_get_error(), nullptr)));
// }
/* Finilize data to be readable with qt */
QByteArray encryptedData = QByteArray(reinterpret_cast<char*>(cipherText.get()), cipherTextLength);
return encryptedData;
} catch (std::exception& exception) {
QSimpleCrypto::QAead::error.setError(1, exception.what());
return QByteArray();
} catch (...) {
QSimpleCrypto::QAead::error.setError(2, "Unknown error!");
return QByteArray();
}
return QByteArray();
}
///
/// \brief QSimpleCrypto::QAEAD::decryptAesGcm - Function decrypts data with Gcm algorithm.
/// \param data - Data that will be decrypted
/// \param key - AES key
/// \param iv - Initialization vector
/// \param tag - Authorization tag
/// \param aad - Additional authenticated data. Must be nullptr, if not used
/// \param cipher - Can be used with OpenSSL EVP_CIPHER (gcm) - 128, 192, 256. Example: EVP_aes_256_gcm()
/// \return Returns decrypted data or "", if error happened.
///
QByteArray QSimpleCrypto::QAead::decryptAesGcm(QByteArray data, QByteArray key, QByteArray iv, QByteArray* tag, QByteArray aad, const EVP_CIPHER* cipher)
{
try {
/* Initialize EVP_CIPHER_CTX */
std::unique_ptr<EVP_CIPHER_CTX, void (*)(EVP_CIPHER_CTX*)> decryptionCipher { EVP_CIPHER_CTX_new(), EVP_CIPHER_CTX_free };
if (decryptionCipher.get() == nullptr) {
throw std::runtime_error("Couldn't initialize \'decryptionCipher\'. EVP_CIPHER_CTX_new(). Error: " + QByteArray(ERR_error_string(ERR_get_error(), nullptr)));
}
/* Set data length */
int cipherTextLength = data.size();
int plainTextLength = 0;
/* Initialize plainText. Here decrypted data will be stored */
std::unique_ptr<unsigned char[]> plainText { new unsigned char[cipherTextLength]() };
if (plainText == nullptr) {
throw std::runtime_error("Couldn't allocate memory for 'plaintext'.");
}
/* Initialize decryption operation. */
if (!EVP_DecryptInit_ex(decryptionCipher.get(), cipher, nullptr, reinterpret_cast<unsigned char*>(key.data()), reinterpret_cast<unsigned char*>(iv.data()))) {
throw std::runtime_error("Couldn't initialize decryption operation. EVP_DecryptInit_ex(). Error: " + QByteArray(ERR_error_string(ERR_get_error(), nullptr)));
}
/* Set IV length. Not necessary if this is 12 bytes (96 bits) */
if (!EVP_CIPHER_CTX_ctrl(decryptionCipher.get(), EVP_CTRL_GCM_SET_IVLEN, iv.length(), nullptr)) {
throw std::runtime_error("Couldn't set IV length. EVP_CIPHER_CTX_ctrl(). Error: " + QByteArray(ERR_error_string(ERR_get_error(), nullptr)));
}
// /* Check if aad need to be used */
// if (aad.length() > 0) {
// /* Provide any AAD data. This can be called zero or more times as required */
// if (!EVP_DecryptUpdate(decryptionCipher.get(), nullptr, &plainTextLength, reinterpret_cast<unsigned char*>(aad.data()), aad.length())) {
// throw std::runtime_error("Couldn't provide aad data. EVP_DecryptUpdate(). Error: " + QByteArray(ERR_error_string(ERR_get_error(), nullptr)));
// }
// }
/*
* Provide the message to be decrypted, and obtain the plain text output.
* EVP_DecryptUpdate can be called multiple times if necessary
*/
if (!EVP_DecryptUpdate(decryptionCipher.get(), plainText.get(), &plainTextLength, reinterpret_cast<const unsigned char*>(data.data()), cipherTextLength)) {
throw std::runtime_error("Couldn't provide message to be decrypted. EVP_DecryptUpdate(). Error: " + QByteArray(ERR_error_string(ERR_get_error(), nullptr)));
}
// /* Set expected tag value. Works in OpenSSL 1.0.1d and later */
// if (!EVP_CIPHER_CTX_ctrl(decryptionCipher.get(), EVP_CTRL_GCM_SET_TAG, tag->length(), reinterpret_cast<unsigned char*>(tag->data()))) {
// throw std::runtime_error("Coldn't set tag. EVP_CIPHER_CTX_ctrl(). Error: " + QByteArray(ERR_error_string(ERR_get_error(), nullptr)));
// }
/*
* Finalize the decryption. A positive return value indicates success,
* anything else is a failure - the plain text is not trustworthy.
*/
if (!EVP_DecryptFinal_ex(decryptionCipher.get(), plainText.get(), &cipherTextLength)) {
throw std::runtime_error("Couldn't finalize decryption. EVP_DecryptFinal_ex(). Error: " + QByteArray(ERR_error_string(ERR_get_error(), nullptr)));
}
/* Finilize data to be readable with qt */
QByteArray decryptedData = QByteArray(reinterpret_cast<char*>(plainText.get()), plainTextLength);
return decryptedData;
} catch (std::exception& exception) {
QSimpleCrypto::QAead::error.setError(1, exception.what());
return QByteArray();
} catch (...) {
QSimpleCrypto::QAead::error.setError(2, "Unknown error!");
return QByteArray();
}
return QByteArray();
}
///
/// \brief QSimpleCrypto::QAEAD::encryptAesCcm - Function encrypts data with Ccm algorithm.
/// \param data - Data that will be encrypted.
/// \param key - AES key.
/// \param iv - Initialization vector.
/// \param tag - Authorization tag.
/// \param aad - Additional authenticated data. Must be nullptr, if not used.
/// \param cipher - Can be used with OpenSSL EVP_CIPHER (ccm) - 128, 192, 256. Example: EVP_aes_256_ccm().
/// \return Returns encrypted data or "", if error happened.
///
QByteArray QSimpleCrypto::QAead::encryptAesCcm(QByteArray data, QByteArray key, QByteArray iv, QByteArray* tag, QByteArray aad, const EVP_CIPHER* cipher)
{
try {
/* Initialize EVP_CIPHER_CTX */
std::unique_ptr<EVP_CIPHER_CTX, void (*)(EVP_CIPHER_CTX*)> encryptionCipher { EVP_CIPHER_CTX_new(), EVP_CIPHER_CTX_free };
if (encryptionCipher == nullptr) {
throw std::runtime_error("Couldn't initialize \'encryptionCipher\'. EVP_CIPHER_CTX_new(). Error: " + QByteArray(ERR_error_string(ERR_get_error(), nullptr)));
}
/* Set data length */
int plainTextLength = data.size();
int cipherTextLength = 0;
/* Initialize cipherText. Here encrypted data will be stored */
std::unique_ptr<unsigned char[]> cipherText { new unsigned char[plainTextLength]() };
if (cipherText.get() == nullptr) {
throw std::runtime_error("Couldn't allocate memory for 'ciphertext'.");
}
/* Initialize encryption operation. */
if (!EVP_EncryptInit_ex(encryptionCipher.get(), cipher, nullptr, reinterpret_cast<unsigned char*>(key.data()), reinterpret_cast<unsigned char*>(iv.data()))) {
throw std::runtime_error("Couldn't initialize encryption operation. EVP_EncryptInit_ex(). Error: " + QByteArray(ERR_error_string(ERR_get_error(), nullptr)));
}
/* Set IV length if default 12 bytes (96 bits) is not appropriate */
if (!EVP_CIPHER_CTX_ctrl(encryptionCipher.get(), EVP_CTRL_CCM_SET_IVLEN, iv.length(), nullptr)) {
throw std::runtime_error("Couldn't set IV length. EVP_CIPHER_CTX_ctrl(). Error: " + QByteArray(ERR_error_string(ERR_get_error(), nullptr)));
}
/* Set tag length */
if (!EVP_CIPHER_CTX_ctrl(encryptionCipher.get(), EVP_CTRL_CCM_SET_TAG, tag->length(), nullptr)) {
throw std::runtime_error("Coldn't set tag. EVP_CIPHER_CTX_ctrl(). Error: " + QByteArray(ERR_error_string(ERR_get_error(), nullptr)));
}
/* Check if aad need to be used */
if (aad.length() > 0) {
/* Provide the total plain text length */
if (!EVP_EncryptUpdate(encryptionCipher.get(), nullptr, &cipherTextLength, nullptr, plainTextLength)) {
throw std::runtime_error("Couldn't provide total plaintext length. EVP_EncryptUpdate(). Error: " + QByteArray(ERR_error_string(ERR_get_error(), nullptr)));
}
/* Provide any AAD data. This can be called zero or more times as required */
if (!EVP_EncryptUpdate(encryptionCipher.get(), nullptr, &cipherTextLength, reinterpret_cast<unsigned char*>(aad.data()), aad.length())) {
throw std::runtime_error("Couldn't provide aad data. EVP_EncryptUpdate(). Error: " + QByteArray(ERR_error_string(ERR_get_error(), nullptr)));
}
}
/*
* Provide the message to be encrypted, and obtain the encrypted output.
* EVP_EncryptUpdate can be called multiple times if necessary
*/
if (!EVP_EncryptUpdate(encryptionCipher.get(), cipherText.get(), &cipherTextLength, reinterpret_cast<const unsigned char*>(data.data()), plainTextLength)) {
throw std::runtime_error("Couldn't provide message to be encrypted. EVP_EncryptUpdate(). Error: " + QByteArray(ERR_error_string(ERR_get_error(), nullptr)));
}
/*
* Finalize the encryption. Normally ciphertext bytes may be written at
* this stage, but this does not occur in GCM mode
*/
if (!EVP_EncryptFinal_ex(encryptionCipher.get(), cipherText.get(), &plainTextLength)) {
throw std::runtime_error("Couldn't finalize encryption. EVP_EncryptFinal_ex(). Error: " + QByteArray(ERR_error_string(ERR_get_error(), nullptr)));
}
/* Get tag */
if (!EVP_CIPHER_CTX_ctrl(encryptionCipher.get(), EVP_CTRL_CCM_GET_TAG, tag->length(), reinterpret_cast<unsigned char*>(tag->data()))) {
throw std::runtime_error("Couldn't get tag. EVP_CIPHER_CTX_ctrl(). Error: " + QByteArray(ERR_error_string(ERR_get_error(), nullptr)));
}
/* Finilize data to be readable with qt */
QByteArray encryptedData = QByteArray(reinterpret_cast<char*>(cipherText.get()), cipherTextLength);
return encryptedData;
} catch (std::exception& exception) {
QSimpleCrypto::QAead::error.setError(1, exception.what());
return QByteArray();
} catch (...) {
QSimpleCrypto::QAead::error.setError(2, "Unknown error!");
return QByteArray();
}
return QByteArray();
}
///
/// \brief QSimpleCrypto::QAEAD::decryptAesCcm - Function decrypts data with Ccm algorithm.
/// \param data - Data that will be decrypted.
/// \param key - AES key.
/// \param iv - Initialization vector.
/// \param tag - Authorization tag.
/// \param aad - Additional authenticated data. Must be nullptr, if not used.
/// \param cipher - Can be used with OpenSSL EVP_CIPHER (ccm) - 128, 192, 256. Example: EVP_aes_256_ccm().
/// \return Returns decrypted data or "", if error happened.
///
QByteArray QSimpleCrypto::QAead::decryptAesCcm(QByteArray data, QByteArray key, QByteArray iv, QByteArray* tag, QByteArray aad, const EVP_CIPHER* cipher)
{
try {
/* Initialize EVP_CIPHER_CTX */
std::unique_ptr<EVP_CIPHER_CTX, void (*)(EVP_CIPHER_CTX*)> decryptionCipher { EVP_CIPHER_CTX_new(), EVP_CIPHER_CTX_free };
if (decryptionCipher.get() == nullptr) {
throw std::runtime_error("Couldn't initialize \'decryptionCipher\'. EVP_CIPHER_CTX_new(). Error: " + QByteArray(ERR_error_string(ERR_get_error(), nullptr)));
}
/* Set data length */
int cipherTextLength = data.size();
int plainTextLength = 0;
/* Initialize plainText. Here decrypted data will be stored */
std::unique_ptr<unsigned char[]> plainText { new unsigned char[cipherTextLength]() };
if (plainText == nullptr) {
throw std::runtime_error("Couldn't allocate memory for 'plaintext'.");
}
/* Initialize decryption operation. */
if (!EVP_DecryptInit_ex(decryptionCipher.get(), cipher, nullptr, reinterpret_cast<unsigned char*>(key.data()), reinterpret_cast<unsigned char*>(iv.data()))) {
throw std::runtime_error("Couldn't initialize decryption operation. EVP_DecryptInit_ex(). Error: " + QByteArray(ERR_error_string(ERR_get_error(), nullptr)));
}
/* Set IV length. Not necessary if this is 12 bytes (96 bits) */
if (!EVP_CIPHER_CTX_ctrl(decryptionCipher.get(), EVP_CTRL_CCM_SET_IVLEN, iv.length(), nullptr)) {
throw std::runtime_error("Couldn't set IV length. EVP_CIPHER_CTX_ctrl(). Error: " + QByteArray(ERR_error_string(ERR_get_error(), nullptr)));
}
/* Set expected tag value. Works in OpenSSL 1.0.1d and later */
if (!EVP_CIPHER_CTX_ctrl(decryptionCipher.get(), EVP_CTRL_CCM_SET_TAG, tag->length(), reinterpret_cast<unsigned char*>(tag->data()))) {
throw std::runtime_error("Coldn't set tag. EVP_CIPHER_CTX_ctrl(). Error: " + QByteArray(ERR_error_string(ERR_get_error(), nullptr)));
}
/* Check if aad need to be used */
if (aad.length() > 0) {
/* Provide the total ciphertext length */
if (!EVP_DecryptUpdate(decryptionCipher.get(), nullptr, &plainTextLength, nullptr, cipherTextLength)) {
throw std::runtime_error("Couldn't provide total plaintext length. EVP_DecryptUpdate(). Error: " + QByteArray(ERR_error_string(ERR_get_error(), nullptr)));
}
/* Provide any AAD data. This can be called zero or more times as required */
if (!EVP_DecryptUpdate(decryptionCipher.get(), nullptr, &plainTextLength, reinterpret_cast<unsigned char*>(aad.data()), aad.length())) {
throw std::runtime_error("Couldn't provide aad data. EVP_DecryptUpdate(). Error: " + QByteArray(ERR_error_string(ERR_get_error(), nullptr)));
}
}
/*
* Provide the message to be decrypted, and obtain the plaintext output.
* EVP_DecryptUpdate can be called multiple times if necessary
*/
if (!EVP_DecryptUpdate(decryptionCipher.get(), plainText.get(), &plainTextLength, reinterpret_cast<const unsigned char*>(data.data()), cipherTextLength)) {
throw std::runtime_error("Couldn't provide message to be decrypted. EVP_DecryptUpdate(). Error: " + QByteArray(ERR_error_string(ERR_get_error(), nullptr)));
}
/*
* Finalize the decryption. A positive return value indicates success,
* anything else is a failure - the plaintext is not trustworthy.
*/
if (!EVP_DecryptFinal_ex(decryptionCipher.get(), plainText.get(), &cipherTextLength)) {
throw std::runtime_error("Couldn't finalize decryption. EVP_DecryptFinal_ex(). Error: " + QByteArray(ERR_error_string(ERR_get_error(), nullptr)));
}
/* Finilize data to be readable with qt */
QByteArray decryptedData = QByteArray(reinterpret_cast<char*>(plainText.get()), plainTextLength);
return decryptedData;
} catch (std::exception& exception) {
QSimpleCrypto::QAead::error.setError(1, exception.what());
return QByteArray();
} catch (...) {
QSimpleCrypto::QAead::error.setError(2, "Unknown error!");
return QByteArray();
}
return QByteArray();
}

View file

@ -0,0 +1,193 @@
/**
* Copyright 2021 BrutalWizard (https://github.com/bru74lw1z4rd). All Rights Reserved.
*
* Licensed under the Apache License 2.0 (the "License"). You may not use
* this file except in compliance with the License. You can obtain a copy
* in the file LICENSE in the source distribution
**/
#include "include/QBlockCipher.h"
QSimpleCrypto::QBlockCipher::QBlockCipher()
{
}
///
/// \brief QSimpleCrypto::QBlockCipher::generateRandomBytes - Function generates random bytes by size.
/// \param size - Size of generated bytes.
/// \return Returns random bytes.
///
QByteArray QSimpleCrypto::QBlockCipher::generateRandomBytes(const int& size)
{
unsigned char arr[sizeof(size)];
RAND_bytes(arr, sizeof(size));
QByteArray buffer = QByteArray(reinterpret_cast<char*>(arr), size);
return buffer;
}
QByteArray QSimpleCrypto::QBlockCipher::generateSecureRandomBytes(const int &size)
{
unsigned char arr[sizeof(size)];
RAND_priv_bytes(arr, sizeof(size));
QByteArray buffer = QByteArray(reinterpret_cast<char*>(arr), size);
return buffer;
}
///
/// \brief QSimpleCrypto::QBlockCipher::encryptAesBlockCipher - Function encrypts data with Aes Block Cipher algorithm.
/// \param data - Data that will be encrypted.
/// \param key - AES key.
/// \param iv - Initialization vector.
/// \param password - Encryption password.
/// \param salt - Random delta.
/// \param rounds - Transformation rounds.
/// \param chiper - Can be used with OpenSSL EVP_CIPHER (ecb, cbc, cfb, ofb, ctr) - 128, 192, 256. Example: EVP_aes_256_cbc().
/// \param md - Hash algroitm (OpenSSL EVP_MD). Example: EVP_sha512().
/// \return Returns decrypted data or "", if error happened.
///
QByteArray QSimpleCrypto::QBlockCipher::encryptAesBlockCipher(QByteArray data, QByteArray key,
QByteArray iv,
const int& rounds, const EVP_CIPHER* cipher, const EVP_MD* md)
{
try {
/* Initialize EVP_CIPHER_CTX */
std::unique_ptr<EVP_CIPHER_CTX, void (*)(EVP_CIPHER_CTX*)> encryptionCipher { EVP_CIPHER_CTX_new(), EVP_CIPHER_CTX_free };
if (encryptionCipher == nullptr) {
throw std::runtime_error("Couldn't initialize \'encryptionCipher\'. EVP_CIPHER_CTX_new(). Error: " + QByteArray(ERR_error_string(ERR_get_error(), nullptr)));
}
/* Reinterpret values for multi use */
unsigned char* m_key = reinterpret_cast<unsigned char*>(key.data());
unsigned char* m_iv = reinterpret_cast<unsigned char*>(iv.data());
/* Set data length */
int cipherTextLength(data.size() + AES_BLOCK_SIZE);
int finalLength = 0;
/* Initialize cipcherText. Here encrypted data will be stored */
std::unique_ptr<unsigned char[]> cipherText { new unsigned char[cipherTextLength]() };
if (cipherText == nullptr) {
throw std::runtime_error("Couldn't allocate memory for 'cipherText'.");
}
// Bug here
// /* Start encryption with password based encryption routine */
// if (!EVP_BytesToKey(cipher, md, reinterpret_cast<unsigned char*>(salt.data()), reinterpret_cast<unsigned char*>(password.data()), password.length(), rounds, m_key, m_iv)) {
// throw std::runtime_error("Couldn't start encryption routine. EVP_BytesToKey(). Error: " + QByteArray(ERR_error_string(ERR_get_error(), nullptr)));
// }
/* Initialize encryption operation. */
if (!EVP_EncryptInit_ex(encryptionCipher.get(), cipher, nullptr, m_key, m_iv)) {
throw std::runtime_error("Couldn't initialize encryption operation. EVP_EncryptInit_ex(). Error: " + QByteArray(ERR_error_string(ERR_get_error(), nullptr)));
}
/*
* Provide the message to be encrypted, and obtain the encrypted output.
* EVP_EncryptUpdate can be called multiple times if necessary
*/
if (!EVP_EncryptUpdate(encryptionCipher.get(), cipherText.get(), &cipherTextLength, reinterpret_cast<const unsigned char*>(data.data()), data.size())) {
throw std::runtime_error("Couldn't provide message to be encrypted. EVP_EncryptUpdate(). Error: " + QByteArray(ERR_error_string(ERR_get_error(), nullptr)));
}
/* Finalize the encryption. Normally ciphertext bytes may be written at this stage */
if (!EVP_EncryptFinal(encryptionCipher.get(), cipherText.get() + cipherTextLength, &finalLength)) {
throw std::runtime_error("Couldn't finalize encryption. EVP_EncryptFinal(). Error: " + QByteArray(ERR_error_string(ERR_get_error(), nullptr)));
}
/* Finilize data to be readable with qt */
QByteArray encryptedData = QByteArray(reinterpret_cast<char*>(cipherText.get()), cipherTextLength + finalLength);
return encryptedData;
} catch (std::exception& exception) {
QSimpleCrypto::QBlockCipher::error.setError(1, exception.what());
return QByteArray();
} catch (...) {
QSimpleCrypto::QBlockCipher::error.setError(2, "Unknown error!");
return QByteArray();
}
return QByteArray();
}
///
/// \brief QSimpleCrypto::QBlockCipher::encryptAesBlockCipher - Function decrypts data with Aes Block Cipher algorithm.
/// \param data - Data that will be decrypted.
/// \param key - AES key.
/// \param iv - Initialization vector.
/// \param password - Decryption password.
/// \param salt - Random delta.
/// \param rounds - Transformation rounds.
/// \param chiper - Can be used with OpenSSL EVP_CIPHER (ecb, cbc, cfb, ofb, ctr) - 128, 192, 256. Example: EVP_aes_256_cbc().
/// \param md - Hash algroitm (OpenSSL EVP_MD). Example: EVP_sha512().
/// \return Returns decrypted data or "", if error happened.
///
QByteArray QSimpleCrypto::QBlockCipher::decryptAesBlockCipher(QByteArray data, QByteArray key,
QByteArray iv,
const int& rounds, const EVP_CIPHER* cipher, const EVP_MD* md)
{
try {
/* Initialize EVP_CIPHER_CTX */
std::unique_ptr<EVP_CIPHER_CTX, void (*)(EVP_CIPHER_CTX*)> decryptionCipher { EVP_CIPHER_CTX_new(), EVP_CIPHER_CTX_free };
if (decryptionCipher == nullptr) {
throw std::runtime_error("Couldn't initialize \'decryptionCipher\'. EVP_CIPHER_CTX_new(). Error: " + QByteArray(ERR_error_string(ERR_get_error(), nullptr)));
}
/* Reinterpret values for multi use */
unsigned char* m_key = reinterpret_cast<unsigned char*>(key.data());
unsigned char* m_iv = reinterpret_cast<unsigned char*>(iv.data());
/* Set data length */
int plainTextLength(data.size());
int finalLength = 0;
/* Initialize plainText. Here decrypted data will be stored */
std::unique_ptr<unsigned char[]> plainText { new unsigned char[plainTextLength + AES_BLOCK_SIZE]() };
if (plainText == nullptr) {
throw std::runtime_error("Couldn't allocate memory for \'plainText\'. EVP_CIPHER_CTX_new(). Error: " + QByteArray(ERR_error_string(ERR_get_error(), nullptr)));
}
// Bug here
// /* Start encryption with password based encryption routine */
// if (!EVP_BytesToKey(cipher, md, reinterpret_cast<const unsigned char*>(salt.data()), reinterpret_cast<const unsigned char*>(password.data()), password.length(), rounds, m_key, m_iv)) {
// throw std::runtime_error("Couldn't start decryption routine. EVP_BytesToKey(). Error: " + QByteArray(ERR_error_string(ERR_get_error(), nullptr)));
// }
/* Initialize decryption operation. */
if (!EVP_DecryptInit_ex(decryptionCipher.get(), cipher, nullptr, m_key, m_iv)) {
throw std::runtime_error("Couldn't initialize decryption operation. EVP_DecryptInit_ex(). Error: " + QByteArray(ERR_error_string(ERR_get_error(), nullptr)));
}
/*
* Provide the message to be decrypted, and obtain the plaintext output.
* EVP_DecryptUpdate can be called multiple times if necessary
*/
if (!EVP_DecryptUpdate(decryptionCipher.get(), plainText.get(), &plainTextLength, reinterpret_cast<const unsigned char*>(data.data()), data.size())) {
throw std::runtime_error("Couldn't provide message to be decrypted. EVP_DecryptUpdate(). Error: " + QByteArray(ERR_error_string(ERR_get_error(), nullptr)));
}
/*
* Finalize the decryption. A positive return value indicates success,
* anything else is a failure - the plaintext is not trustworthy.
*/
if (!EVP_DecryptFinal(decryptionCipher.get(), plainText.get() + plainTextLength, &finalLength)) {
throw std::runtime_error("Couldn't finalize decryption. EVP_DecryptFinal. Error: " + QByteArray(ERR_error_string(ERR_get_error(), nullptr)));
}
/* Finilize data to be readable with qt */
QByteArray decryptedData = QByteArray(reinterpret_cast<char*>(plainText.get()), plainTextLength + finalLength);
return decryptedData;
} catch (std::exception& exception) {
QSimpleCrypto::QBlockCipher::error.setError(1, exception.what());
return QByteArray(exception.what());
} catch (...) {
QSimpleCrypto::QBlockCipher::error.setError(2, "Unknown error!");
return QByteArray();
}
return QByteArray();
}

View file

@ -0,0 +1,6 @@
#include "include/QCryptoError.h"
QSimpleCrypto::QCryptoError::QCryptoError(QObject* parent)
: QObject(parent)
{
}

View file

@ -0,0 +1,274 @@
/**
* Copyright 2021 BrutalWizard (https://github.com/bru74lw1z4rd). All Rights Reserved.
*
* Licensed under the Apache License 2.0 (the "License"). You may not use
* this file except in compliance with the License. You can obtain a copy
* in the file LICENSE in the source distribution
**/
#include "include/QRsa.h"
QSimpleCrypto::QRsa::QRsa()
{
}
///
/// \brief QSimpleCrypto::QRSA::generateRsaKeys - Function generate Rsa Keys and returns them in OpenSSL structure.
/// \param bits - RSA key size.
/// \param rsaBigNumber - The exponent is an odd number, typically 3, 17 or 65537.
/// \return Returns 'OpenSSL RSA structure' or 'nullptr', if error happened. Returned value must be cleaned up with 'RSA_free()' to avoid memory leak.
///
RSA* QSimpleCrypto::QRsa::generateRsaKeys(const int& bits, const int& rsaBigNumber)
{
try {
/* Initialize big number */
std::unique_ptr<BIGNUM, void (*)(BIGNUM*)> bigNumber { BN_new(), BN_free };
if (bigNumber == nullptr) {
throw std::runtime_error("Couldn't initialize \'bigNumber\'. BN_new(). Error: " + QByteArray(ERR_error_string(ERR_get_error(), nullptr)));
return nullptr;
}
/* Set big number */
if (!BN_set_word(bigNumber.get(), rsaBigNumber)) {
throw std::runtime_error("Couldn't set bigNumber. BN_set_word(). Error: " + QByteArray(ERR_error_string(ERR_get_error(), nullptr)));
}
/* Initialize RSA */
RSA* rsa = nullptr;
if (!(rsa = RSA_new())) {
throw std::runtime_error("Couldn't initialize x509. X509_new(). Error: " + QByteArray(ERR_error_string(ERR_get_error(), nullptr)));
}
/* Generate key pair and store it in RSA */
if (!RSA_generate_key_ex(rsa, bits, bigNumber.get(), nullptr)) {
throw std::runtime_error("Couldn't generate RSA. RSA_generate_key_ex(). Error: " + QByteArray(ERR_error_string(ERR_get_error(), nullptr)));
}
return rsa;
} catch (std::exception& exception) {
QSimpleCrypto::QRsa::error.setError(1, exception.what());
return nullptr;
} catch (...) {
QSimpleCrypto::QRsa::error.setError(2, "Unknown error!");
return nullptr;
}
}
///
/// \brief QSimpleCrypto::QRSA::savePublicKey - Saves to file RSA public key.
/// \param rsa - OpenSSL RSA structure.
/// \param publicKeyFileName - Public key file name.
///
void QSimpleCrypto::QRsa::savePublicKey(RSA* rsa, const QByteArray& publicKeyFileName)
{
try {
/* Initialize BIO */
std::unique_ptr<BIO, void (*)(BIO*)> bioPublicKey { BIO_new_file(publicKeyFileName.data(), "w+"), BIO_free_all };
if (bioPublicKey == nullptr) {
throw std::runtime_error("Couldn't initialize \'bioPublicKey\'. BIO_new_file(). Error: " + QByteArray(ERR_error_string(ERR_get_error(), nullptr)));
}
/* Write public key on file */
if (!PEM_write_bio_RSA_PUBKEY(bioPublicKey.get(), rsa)) {
throw std::runtime_error("Couldn't save public key. PEM_write_bio_RSAPublicKey(). Error: " + QByteArray(ERR_error_string(ERR_get_error(), nullptr)));
}
} catch (std::exception& exception) {
QSimpleCrypto::QRsa::error.setError(1, exception.what());
return;
} catch (...) {
QSimpleCrypto::QRsa::error.setError(2, "Unknown error!");
return;
}
}
///
/// \brief QSimpleCrypto::QRSA::savePrivateKey - Saves to file RSA private key.
/// \param rsa - OpenSSL RSA structure.
/// \param privateKeyFileName - Private key file name.
/// \param password - Private key password.
/// \param cipher - Can be used with 'OpenSSL EVP_CIPHER' (ecb, cbc, cfb, ofb, ctr) - 128, 192, 256. Example: EVP_aes_256_cbc().
///
void QSimpleCrypto::QRsa::savePrivateKey(RSA* rsa, const QByteArray& privateKeyFileName, QByteArray password, const EVP_CIPHER* cipher)
{
try {
/* Initialize BIO */
std::unique_ptr<BIO, void (*)(BIO*)> bioPrivateKey { BIO_new_file(privateKeyFileName.data(), "w+"), BIO_free_all };
if (bioPrivateKey == nullptr) {
throw std::runtime_error("Couldn't initialize bioPrivateKey. BIO_new_file(). Error: " + QByteArray(ERR_error_string(ERR_get_error(), nullptr)));
}
/* Write private key to file */
if (!PEM_write_bio_RSAPrivateKey(bioPrivateKey.get(), rsa, cipher, reinterpret_cast<unsigned char*>(password.data()), password.size(), nullptr, nullptr)) {
throw std::runtime_error("Couldn't save private key. PEM_write_bio_RSAPrivateKey(). Error: " + QByteArray(ERR_error_string(ERR_get_error(), nullptr)));
}
} catch (std::exception& exception) {
QSimpleCrypto::QRsa::error.setError(1, exception.what());
return;
} catch (...) {
QSimpleCrypto::QRsa::error.setError(2, "Unknown error!");
return;
}
}
///
/// \brief QSimpleCrypto::QRSA::getPublicKeyFromFile - Gets RSA public key from a file.
/// \param filePath - File path to public key file.
/// \return Returns 'OpenSSL EVP_PKEY structure' or 'nullptr', if error happened. Returned value must be cleaned up with 'EVP_PKEY_free()' to avoid memory leak.
///
EVP_PKEY* QSimpleCrypto::QRsa::getPublicKeyFromFile(const QByteArray& filePath)
{
try {
/* Initialize BIO */
std::unique_ptr<BIO, void (*)(BIO*)> bioPublicKey { BIO_new_file(filePath.data(), "r"), BIO_free_all };
if (bioPublicKey == nullptr) {
throw std::runtime_error("Couldn't initialize bioPublicKey. BIO_new_file(). Error: " + QByteArray(ERR_error_string(ERR_get_error(), nullptr)));
}
/* Initialize EVP_PKEY */
EVP_PKEY* keyStore = nullptr;
if (!(keyStore = EVP_PKEY_new())) {
throw std::runtime_error("Couldn't initialize keyStore. EVP_PKEY_new(). Error: " + QByteArray(ERR_error_string(ERR_get_error(), nullptr)));
}
/* Write private key to file */
if (!PEM_read_bio_PUBKEY(bioPublicKey.get(), &keyStore, nullptr, nullptr)) {
throw std::runtime_error("Couldn't read private key. PEM_read_bio_PrivateKey(). Error: " + QByteArray(ERR_error_string(ERR_get_error(), nullptr)));
}
return keyStore;
} catch (std::exception& exception) {
QSimpleCrypto::QRsa::error.setError(1, exception.what());
return nullptr;
} catch (...) {
QSimpleCrypto::QRsa::error.setError(2, "Unknown error!");
return nullptr;
}
}
///
/// \brief QSimpleCrypto::QRSA::getPrivateKeyFromFile - Gets RSA private key from a file.
/// \param filePath - File path to private key file.
/// \param password - Private key password.
/// \return - Returns 'OpenSSL EVP_PKEY structure' or 'nullptr', if error happened. Returned value must be cleaned up with 'EVP_PKEY_free()' to avoid memory leak.
///
EVP_PKEY* QSimpleCrypto::QRsa::getPrivateKeyFromFile(const QByteArray& filePath, const QByteArray& password)
{
try {
/* Initialize BIO */
std::unique_ptr<BIO, void (*)(BIO*)> bioPrivateKey { BIO_new_file(filePath.data(), "r"), BIO_free_all };
if (bioPrivateKey == nullptr) {
throw std::runtime_error("Couldn't initialize bioPrivateKey. BIO_new_file(). Error: " + QByteArray(ERR_error_string(ERR_get_error(), nullptr)));
}
/* Initialize EVP_PKEY */
EVP_PKEY* keyStore = nullptr;
if (!(keyStore = EVP_PKEY_new())) {
throw std::runtime_error("Couldn't initialize keyStore. EVP_PKEY_new(). Error: " + QByteArray(ERR_error_string(ERR_get_error(), nullptr)));
}
/* Write private key to file */
if (!PEM_read_bio_PrivateKey(bioPrivateKey.get(), &keyStore, nullptr, (void*)password.data())) {
throw std::runtime_error("Couldn't read private key. PEM_read_bio_PrivateKey(). Error: " + QByteArray(ERR_error_string(ERR_get_error(), nullptr)));
}
return keyStore;
} catch (std::exception& exception) {
QSimpleCrypto::QRsa::error.setError(1, exception.what());
return nullptr;
} catch (...) {
QSimpleCrypto::QRsa::error.setError(2, "Unknown error!");
return nullptr;
}
}
///
/// \brief QSimpleCrypto::QRSA::encrypt - Encrypt data with RSA algorithm.
/// \param plaintext - Text that must be encrypted.
/// \param rsa - OpenSSL RSA structure.
/// \param encryptType - Public or private encrypt type. (PUBLIC_ENCRYPT, PRIVATE_ENCRYPT).
/// \param padding - OpenSSL RSA padding can be used with: 'RSA_PKCS1_PADDING', 'RSA_NO_PADDING' and etc.
/// \return Returns encrypted data or "", if error happened.
///
QByteArray QSimpleCrypto::QRsa::encrypt(QByteArray plainText, RSA* rsa, const int& encryptType, const int& padding)
{
try {
/* Initialize array. Here encrypted data will be saved */
std::unique_ptr<unsigned char[]> cipherText { new unsigned char[RSA_size(rsa)]() };
if (cipherText == nullptr) {
throw std::runtime_error("Couldn't allocate memory for 'cipherText'.");
}
/* Result of encryption operation */
short int result = 0;
/* Execute encryption operation */
if (encryptType == PublicDecrypt) {
result = RSA_public_encrypt(plainText.size(), reinterpret_cast<unsigned char*>(plainText.data()), cipherText.get(), rsa, padding);
} else if (encryptType == PrivateDecrypt) {
result = RSA_private_encrypt(plainText.size(), reinterpret_cast<unsigned char*>(plainText.data()), cipherText.get(), rsa, padding);
}
/* Check for result */
if (result <= -1) {
throw std::runtime_error("Couldn't encrypt data. Error: " + QByteArray(ERR_error_string(ERR_get_error(), nullptr)));
}
/* Get encrypted data */
const QByteArray& encryptedData = QByteArray(reinterpret_cast<char*>(cipherText.get()), RSA_size(rsa));
return encryptedData;
} catch (std::exception& exception) {
QSimpleCrypto::QRsa::error.setError(1, exception.what());
return "";
} catch (...) {
QSimpleCrypto::QRsa::error.setError(2, "Unknown error!");
return "";
}
}
///
/// \brief QSimpleCrypto::QRSA::decrypt - Decrypt data with RSA algorithm.
/// \param cipherText - Text that must be decrypted.
/// \param rsa - OpenSSL RSA structure.
/// \param decryptType - Public or private type. (PUBLIC_DECRYPT, PRIVATE_DECRYPT).
/// \param padding - RSA padding can be used with: 'RSA_PKCS1_PADDING', 'RSA_NO_PADDING' and etc.
/// \return - Returns decrypted data or "", if error happened.
///
QByteArray QSimpleCrypto::QRsa::decrypt(QByteArray cipherText, RSA* rsa, const int& decryptType, const int& padding)
{
try {
/* Initialize array. Here decrypted data will be saved */
std::unique_ptr<unsigned char[]> plainText { new unsigned char[cipherText.size()]() };
if (plainText == nullptr) {
throw std::runtime_error("Couldn't allocate memory for 'plainText'.");
}
/* Result of decryption operation */
short int result = 0;
/* Execute decryption operation */
if (decryptType == PublicDecrypt) {
result = RSA_public_decrypt(RSA_size(rsa), reinterpret_cast<unsigned char*>(cipherText.data()), plainText.get(), rsa, padding);
} else if (decryptType == PrivateDecrypt) {
result = RSA_private_decrypt(RSA_size(rsa), reinterpret_cast<unsigned char*>(cipherText.data()), plainText.get(), rsa, padding);
}
/* Check for result */
if (result <= -1) {
throw std::runtime_error("Couldn't decrypt data. Error: " + QByteArray(ERR_error_string(ERR_get_error(), nullptr)));
}
/* Get decrypted data */
const QByteArray& decryptedData = QByteArray(reinterpret_cast<char*>(plainText.get()));
return decryptedData;
} catch (std::exception& exception) {
QSimpleCrypto::QRsa::error.setError(1, exception.what());
return "";
} catch (...) {
QSimpleCrypto::QRsa::error.setError(2, "Unknown error!");
return "";
}
}

View file

@ -0,0 +1,234 @@
/**
* Copyright 2021 BrutalWizard (https://github.com/bru74lw1z4rd). All Rights Reserved.
*
* Licensed under the Apache License 2.0 (the "License"). You may not use
* this file except in compliance with the License. You can obtain a copy
* in the file LICENSE in the source distribution
**/
#include "include/QX509.h"
QSimpleCrypto::QX509::QX509()
{
}
///
/// \brief QSimpleCrypto::QX509::loadCertificateFromFile - Function load X509 from file and returns OpenSSL structure.
/// \param fileName - File path to certificate.
/// \return Returns OpenSSL X509 structure or nullptr, if error happened. Returned value must be cleaned up with 'X509_free' to avoid memory leak.
///
X509* QSimpleCrypto::QX509::loadCertificateFromFile(const QByteArray& fileName)
{
try {
/* Initialize X509 */
X509* x509 = nullptr;
if (!(x509 = X509_new())) {
throw std::runtime_error("Couldn't initialize X509. X509_new(). Error: " + QByteArray(ERR_error_string(ERR_get_error(), nullptr)));
}
/* Initialize BIO */
std::unique_ptr<BIO, void (*)(BIO*)> certFile { BIO_new_file(fileName.data(), "r+"), BIO_free_all };
if (certFile == nullptr) {
throw std::runtime_error("Couldn't initialize certFile. BIO_new_file(). Error: " + QByteArray(ERR_error_string(ERR_get_error(), nullptr)));
}
/* Read file */
if (!PEM_read_bio_X509(certFile.get(), &x509, nullptr, nullptr)) {
throw std::runtime_error("Couldn't read certificate file from disk. PEM_read_bio_X509(). Error: " + QByteArray(ERR_error_string(ERR_get_error(), nullptr)));
}
return x509;
} catch (std::exception& exception) {
QSimpleCrypto::QX509::error.setError(1, exception.what());
return nullptr;
} catch (...) {
QSimpleCrypto::QX509::error.setError(2, "Unknown error!");
return nullptr;
}
}
///
/// \brief QSimpleCrypto::QX509::signCertificate - Function signs X509 certificate and returns signed X509 OpenSSL structure.
/// \param endCertificate - Certificate that will be signed
/// \param caCertificate - CA certificate that will sign end certificate
/// \param caPrivateKey - CA certificate private key
/// \param fileName - With that name certificate will be saved. Leave "", if don't need to save it
/// \return Returns OpenSSL X509 structure or nullptr, if error happened.
///
X509* QSimpleCrypto::QX509::signCertificate(X509* endCertificate, X509* caCertificate, EVP_PKEY* caPrivateKey, const QByteArray& fileName)
{
try {
/* Set issuer to CA's subject. */
if (!X509_set_issuer_name(endCertificate, X509_get_subject_name(caCertificate))) {
throw std::runtime_error("Couldn't set issuer name for X509. X509_set_issuer_name(). Error: " + QByteArray(ERR_error_string(ERR_get_error(), nullptr)));
}
/* Sign the certificate with key. */
if (!X509_sign(endCertificate, caPrivateKey, EVP_sha256())) {
throw std::runtime_error("Couldn't sign X509. X509_sign(). Error: " + QByteArray(ERR_error_string(ERR_get_error(), nullptr)));
}
/* Write certificate file on disk. If needed */
if (!fileName.isEmpty()) {
/* Initialize BIO */
std::unique_ptr<BIO, void (*)(BIO*)> certFile { BIO_new_file(fileName.data(), "w+"), BIO_free_all };
if (certFile == nullptr) {
throw std::runtime_error("Couldn't initialize certFile. BIO_new_file(). Error: " + QByteArray(ERR_error_string(ERR_get_error(), nullptr)));
}
/* Write file on disk */
if (!PEM_write_bio_X509(certFile.get(), endCertificate)) {
throw std::runtime_error("Couldn't write certificate file on disk. PEM_write_bio_X509(). Error: " + QByteArray(ERR_error_string(ERR_get_error(), nullptr)));
}
}
return endCertificate;
} catch (std::exception& exception) {
QSimpleCrypto::QX509::error.setError(1, exception.what());
return nullptr;
} catch (...) {
QSimpleCrypto::QX509::error.setError(2, "Unknown error!");
return nullptr;
}
}
///
/// \brief QSimpleCrypto::QX509::verifyCertificate - Function verifies X509 certificate and returns verified X509 OpenSSL structure.
/// \param x509 - OpenSSL X509. That certificate will be verified.
/// \param store - Trusted certificate must be added to X509_Store with 'addCertificateToStore(X509_STORE* ctx, X509* x509)'.
/// \return Returns OpenSSL X509 structure or nullptr, if error happened
///
X509* QSimpleCrypto::QX509::verifyCertificate(X509* x509, X509_STORE* store)
{
try {
/* Initialize X509_STORE_CTX */
std::unique_ptr<X509_STORE_CTX, void (*)(X509_STORE_CTX*)> ctx { X509_STORE_CTX_new(), X509_STORE_CTX_free };
if (ctx == nullptr) {
throw std::runtime_error("Couldn't initialize keyStore. EVP_PKEY_new(). Error: " + QByteArray(ERR_error_string(ERR_get_error(), nullptr)));
}
/* Set up CTX for a subsequent verification operation */
if (!X509_STORE_CTX_init(ctx.get(), store, x509, nullptr)) {
throw std::runtime_error("Couldn't initialize X509_STORE_CTX. X509_STORE_CTX_init(). Error: " + QByteArray(ERR_error_string(ERR_get_error(), nullptr)));
}
/* Verify X509 */
if (!X509_verify_cert(ctx.get())) {
throw std::runtime_error("Couldn't verify cert. X509_verify_cert(). Error: " + QByteArray(ERR_error_string(ERR_get_error(), nullptr)));
}
return x509;
} catch (std::exception& exception) {
QSimpleCrypto::QX509::error.setError(1, exception.what());
return nullptr;
} catch (...) {
QSimpleCrypto::QX509::error.setError(2, "Unknown error!");
return nullptr;
}
}
///
/// \brief QSimpleCrypto::QX509::generateSelfSignedCertificate - Function generatesand returns self signed X509.
/// \param rsa - OpenSSL RSA.
/// \param additionalData - Certificate information.
/// \param certificateFileName - With that name certificate will be saved. Leave "", if don't need to save it.
/// \param md - OpenSSL EVP_MD structure. Example: EVP_sha512().
/// \param serialNumber - X509 certificate serial number.
/// \param version - X509 certificate version.
/// \param notBefore - X509 start date.
/// \param notAfter - X509 end date.
/// \return Returns OpenSSL X509 structure or nullptr, if error happened. Returned value must be cleaned up with 'X509_free' to avoid memory leak.
///
X509* QSimpleCrypto::QX509::generateSelfSignedCertificate(const RSA* rsa, const QMap<QByteArray, QByteArray>& additionalData,
const QByteArray& certificateFileName, const EVP_MD* md,
const long& serialNumber, const long& version,
const long& notBefore, const long& notAfter)
{
try {
/* Initialize X509 */
X509* x509 = nullptr;
if (!(x509 = X509_new())) {
throw std::runtime_error("Couldn't initialize X509. X509_new(). Error: " + QByteArray(ERR_error_string(ERR_get_error(), nullptr)));
}
/* Initialize EVP_PKEY */
std::unique_ptr<EVP_PKEY, void (*)(EVP_PKEY*)> keyStore { EVP_PKEY_new(), EVP_PKEY_free };
if (keyStore == nullptr) {
throw std::runtime_error("Couldn't initialize keyStore. EVP_PKEY_new(). Error: " + QByteArray(ERR_error_string(ERR_get_error(), nullptr)));
}
/* Sign rsa key */
if (!EVP_PKEY_assign_RSA(keyStore.get(), rsa)) {
throw std::runtime_error("Couldn't assign rsa. EVP_PKEY_assign_RSA(). Error: " + QByteArray(ERR_error_string(ERR_get_error(), nullptr)));
}
/* Set certificate serial number. */
if (!ASN1_INTEGER_set(X509_get_serialNumber(x509), serialNumber)) {
throw std::runtime_error("Couldn't set serial number. ASN1_INTEGER_set(). Error: " + QByteArray(ERR_error_string(ERR_get_error(), nullptr)));
}
/* Set certificate version */
if (!X509_set_version(x509, version)) {
throw std::runtime_error("Couldn't set version. X509_set_version(). Error: " + QByteArray(ERR_error_string(ERR_get_error(), nullptr)));
}
/* Set certificate creation and expiration date */
X509_gmtime_adj(X509_get_notBefore(x509), notBefore);
X509_gmtime_adj(X509_get_notAfter(x509), notAfter);
/* Set certificate public key */
if (!X509_set_pubkey(x509, keyStore.get())) {
throw std::runtime_error("Couldn't set public key. X509_set_pubkey(). Error: " + QByteArray(ERR_error_string(ERR_get_error(), nullptr)));
}
/* Initialize X509_NAME */
X509_NAME* x509Name = X509_get_subject_name(x509);
if (x509Name == nullptr) {
throw std::runtime_error("Couldn't initialize X509_NAME. X509_NAME(). Error: " + QByteArray(ERR_error_string(ERR_get_error(), nullptr)));
}
/* Add additional data to certificate */
QMapIterator<QByteArray, QByteArray> certificateInformationList(additionalData);
while (certificateInformationList.hasNext()) {
/* Read next item in list */
certificateInformationList.next();
/* Set additional data */
if (!X509_NAME_add_entry_by_txt(x509Name, certificateInformationList.key().data(), MBSTRING_UTF8, reinterpret_cast<const unsigned char*>(certificateInformationList.value().data()), -1, -1, 0)) {
throw std::runtime_error("Couldn't set additional information. X509_NAME_add_entry_by_txt(). Error: " + QByteArray(ERR_error_string(ERR_get_error(), nullptr)));
}
}
/* Set certificate info */
if (!X509_set_issuer_name(x509, x509Name)) {
throw std::runtime_error("Couldn't set issuer name. X509_set_issuer_name(). Error: " + QByteArray(ERR_error_string(ERR_get_error(), nullptr)));
}
/* Sign certificate */
if (!X509_sign(x509, keyStore.get(), md)) {
throw std::runtime_error("Couldn't sign X509. X509_sign(). Error: " + QByteArray(ERR_error_string(ERR_get_error(), nullptr)));
}
/* Write certificate file on disk. If needed */
if (!certificateFileName.isEmpty()) {
/* Initialize BIO */
std::unique_ptr<BIO, void (*)(BIO*)> certFile { BIO_new_file(certificateFileName.data(), "w+"), BIO_free_all };
if (certFile == nullptr) {
throw std::runtime_error("Couldn't initialize certFile. BIO_new_file(). Error: " + QByteArray(ERR_error_string(ERR_get_error(), nullptr)));
}
/* Write file on disk */
if (!PEM_write_bio_X509(certFile.get(), x509)) {
throw std::runtime_error("Couldn't write certificate file on disk. PEM_write_bio_X509(). Error: " + QByteArray(ERR_error_string(ERR_get_error(), nullptr)));
}
}
return x509;
} catch (std::exception& exception) {
QSimpleCrypto::QX509::error.setError(1, exception.what());
return nullptr;
} catch (...) {
QSimpleCrypto::QX509::error.setError(2, "Unknown error!");
return nullptr;
}
}

View file

@ -0,0 +1,176 @@
/**
* Copyright 2021 BrutalWizard (https://github.com/bru74lw1z4rd). All Rights Reserved.
*
* Licensed under the Apache License 2.0 (the "License"). You may not use
* this file except in compliance with the License. You can obtain a copy
* in the file LICENSE in the source distribution
**/
#include "include/QX509Store.h"
QSimpleCrypto::QX509Store::QX509Store()
{
}
///
/// \brief QSimpleCrypto::QX509::addCertificateToStore
/// \param store - OpenSSL X509_STORE.
/// \param x509 - OpenSSL X509.
/// \return Returns 'true' on success and 'false', if error happened.
///
bool QSimpleCrypto::QX509Store::addCertificateToStore(X509_STORE* store, X509* x509)
{
if (!X509_STORE_add_cert(store, x509)) {
QSimpleCrypto::QX509Store::error.setError(1, "Couldn't add certificate to X509_STORE. X509_STORE_add_cert(). Error: " + QByteArray(ERR_error_string(ERR_get_error(), nullptr)));
return false;
}
return true;
}
///
/// \brief QSimpleCrypto::QX509Store::addLookup
/// \param store - OpenSSL X509_STORE.
/// \param method - OpenSSL X509_LOOKUP_METHOD. Example: X509_LOOKUP_file.
/// \return Returns 'true' on success and 'false', if error happened.
///
bool QSimpleCrypto::QX509Store::addLookup(X509_STORE* store, X509_LOOKUP_METHOD* method)
{
if (!X509_STORE_add_lookup(store, method)) {
QSimpleCrypto::QX509Store::error.setError(1, "Couldn't add lookup to X509_STORE. X509_STORE_add_lookup(). Error: " + QByteArray(ERR_error_string(ERR_get_error(), nullptr)));
return false;
}
return true;
}
///
/// \brief QSimpleCrypto::QX509Store::setCertificateDepth
/// \param store - OpenSSL X509_STORE.
/// \param depth - That is the maximum number of untrusted CA certificates that can appear in a chain. Example: 0.
/// \return Returns 'true' on success and 'false', if error happened.
///
bool QSimpleCrypto::QX509Store::setDepth(X509_STORE* store, const int& depth)
{
if (!X509_STORE_set_depth(store, depth)) {
QSimpleCrypto::QX509Store::error.setError(1, "Couldn't set depth for X509_STORE. X509_STORE_set_depth(). Error: " + QByteArray(ERR_error_string(ERR_get_error(), nullptr)));
return false;
}
return true;
}
///
/// \brief QSimpleCrypto::QX509Store::setFlag
/// \param store - OpenSSL X509_STORE.
/// \param flag - The verification flags consists of zero or more of the following flags ored together. Example: X509_V_FLAG_CRL_CHECK.
/// \return Returns 'true' on success and 'false', if error happened.
///
bool QSimpleCrypto::QX509Store::setFlag(X509_STORE* store, const unsigned long& flag)
{
if (!X509_STORE_set_flags(store, flag)) {
QSimpleCrypto::QX509Store::error.setError(1, "Couldn't set flag for X509_STORE. X509_STORE_set_flags(). Error: " + QByteArray(ERR_error_string(ERR_get_error(), nullptr)));
return false;
}
return true;
}
///
/// \brief QSimpleCrypto::QX509Store::setFlag
/// \param store - OpenSSL X509_STORE.
/// \param purpose - Verification purpose in param to purpose. Example: X509_PURPOSE_ANY.
/// \return Returns 'true' on success and 'false', if error happened.
///
bool QSimpleCrypto::QX509Store::setPurpose(X509_STORE* store, const int& purpose)
{
if (!X509_STORE_set_purpose(store, purpose)) {
QSimpleCrypto::QX509Store::error.setError(1, "Couldn't set purpose for X509_STORE. X509_STORE_set_purpose(). Error: " + QByteArray(ERR_error_string(ERR_get_error(), nullptr)));
return false;
}
return true;
}
///
/// \brief QSimpleCrypto::QX509Store::setTrust
/// \param store - OpenSSL X509_STORE.
/// \param trust - Trust Level. Example: X509_TRUST_SSL_SERVER.
/// \return Returns 'true' on success and 'false', if error happened.
///
bool QSimpleCrypto::QX509Store::setTrust(X509_STORE* store, const int& trust)
{
if (!X509_STORE_set_trust(store, trust)) {
QSimpleCrypto::QX509Store::error.setError(1, "Couldn't set trust for X509_STORE. X509_STORE_set_trust(). Error: " + QByteArray(ERR_error_string(ERR_get_error(), nullptr)));
return false;
}
return true;
}
///
/// \brief QSimpleCrypto::QX509Store::setDefaultPaths
/// \param store - OpenSSL X509_STORE.
/// \return Returns 'true' on success and 'false', if error happened.
///
bool QSimpleCrypto::QX509Store::setDefaultPaths(X509_STORE* store)
{
if (!X509_STORE_set_default_paths(store)) {
QSimpleCrypto::QX509Store::error.setError(1, "Couldn't set default paths for X509_STORE. X509_STORE_set_default_paths(). Error: " + QByteArray(ERR_error_string(ERR_get_error(), nullptr)));
return false;
}
return true;
}
///
/// \brief QSimpleCrypto::QX509Store::loadLocations
/// \param store - OpenSSL X509_STORE.
/// \param fileName - File name. Example: "caCertificate.pem".
/// \param dirPath - Path to file. Example: "path/To/File".
/// \return Returns 'true' on success and 'false', if error happened.
///
bool QSimpleCrypto::QX509Store::loadLocations(X509_STORE* store, const QByteArray& fileName, const QByteArray& dirPath)
{
if (!X509_STORE_load_locations(store, fileName, dirPath)) {
QSimpleCrypto::QX509Store::error.setError(1, "Couldn't load locations for X509_STORE. X509_STORE_load_locations(). Error: " + QByteArray(ERR_error_string(ERR_get_error(), nullptr)));
return false;
}
return true;
}
///
/// \brief QSimpleCrypto::QX509Store::loadLocations
/// \param store - OpenSSL X509_STORE.
/// \param file - Qt QFile that will be loaded.
/// \return Returns 'true' on success and 'false', if error happened.
///
bool QSimpleCrypto::QX509Store::loadLocations(X509_STORE* store, const QFile& file)
{
/* Initialize QFileInfo to read information about file */
QFileInfo info(file);
if (!X509_STORE_load_locations(store, info.fileName().toLocal8Bit(), info.absoluteDir().path().toLocal8Bit())) {
QSimpleCrypto::QX509Store::error.setError(1, "Couldn't load locations for X509_STORE. X509_STORE_load_locations(). Error: " + QByteArray(ERR_error_string(ERR_get_error(), nullptr)));
return false;
}
return true;
}
///
/// \brief QSimpleCrypto::QX509Store::loadLocations
/// \param store - OpenSSL X509_STORE.
/// \param fileInfo - Qt QFileInfo.
/// \return Returns 'true' on success and 'false', if error happened.
///
bool QSimpleCrypto::QX509Store::loadLocations(X509_STORE* store, const QFileInfo& fileInfo)
{
if (!X509_STORE_load_locations(store, fileInfo.fileName().toLocal8Bit(), fileInfo.absoluteDir().path().toLocal8Bit())) {
QSimpleCrypto::QX509Store::error.setError(1, "Couldn't load locations for X509_STORE. X509_STORE_load_locations(). Error: " + QByteArray(ERR_error_string(ERR_get_error(), nullptr)));
return false;
}
return true;
}

1
client/3rd/qtkeychain Submodule

@ -0,0 +1 @@
Subproject commit f197cdb935b0cfd9881fdc6860874cb8379d1238

View file

@ -0,0 +1,205 @@
#include "amnezia_application.h"
#include <QFontDatabase>
#include <QTimer>
#include <QTranslator>
#include "QZXing.h"
#include "core/servercontroller.h"
#include "debug.h"
#include "defines.h"
#include "platforms/ios/QRCodeReaderBase.h"
#include "ui/pages.h"
#include "ui/pages_logic/AppSettingsLogic.h"
#include "ui/pages_logic/GeneralSettingsLogic.h"
#include "ui/pages_logic/NetworkSettingsLogic.h"
#include "ui/pages_logic/NewServerProtocolsLogic.h"
#include "ui/pages_logic/QrDecoderLogic.h"
#include "ui/pages_logic/ServerConfiguringProgressLogic.h"
#include "ui/pages_logic/ServerContainersLogic.h"
#include "ui/pages_logic/ServerListLogic.h"
#include "ui/pages_logic/ServerSettingsLogic.h"
#include "ui/pages_logic/ServerContainersLogic.h"
#include "ui/pages_logic/ShareConnectionLogic.h"
#include "ui/pages_logic/SitesLogic.h"
#include "ui/pages_logic/StartPageLogic.h"
#include "ui/pages_logic/VpnLogic.h"
#include "ui/pages_logic/WizardLogic.h"
#include "ui/pages_logic/protocols/CloakLogic.h"
#include "ui/pages_logic/protocols/OpenVpnLogic.h"
#include "ui/pages_logic/protocols/ShadowSocksLogic.h"
#if defined(Q_OS_IOS)
#include "platforms/ios/QtAppDelegate-C-Interface.h"
#endif
#if defined(Q_OS_ANDROID) || defined(Q_OS_IOS)
AmneziaApplication::AmneziaApplication(int &argc, char *argv[]):
AMNEZIA_BASE_CLASS(argc, argv)
#else
AmneziaApplication::AmneziaApplication(int &argc, char *argv[], bool allowSecondary,
SingleApplication::Options options, int timeout, const QString &userData):
SingleApplication(argc, argv, allowSecondary, options, timeout, userData)
#endif
{
setQuitOnLastWindowClosed(false);
m_settings = std::shared_ptr<Settings>(new Settings);
m_serverController = std::shared_ptr<ServerController>(new ServerController(m_settings, this));
m_configurator = std::shared_ptr<VpnConfigurator>(new VpnConfigurator(m_settings, m_serverController, this));
}
AmneziaApplication::~AmneziaApplication()
{
if (m_engine) {
QObject::disconnect(m_engine, 0,0,0);
delete m_engine;
}
if (m_uiLogic) {
QObject::disconnect(m_uiLogic, 0,0,0);
delete m_uiLogic;
}
if (m_protocolProps) delete m_protocolProps;
if (m_containerProps) delete m_containerProps;
}
void AmneziaApplication::init()
{
m_engine = new QQmlApplicationEngine;
m_uiLogic = new UiLogic(m_settings, m_configurator, m_serverController);
const QUrl url(QStringLiteral("qrc:/ui/qml/main.qml"));
QObject::connect(m_engine, &QQmlApplicationEngine::objectCreated,
this, [url](QObject *obj, const QUrl &objUrl) {
if (!obj && url == objUrl)
QCoreApplication::exit(-1);
}, Qt::QueuedConnection);
m_engine->rootContext()->setContextProperty("Debug", &Debug::Instance());
m_uiLogic->registerPagesLogic();
#if defined(Q_OS_IOS)
setStartPageLogic(m_uiLogic->pageLogic<StartPageLogic>());
#endif
m_engine->load(url);
if (m_engine->rootObjects().size() > 0) {
m_uiLogic->setQmlRoot(m_engine->rootObjects().at(0));
}
if (m_settings->isSaveLogs()) {
if (!Debug::init()) {
qWarning() << "Initialization of debug subsystem failed";
}
}
#ifdef Q_OS_WIN
if (m_parser.isSet("a")) m_uiLogic->showOnStartup();
else emit m_uiLogic->show();
#else
m_uiLogic->showOnStartup();
#endif
// TODO - fix
#if !defined(Q_OS_ANDROID) && !defined(Q_OS_IOS)
if (isPrimary()) {
QObject::connect(this, &SingleApplication::instanceStarted, m_uiLogic, [this](){
qDebug() << "Secondary instance started, showing this window instead";
emit m_uiLogic->show();
emit m_uiLogic->raise();
});
}
#endif
}
void AmneziaApplication::registerTypes()
{
QZXing::registerQMLTypes();
qRegisterMetaType<VpnProtocol::VpnConnectionState>("VpnProtocol::VpnConnectionState");
qRegisterMetaType<ServerCredentials>("ServerCredentials");
qRegisterMetaType<DockerContainer>("DockerContainer");
qRegisterMetaType<TransportProto>("TransportProto");
qRegisterMetaType<Proto>("Proto");
qRegisterMetaType<ServiceType>("ServiceType");
qRegisterMetaType<Page>("Page");
qRegisterMetaType<VpnProtocol::VpnConnectionState>("ConnectionState");
qRegisterMetaType<PageProtocolLogicBase *>("PageProtocolLogicBase *");
declareQmlPageEnum();
declareQmlProtocolEnum();
declareQmlContainerEnum();
qmlRegisterType<PageType>("PageType", 1, 0, "PageType");
qmlRegisterType<QRCodeReader>("QRCodeReader", 1, 0, "QRCodeReader");
m_containerProps = new ContainerProps;
qmlRegisterSingletonInstance("ContainerProps", 1, 0, "ContainerProps", m_containerProps);
m_protocolProps = new ProtocolProps;
qmlRegisterSingletonInstance("ProtocolProps", 1, 0, "ProtocolProps", m_protocolProps);
}
void AmneziaApplication::loadFonts()
{
QFontDatabase::addApplicationFont(":/fonts/Lato-Black.ttf");
QFontDatabase::addApplicationFont(":/fonts/Lato-BlackItalic.ttf");
QFontDatabase::addApplicationFont(":/fonts/Lato-Bold.ttf");
QFontDatabase::addApplicationFont(":/fonts/Lato-BoldItalic.ttf");
QFontDatabase::addApplicationFont(":/fonts/Lato-Italic.ttf");
QFontDatabase::addApplicationFont(":/fonts/Lato-Light.ttf");
QFontDatabase::addApplicationFont(":/fonts/Lato-LightItalic.ttf");
QFontDatabase::addApplicationFont(":/fonts/Lato-Regular.ttf");
QFontDatabase::addApplicationFont(":/fonts/Lato-Thin.ttf");
QFontDatabase::addApplicationFont(":/fonts/Lato-ThinItalic.ttf");
}
void AmneziaApplication::loadTranslator()
{
m_translator = new QTranslator;
if (m_translator->load(QLocale(), QString("amneziavpn"), QLatin1String("_"), QLatin1String(":/translations"))) {
installTranslator(m_translator);
}
}
bool AmneziaApplication::parseCommands()
{
m_parser.setApplicationDescription(APPLICATION_NAME);
m_parser.addHelpOption();
m_parser.addVersionOption();
QCommandLineOption c_autostart {{"a", "autostart"}, "System autostart"};
m_parser.addOption(c_autostart);
QCommandLineOption c_cleanup {{"c", "cleanup"}, "Cleanup logs"};
m_parser.addOption(c_cleanup);
m_parser.process(*this);
if (m_parser.isSet(c_cleanup)) {
Debug::cleanUp();
QTimer::singleShot(100, this, [this]{
quit();
});
exec();
return false;
}
return true;
}
QQmlApplicationEngine *AmneziaApplication::qmlEngine() const
{
return m_engine;
}

View file

@ -0,0 +1,62 @@
#ifndef AMNEZIA_APPLICATION_H
#define AMNEZIA_APPLICATION_H
#include <QApplication>
#include <QGuiApplication>
#include <QCommandLineParser>
#include <QQmlApplicationEngine>
#include <QQmlContext>
#include "settings.h"
#include "ui/uilogic.h"
#include "configurators/vpn_configurator.h"
#define amnApp (static_cast<AmneziaApplication *>(QCoreApplication::instance()))
#if defined(Q_OS_ANDROID) || defined(Q_OS_IOS)
#define AMNEZIA_BASE_CLASS QApplication
#else
#define AMNEZIA_BASE_CLASS SingleApplication
#define QAPPLICATION_CLASS QApplication
#include "singleapplication.h"
#endif
class AmneziaApplication : public AMNEZIA_BASE_CLASS
{
Q_OBJECT
public:
#if defined(Q_OS_ANDROID) || defined(Q_OS_IOS)
AmneziaApplication(int &argc, char *argv[]);
#else
AmneziaApplication(int &argc, char *argv[], bool allowSecondary = false,
SingleApplication::Options options = SingleApplication::User, int timeout = 1000, const QString &userData = {} );
#endif
virtual ~AmneziaApplication();
void init();
void registerTypes();
void loadFonts();
void loadTranslator();
bool parseCommands();
QQmlApplicationEngine *qmlEngine() const;
private:
QQmlApplicationEngine *m_engine {};
UiLogic *m_uiLogic {};
std::shared_ptr<Settings> m_settings;
std::shared_ptr<VpnConfigurator> m_configurator;
std::shared_ptr<ServerController> m_serverController;
ContainerProps* m_containerProps {};
ProtocolProps* m_protocolProps {};
QTranslator* m_translator;
QCommandLineParser m_parser;
};
#endif // AMNEZIA_APPLICATION_H

View file

@ -2,7 +2,6 @@ QT += widgets core gui network xml remoteobjects quick svg
TARGET = AmneziaVPN TARGET = AmneziaVPN
TEMPLATE = app TEMPLATE = app
#CONFIG += console
CONFIG += qtquickcompiler CONFIG += qtquickcompiler
CONFIG += qzxing_multimedia \ CONFIG += qzxing_multimedia \
@ -16,31 +15,37 @@ include("3rd/QtSsh/src/botan/botan.pri")
!android:!ios:include("3rd/SingleApplication/singleapplication.pri") !android:!ios:include("3rd/SingleApplication/singleapplication.pri")
include ("3rd/SortFilterProxyModel/SortFilterProxyModel.pri") include ("3rd/SortFilterProxyModel/SortFilterProxyModel.pri")
include("3rd/qzxing/src/QZXing-components.pri") include("3rd/qzxing/src/QZXing-components.pri")
include("3rd/QSimpleCrypto/QSimpleCrypto.pri")
include("3rd/qtkeychain/qtkeychain.pri")
INCLUDEPATH += $$PWD/3rd/QSimpleCrypto/include
INCLUDEPATH += $$PWD/3rd/OpenSSL/include INCLUDEPATH += $$PWD/3rd/OpenSSL/include
DEPENDPATH += $$PWD/3rd/OpenSSL/include DEPENDPATH += $$PWD/3rd/OpenSSL/include
HEADERS += \ HEADERS += \
../ipc/ipc.h \ ../ipc/ipc.h \
configurators/cloak_configurator.h \ amnezia_application.h \
configurators/ikev2_configurator.h \ configurators/cloak_configurator.h \
configurators/shadowsocks_configurator.h \ configurators/configurator_base.h \
configurators/ssh_configurator.h \ configurators/ikev2_configurator.h \
configurators/vpn_configurator.h \ configurators/shadowsocks_configurator.h \
configurators/wireguard_configurator.h \ configurators/ssh_configurator.h \
configurators/vpn_configurator.h \
configurators/wireguard_configurator.h \
containers/containers_defs.h \ containers/containers_defs.h \
core/defs.h \ core/defs.h \
core/errorstrings.h \ core/errorstrings.h \
configurators/openvpn_configurator.h \ configurators/openvpn_configurator.h \
core/scripts_registry.h \ core/scripts_registry.h \
core/server_defs.h \ core/server_defs.h \
core/servercontroller.h \ core/servercontroller.h \
debug.h \ debug.h \
defines.h \ defines.h \
managementserver.h \ managementserver.h \
platforms/ios/MobileUtils.h \ platforms/ios/MobileUtils.h \
platforms/linux/leakdetector.h \ platforms/linux/leakdetector.h \
protocols/protocols_defs.h \ protocols/protocols_defs.h \
secure_qsettings.h \
settings.h \ settings.h \
ui/notificationhandler.h \ ui/notificationhandler.h \
ui/models/containers_model.h \ ui/models/containers_model.h \
@ -49,28 +54,29 @@ HEADERS += \
ui/pages_logic/AppSettingsLogic.h \ ui/pages_logic/AppSettingsLogic.h \
ui/pages_logic/GeneralSettingsLogic.h \ ui/pages_logic/GeneralSettingsLogic.h \
ui/pages_logic/NetworkSettingsLogic.h \ ui/pages_logic/NetworkSettingsLogic.h \
ui/pages_logic/NewServerProtocolsLogic.h \ ui/pages_logic/NewServerProtocolsLogic.h \
ui/pages_logic/PageLogicBase.h \ ui/pages_logic/PageLogicBase.h \
ui/pages_logic/QrDecoderLogic.h \ ui/pages_logic/QrDecoderLogic.h \
ui/pages_logic/ServerConfiguringProgressLogic.h \ ui/pages_logic/ServerConfiguringProgressLogic.h \
ui/pages_logic/ServerContainersLogic.h \ ui/pages_logic/ServerContainersLogic.h \
ui/pages_logic/ServerListLogic.h \ ui/pages_logic/ServerListLogic.h \
ui/pages_logic/ServerSettingsLogic.h \ ui/pages_logic/ServerSettingsLogic.h \
ui/pages_logic/ShareConnectionLogic.h \ ui/pages_logic/ShareConnectionLogic.h \
ui/pages_logic/SitesLogic.h \ ui/pages_logic/SitesLogic.h \
ui/pages_logic/StartPageLogic.h \ ui/pages_logic/StartPageLogic.h \
ui/pages_logic/ViewConfigLogic.h \
ui/pages_logic/VpnLogic.h \ ui/pages_logic/VpnLogic.h \
ui/pages_logic/WizardLogic.h \ ui/pages_logic/WizardLogic.h \
ui/pages_logic/protocols/CloakLogic.h \ ui/pages_logic/protocols/CloakLogic.h \
ui/pages_logic/protocols/OpenVpnLogic.h \ ui/pages_logic/protocols/OpenVpnLogic.h \
ui/pages_logic/protocols/OtherProtocolsLogic.h \ ui/pages_logic/protocols/OtherProtocolsLogic.h \
ui/pages_logic/protocols/PageProtocolLogicBase.h \ ui/pages_logic/protocols/PageProtocolLogicBase.h \
ui/pages_logic/protocols/ShadowSocksLogic.h \ ui/pages_logic/protocols/ShadowSocksLogic.h \
ui/property_helper.h \ ui/property_helper.h \
ui/models/servers_model.h \ ui/models/servers_model.h \
ui/uilogic.h \ ui/uilogic.h \
ui/qautostart.h \ ui/qautostart.h \
ui/models/sites_model.h \ ui/models/sites_model.h \
utils.h \ utils.h \
vpnconnection.h \ vpnconnection.h \
protocols/vpnprotocol.h \ protocols/vpnprotocol.h \
@ -81,24 +87,27 @@ HEADERS += \
platforms/ios/QRCodeReaderBase.h platforms/ios/QRCodeReaderBase.h
SOURCES += \ SOURCES += \
configurators/cloak_configurator.cpp \ amnezia_application.cpp \
configurators/ikev2_configurator.cpp \ configurators/cloak_configurator.cpp \
configurators/shadowsocks_configurator.cpp \ configurators/configurator_base.cpp \
configurators/ssh_configurator.cpp \ configurators/ikev2_configurator.cpp \
configurators/vpn_configurator.cpp \ configurators/shadowsocks_configurator.cpp \
configurators/wireguard_configurator.cpp \ configurators/ssh_configurator.cpp \
configurators/vpn_configurator.cpp \
configurators/wireguard_configurator.cpp \
containers/containers_defs.cpp \ containers/containers_defs.cpp \
core/errorstrings.cpp \ core/errorstrings.cpp \
configurators/openvpn_configurator.cpp \ configurators/openvpn_configurator.cpp \
core/scripts_registry.cpp \ core/scripts_registry.cpp \
core/server_defs.cpp \ core/server_defs.cpp \
core/servercontroller.cpp \ core/servercontroller.cpp \
debug.cpp \ debug.cpp \
main.cpp \ main.cpp \
managementserver.cpp \ managementserver.cpp \
platforms/ios/MobileUtils.cpp \ platforms/ios/MobileUtils.cpp \
platforms/linux/leakdetector.cpp \ platforms/linux/leakdetector.cpp \
protocols/protocols_defs.cpp \ protocols/protocols_defs.cpp \
secure_qsettings.cpp \
settings.cpp \ settings.cpp \
ui/notificationhandler.cpp \ ui/notificationhandler.cpp \
ui/models/containers_model.cpp \ ui/models/containers_model.cpp \
@ -106,27 +115,28 @@ SOURCES += \
ui/pages_logic/AppSettingsLogic.cpp \ ui/pages_logic/AppSettingsLogic.cpp \
ui/pages_logic/GeneralSettingsLogic.cpp \ ui/pages_logic/GeneralSettingsLogic.cpp \
ui/pages_logic/NetworkSettingsLogic.cpp \ ui/pages_logic/NetworkSettingsLogic.cpp \
ui/pages_logic/NewServerProtocolsLogic.cpp \ ui/pages_logic/NewServerProtocolsLogic.cpp \
ui/pages_logic/PageLogicBase.cpp \ ui/pages_logic/PageLogicBase.cpp \
ui/pages_logic/QrDecoderLogic.cpp \ ui/pages_logic/QrDecoderLogic.cpp \
ui/pages_logic/ServerConfiguringProgressLogic.cpp \ ui/pages_logic/ServerConfiguringProgressLogic.cpp \
ui/pages_logic/ServerContainersLogic.cpp \ ui/pages_logic/ServerContainersLogic.cpp \
ui/pages_logic/ServerListLogic.cpp \ ui/pages_logic/ServerListLogic.cpp \
ui/pages_logic/ServerSettingsLogic.cpp \ ui/pages_logic/ServerSettingsLogic.cpp \
ui/pages_logic/ShareConnectionLogic.cpp \ ui/pages_logic/ShareConnectionLogic.cpp \
ui/pages_logic/SitesLogic.cpp \ ui/pages_logic/SitesLogic.cpp \
ui/pages_logic/StartPageLogic.cpp \ ui/pages_logic/StartPageLogic.cpp \
ui/pages_logic/ViewConfigLogic.cpp \
ui/pages_logic/VpnLogic.cpp \ ui/pages_logic/VpnLogic.cpp \
ui/pages_logic/WizardLogic.cpp \ ui/pages_logic/WizardLogic.cpp \
ui/pages_logic/protocols/CloakLogic.cpp \ ui/pages_logic/protocols/CloakLogic.cpp \
ui/pages_logic/protocols/OpenVpnLogic.cpp \ ui/pages_logic/protocols/OpenVpnLogic.cpp \
ui/pages_logic/protocols/OtherProtocolsLogic.cpp \ ui/pages_logic/protocols/OtherProtocolsLogic.cpp \
ui/pages_logic/protocols/PageProtocolLogicBase.cpp \ ui/pages_logic/protocols/PageProtocolLogicBase.cpp \
ui/pages_logic/protocols/ShadowSocksLogic.cpp \ ui/pages_logic/protocols/ShadowSocksLogic.cpp \
ui/models/servers_model.cpp \ ui/models/servers_model.cpp \
ui/uilogic.cpp \ ui/uilogic.cpp \
ui/qautostart.cpp \ ui/qautostart.cpp \
ui/models/sites_model.cpp \ ui/models/sites_model.cpp \
utils.cpp \ utils.cpp \
vpnconnection.cpp \ vpnconnection.cpp \
protocols/vpnprotocol.cpp \ protocols/vpnprotocol.cpp \
@ -165,7 +175,6 @@ win32 {
-lshlwapi \ -lshlwapi \
-liphlpapi \ -liphlpapi \
-lws2_32 \ -lws2_32 \
-liphlpapi \
-lgdi32 -lgdi32
@ -246,20 +255,20 @@ android {
DISTFILES += \ DISTFILES += \
android/AndroidManifest.xml \ android/AndroidManifest.xml \
android/build.gradle \ android/build.gradle \
android/gradle/wrapper/gradle-wrapper.jar \ android/gradle/wrapper/gradle-wrapper.jar \
android/gradle/wrapper/gradle-wrapper.properties \ android/gradle/wrapper/gradle-wrapper.properties \
android/gradlew \ android/gradlew \
android/gradlew.bat \ android/gradlew.bat \
android/gradle.properties \ android/gradle.properties \
android/res/values/libs.xml \ android/res/values/libs.xml \
android/src/org/amnezia/vpn/OpenVPNThreadv3.kt \ android/src/org/amnezia/vpn/OpenVPNThreadv3.kt \
android/src/org/amnezia/vpn/VpnService.kt \ android/src/org/amnezia/vpn/VpnService.kt \
android/src/org/amnezia/vpn/VpnServiceBinder.kt \ android/src/org/amnezia/vpn/VpnServiceBinder.kt \
android/src/org/amnezia/vpn/qt/VPNPermissionHelper.kt android/src/org/amnezia/vpn/qt/VPNPermissionHelper.kt
ANDROID_PACKAGE_SOURCE_DIR = $$PWD/android ANDROID_PACKAGE_SOURCE_DIR = $$PWD/android
for (abi, ANDROID_ABIS): { for (abi, ANDROID_ABIS): {
equals(ANDROID_TARGET_ARCH,$$abi) { equals(ANDROID_TARGET_ARCH,$$abi) {
@ -280,7 +289,7 @@ android {
} }
ios { ios {
message("Client ios build") message("Client iOS build")
CONFIG += static CONFIG += static
CONFIG += file_copies CONFIG += file_copies
@ -307,7 +316,7 @@ ios {
platforms/ios/QtAppDelegate-C-Interface.h platforms/ios/QtAppDelegate-C-Interface.h
SOURCES -= \ SOURCES -= \
platforms/ios/QRCodeReader.cpp \ platforms/ios/QRCodeReaderBase.cpp \
platforms/ios/MobileUtils.cpp platforms/ios/MobileUtils.cpp
SOURCES += \ SOURCES += \

View file

@ -4,18 +4,25 @@
#include <QJsonObject> #include <QJsonObject>
#include <QJsonDocument> #include <QJsonDocument>
#include "core/servercontroller.h"
#include "containers/containers_defs.h" #include "containers/containers_defs.h"
CloakConfigurator::CloakConfigurator(std::shared_ptr<Settings> settings, std::shared_ptr<ServerController> serverController, QObject *parent):
ConfiguratorBase(settings, serverController, parent)
{
}
QString CloakConfigurator::genCloakConfig(const ServerCredentials &credentials, QString CloakConfigurator::genCloakConfig(const ServerCredentials &credentials,
DockerContainer container, const QJsonObject &containerConfig, ErrorCode *errorCode) DockerContainer container, const QJsonObject &containerConfig, ErrorCode *errorCode)
{ {
ErrorCode e = ErrorCode::NoError; ErrorCode e = ErrorCode::NoError;
QString cloakPublicKey = ServerController::getTextFileFromContainer(container, credentials, QString cloakPublicKey = m_serverController->getTextFileFromContainer(container, credentials,
amnezia::protocols::cloak::ckPublicKeyPath, &e); amnezia::protocols::cloak::ckPublicKeyPath, &e);
cloakPublicKey.replace("\n", ""); cloakPublicKey.replace("\n", "");
QString cloakBypassUid = ServerController::getTextFileFromContainer(container, credentials, QString cloakBypassUid = m_serverController->getTextFileFromContainer(container, credentials,
amnezia::protocols::cloak::ckBypassUidKeyPath, &e); amnezia::protocols::cloak::ckBypassUidKeyPath, &e);
cloakBypassUid.replace("\n", ""); cloakBypassUid.replace("\n", "");
@ -40,8 +47,8 @@ QString CloakConfigurator::genCloakConfig(const ServerCredentials &credentials,
config.insert(config_key::remote, credentials.hostName); config.insert(config_key::remote, credentials.hostName);
config.insert(config_key::port, "$CLOAK_SERVER_PORT"); config.insert(config_key::port, "$CLOAK_SERVER_PORT");
QString textCfg = ServerController::replaceVars(QJsonDocument(config).toJson(), QString textCfg = m_serverController->replaceVars(QJsonDocument(config).toJson(),
ServerController::genVarsForScript(credentials, container, containerConfig)); m_serverController->genVarsForScript(credentials, container, containerConfig));
// qDebug().noquote() << textCfg; // qDebug().noquote() << textCfg;
return textCfg; return textCfg;

View file

@ -3,15 +3,18 @@
#include <QObject> #include <QObject>
#include "core/defs.h" #include "configurator_base.h"
#include "settings.h"
#include "core/servercontroller.h"
class CloakConfigurator using namespace amnezia;
class CloakConfigurator : ConfiguratorBase
{ {
Q_OBJECT
public: public:
CloakConfigurator(std::shared_ptr<Settings> settings,
std::shared_ptr<ServerController> serverController, QObject *parent = nullptr);
static QString genCloakConfig(const ServerCredentials &credentials, DockerContainer container, QString genCloakConfig(const ServerCredentials &credentials, DockerContainer container,
const QJsonObject &containerConfig, ErrorCode *errorCode = nullptr); const QJsonObject &containerConfig, ErrorCode *errorCode = nullptr);
}; };

View file

@ -0,0 +1,10 @@
#include "configurator_base.h"
ConfiguratorBase::ConfiguratorBase(std::shared_ptr<Settings> settings,
std::shared_ptr<ServerController> serverController, QObject *parent)
: QObject{parent},
m_settings(settings),
m_serverController(serverController)
{
}

View file

@ -0,0 +1,25 @@
#ifndef CONFIGURATORBASE_H
#define CONFIGURATORBASE_H
#include <QObject>
class Settings;
class ServerController;
#include "containers/containers_defs.h"
#include "core/defs.h"
class ConfiguratorBase : public QObject
{
Q_OBJECT
public:
explicit ConfiguratorBase(std::shared_ptr<Settings> settings,
std::shared_ptr<ServerController> serverController, QObject *parent = nullptr);
protected:
std::shared_ptr<Settings> m_settings;
std::shared_ptr<ServerController> m_serverController;
};
#endif // CONFIGURATORBASE_H

View file

@ -8,13 +8,18 @@
#include <QJsonDocument> #include <QJsonDocument>
#include <QUuid> #include <QUuid>
#include "sftpdefs.h"
#include "core/server_defs.h"
#include "containers/containers_defs.h" #include "containers/containers_defs.h"
#include "core/server_defs.h"
#include "core/scripts_registry.h" #include "core/scripts_registry.h"
#include "core/servercontroller.h"
#include "utils.h" #include "utils.h"
Ikev2Configurator::Ikev2Configurator(std::shared_ptr<Settings> settings, std::shared_ptr<ServerController> serverController, QObject *parent):
ConfiguratorBase(settings, serverController, parent)
{
}
Ikev2Configurator::ConnectionData Ikev2Configurator::prepareIkev2Config(const ServerCredentials &credentials, Ikev2Configurator::ConnectionData Ikev2Configurator::prepareIkev2Config(const ServerCredentials &credentials,
DockerContainer container, ErrorCode *errorCode) DockerContainer container, ErrorCode *errorCode)
{ {
@ -35,16 +40,16 @@ Ikev2Configurator::ConnectionData Ikev2Configurator::prepareIkev2Config(const Se
"--extKeyUsage serverAuth,clientAuth -8 \"%1\"") "--extKeyUsage serverAuth,clientAuth -8 \"%1\"")
.arg(connData.clientId); .arg(connData.clientId);
ErrorCode e = ServerController::runContainerScript(credentials, container, scriptCreateCert); ErrorCode e = m_serverController->runContainerScript(credentials, container, scriptCreateCert);
QString scriptExportCert = QString("pk12util -W \"%1\" -d sql:/etc/ipsec.d -n \"%2\" -o \"%3\"") QString scriptExportCert = QString("pk12util -W \"%1\" -d sql:/etc/ipsec.d -n \"%2\" -o \"%3\"")
.arg(connData.password) .arg(connData.password)
.arg(connData.clientId) .arg(connData.clientId)
.arg(certFileName); .arg(certFileName);
e = ServerController::runContainerScript(credentials, container, scriptExportCert); e = m_serverController->runContainerScript(credentials, container, scriptExportCert);
connData.clientCert = ServerController::getTextFileFromContainer(container, credentials, certFileName, &e); connData.clientCert = m_serverController->getTextFileFromContainer(container, credentials, certFileName, &e);
connData.caCert = ServerController::getTextFileFromContainer(container, credentials, "/etc/ipsec.d/ca_cert_base64.p12", &e); connData.caCert = m_serverController->getTextFileFromContainer(container, credentials, "/etc/ipsec.d/ca_cert_base64.p12", &e);
qDebug() << "Ikev2Configurator::ConnectionData client cert size:" << connData.clientCert.size(); qDebug() << "Ikev2Configurator::ConnectionData client cert size:" << connData.clientCert.size();
qDebug() << "Ikev2Configurator::ConnectionData ca cert size:" << connData.caCert.size(); qDebug() << "Ikev2Configurator::ConnectionData ca cert size:" << connData.caCert.size();

View file

@ -4,12 +4,15 @@
#include <QObject> #include <QObject>
#include <QProcessEnvironment> #include <QProcessEnvironment>
#include "configurator_base.h"
#include "core/defs.h" #include "core/defs.h"
#include "core/servercontroller.h"
class Ikev2Configurator class Ikev2Configurator : ConfiguratorBase
{ {
Q_OBJECT
public: public:
Ikev2Configurator(std::shared_ptr<Settings> settings,
std::shared_ptr<ServerController> serverController, QObject *parent = nullptr);
struct ConnectionData { struct ConnectionData {
QByteArray clientCert; // p12 client cert QByteArray clientCert; // p12 client cert
@ -19,14 +22,14 @@ public:
QString host; // host ip QString host; // host ip
}; };
static QString genIkev2Config(const ServerCredentials &credentials, DockerContainer container, QString genIkev2Config(const ServerCredentials &credentials, DockerContainer container,
const QJsonObject &containerConfig, ErrorCode *errorCode = nullptr); const QJsonObject &containerConfig, ErrorCode *errorCode = nullptr);
static QString genIkev2Config(const ConnectionData &connData); QString genIkev2Config(const ConnectionData &connData);
static QString genMobileConfig(const ConnectionData &connData); QString genMobileConfig(const ConnectionData &connData);
static QString genStrongSwanConfig(const ConnectionData &connData); QString genStrongSwanConfig(const ConnectionData &connData);
static ConnectionData prepareIkev2Config(const ServerCredentials &credentials, ConnectionData prepareIkev2Config(const ServerCredentials &credentials,
DockerContainer container, ErrorCode *errorCode = nullptr); DockerContainer container, ErrorCode *errorCode = nullptr);
}; };

View file

@ -6,16 +6,25 @@
#include <QDebug> #include <QDebug>
#include <QTemporaryFile> #include <QTemporaryFile>
#include <QJsonObject> #include <QJsonObject>
#include <QJsonDocument>
#include "core/server_defs.h"
#include "containers/containers_defs.h" #include "containers/containers_defs.h"
#include "core/server_defs.h"
#include "core/servercontroller.h"
#include "core/scripts_registry.h" #include "core/scripts_registry.h"
#include "settings.h"
#include "utils.h" #include "utils.h"
#include <openssl/rsa.h> #include <openssl/rsa.h>
#include <openssl/x509.h> #include <openssl/x509.h>
#include <openssl/pem.h> #include <openssl/pem.h>
OpenVpnConfigurator::OpenVpnConfigurator(std::shared_ptr<Settings> settings, std::shared_ptr<ServerController> serverController, QObject *parent):
ConfiguratorBase(settings, serverController, parent)
{
}
OpenVpnConfigurator::ConnectionData OpenVpnConfigurator::prepareOpenVpnConfig(const ServerCredentials &credentials, OpenVpnConfigurator::ConnectionData OpenVpnConfigurator::prepareOpenVpnConfig(const ServerCredentials &credentials,
DockerContainer container, ErrorCode *errorCode) DockerContainer container, ErrorCode *errorCode)
{ {
@ -31,7 +40,7 @@ OpenVpnConfigurator::ConnectionData OpenVpnConfigurator::prepareOpenVpnConfig(co
arg(amnezia::protocols::openvpn::clientsDirPath). arg(amnezia::protocols::openvpn::clientsDirPath).
arg(connData.clientId); arg(connData.clientId);
ErrorCode e = ServerController::uploadTextFileToContainer(container, credentials, connData.request, reqFileName); ErrorCode e = m_serverController->uploadTextFileToContainer(container, credentials, connData.request, reqFileName);
if (e) { if (e) {
if (errorCode) *errorCode = e; if (errorCode) *errorCode = e;
return connData; return connData;
@ -43,8 +52,8 @@ OpenVpnConfigurator::ConnectionData OpenVpnConfigurator::prepareOpenVpnConfig(co
return connData; return connData;
} }
connData.caCert = ServerController::getTextFileFromContainer(container, credentials, amnezia::protocols::openvpn::caCertPath, &e); connData.caCert = m_serverController->getTextFileFromContainer(container, credentials, amnezia::protocols::openvpn::caCertPath, &e);
connData.clientCert = ServerController::getTextFileFromContainer(container, credentials, connData.clientCert = m_serverController->getTextFileFromContainer(container, credentials,
QString("%1/%2.crt").arg(amnezia::protocols::openvpn::clientCertPath).arg(connData.clientId), &e); QString("%1/%2.crt").arg(amnezia::protocols::openvpn::clientCertPath).arg(connData.clientId), &e);
if (e) { if (e) {
@ -52,7 +61,7 @@ OpenVpnConfigurator::ConnectionData OpenVpnConfigurator::prepareOpenVpnConfig(co
return connData; return connData;
} }
connData.taKey = ServerController::getTextFileFromContainer(container, credentials, amnezia::protocols::openvpn::taKeyPath, &e); connData.taKey = m_serverController->getTextFileFromContainer(container, credentials, amnezia::protocols::openvpn::taKeyPath, &e);
if (connData.caCert.isEmpty() || connData.clientCert.isEmpty() || connData.taKey.isEmpty()) { if (connData.caCert.isEmpty() || connData.clientCert.isEmpty() || connData.taKey.isEmpty()) {
if (errorCode) *errorCode = ErrorCode::RemoteProcessCrashError; if (errorCode) *errorCode = ErrorCode::RemoteProcessCrashError;
@ -61,17 +70,11 @@ OpenVpnConfigurator::ConnectionData OpenVpnConfigurator::prepareOpenVpnConfig(co
return connData; return connData;
} }
Settings &OpenVpnConfigurator::m_settings()
{
static Settings s;
return s;
}
QString OpenVpnConfigurator::genOpenVpnConfig(const ServerCredentials &credentials, QString OpenVpnConfigurator::genOpenVpnConfig(const ServerCredentials &credentials,
DockerContainer container, const QJsonObject &containerConfig, ErrorCode *errorCode) DockerContainer container, const QJsonObject &containerConfig, ErrorCode *errorCode)
{ {
QString config = ServerController::replaceVars(amnezia::scriptData(ProtocolScriptType::openvpn_template, container), QString config = m_serverController->replaceVars(amnezia::scriptData(ProtocolScriptType::openvpn_template, container),
ServerController::genVarsForScript(credentials, container, containerConfig)); m_serverController->genVarsForScript(credentials, container, containerConfig));
ConnectionData connData = prepareOpenVpnConfig(credentials, container, errorCode); ConnectionData connData = prepareOpenVpnConfig(credentials, container, errorCode);
if (errorCode && *errorCode) { if (errorCode && *errorCode) {
@ -105,7 +108,7 @@ QString OpenVpnConfigurator::processConfigWithLocalSettings(QString jsonConfig)
QJsonObject json = QJsonDocument::fromJson(jsonConfig.toUtf8()).object(); QJsonObject json = QJsonDocument::fromJson(jsonConfig.toUtf8()).object();
QString config = json[config_key::config].toString(); QString config = json[config_key::config].toString();
if (m_settings().routeMode() != Settings::VpnAllSites) { if (m_settings->routeMode() != Settings::VpnAllSites) {
config.replace("redirect-gateway def1 bypass-dhcp", ""); config.replace("redirect-gateway def1 bypass-dhcp", "");
} }
else { else {
@ -161,9 +164,9 @@ ErrorCode OpenVpnConfigurator::signCert(DockerContainer container,
.arg(clientId); .arg(clientId);
QStringList scriptList {script_import, script_sign}; QStringList scriptList {script_import, script_sign};
QString script = ServerController::replaceVars(scriptList.join("\n"), ServerController::genVarsForScript(credentials, container)); QString script = m_serverController->replaceVars(scriptList.join("\n"), m_serverController->genVarsForScript(credentials, container));
return ServerController::runScript(credentials, script); return m_serverController->runScript(credentials, script);
} }
OpenVpnConfigurator::ConnectionData OpenVpnConfigurator::createCertRequest() OpenVpnConfigurator::ConnectionData OpenVpnConfigurator::createCertRequest()

View file

@ -4,13 +4,15 @@
#include <QObject> #include <QObject>
#include <QProcessEnvironment> #include <QProcessEnvironment>
#include "configurator_base.h"
#include "core/defs.h" #include "core/defs.h"
#include "settings.h"
#include "core/servercontroller.h"
class OpenVpnConfigurator class OpenVpnConfigurator : ConfiguratorBase
{ {
Q_OBJECT
public: public:
OpenVpnConfigurator(std::shared_ptr<Settings> settings,
std::shared_ptr<ServerController> serverController, QObject *parent = nullptr);
struct ConnectionData { struct ConnectionData {
QString clientId; QString clientId;
@ -22,22 +24,21 @@ public:
QString host; // host ip QString host; // host ip
}; };
static QString genOpenVpnConfig(const ServerCredentials &credentials, DockerContainer container, QString genOpenVpnConfig(const ServerCredentials &credentials, DockerContainer container,
const QJsonObject &containerConfig, ErrorCode *errorCode = nullptr); const QJsonObject &containerConfig, ErrorCode *errorCode = nullptr);
static QString processConfigWithLocalSettings(QString jsonConfig); QString processConfigWithLocalSettings(QString jsonConfig);
static QString processConfigWithExportSettings(QString jsonConfig); QString processConfigWithExportSettings(QString jsonConfig);
static ErrorCode signCert(DockerContainer container, ErrorCode signCert(DockerContainer container,
const ServerCredentials &credentials, QString clientId); const ServerCredentials &credentials, QString clientId);
private: private:
static ConnectionData createCertRequest(); ConnectionData createCertRequest();
static ConnectionData prepareOpenVpnConfig(const ServerCredentials &credentials, ConnectionData prepareOpenVpnConfig(const ServerCredentials &credentials,
DockerContainer container, ErrorCode *errorCode = nullptr); DockerContainer container, ErrorCode *errorCode = nullptr);
static Settings &m_settings();
}; };
#endif // OPENVPN_CONFIGURATOR_H #endif // OPENVPN_CONFIGURATOR_H

View file

@ -5,13 +5,20 @@
#include <QJsonDocument> #include <QJsonDocument>
#include "containers/containers_defs.h" #include "containers/containers_defs.h"
#include "core/servercontroller.h"
ShadowSocksConfigurator::ShadowSocksConfigurator(std::shared_ptr<Settings> settings, std::shared_ptr<ServerController> serverController, QObject *parent):
ConfiguratorBase(settings, serverController, parent)
{
}
QString ShadowSocksConfigurator::genShadowSocksConfig(const ServerCredentials &credentials, QString ShadowSocksConfigurator::genShadowSocksConfig(const ServerCredentials &credentials,
DockerContainer container, const QJsonObject &containerConfig, ErrorCode *errorCode) DockerContainer container, const QJsonObject &containerConfig, ErrorCode *errorCode)
{ {
ErrorCode e = ErrorCode::NoError; ErrorCode e = ErrorCode::NoError;
QString ssKey = ServerController::getTextFileFromContainer(container, credentials, QString ssKey = m_serverController->getTextFileFromContainer(container, credentials,
amnezia::protocols::shadowsocks::ssKeyPath, &e); amnezia::protocols::shadowsocks::ssKeyPath, &e);
ssKey.replace("\n", ""); ssKey.replace("\n", "");
@ -29,8 +36,8 @@ QString ShadowSocksConfigurator::genShadowSocksConfig(const ServerCredentials &c
config.insert("method", "$SHADOWSOCKS_CIPHER"); config.insert("method", "$SHADOWSOCKS_CIPHER");
QString textCfg = ServerController::replaceVars(QJsonDocument(config).toJson(), QString textCfg = m_serverController->replaceVars(QJsonDocument(config).toJson(),
ServerController::genVarsForScript(credentials, container, containerConfig)); m_serverController->genVarsForScript(credentials, container, containerConfig));
//qDebug().noquote() << textCfg; //qDebug().noquote() << textCfg;
return textCfg; return textCfg;

View file

@ -3,15 +3,17 @@
#include <QObject> #include <QObject>
#include "configurator_base.h"
#include "core/defs.h" #include "core/defs.h"
#include "settings.h"
#include "core/servercontroller.h"
class ShadowSocksConfigurator class ShadowSocksConfigurator : ConfiguratorBase
{ {
Q_OBJECT
public: public:
ShadowSocksConfigurator(std::shared_ptr<Settings> settings,
std::shared_ptr<ServerController> serverController, QObject *parent = nullptr);
static QString genShadowSocksConfig(const ServerCredentials &credentials, DockerContainer container, QString genShadowSocksConfig(const ServerCredentials &credentials, DockerContainer container,
const QJsonObject &containerConfig, ErrorCode *errorCode = nullptr); const QJsonObject &containerConfig, ErrorCode *errorCode = nullptr);
}; };

View file

@ -14,8 +14,15 @@
#include "core/server_defs.h" #include "core/server_defs.h"
#include "utils.h" #include "utils.h"
#include "sftpdefs.h"
using namespace QSsh; using namespace QSsh;
SshConfigurator::SshConfigurator(std::shared_ptr<Settings> settings, std::shared_ptr<ServerController> serverController, QObject *parent):
ConfiguratorBase(settings, serverController, parent)
{
}
QString SshConfigurator::convertOpenSShKey(const QString &key) QString SshConfigurator::convertOpenSShKey(const QString &key)
{ {

View file

@ -4,16 +4,19 @@
#include <QObject> #include <QObject>
#include <QProcessEnvironment> #include <QProcessEnvironment>
#include "configurator_base.h"
#include "core/defs.h" #include "core/defs.h"
#include "settings.h"
#include "core/servercontroller.h"
class SshConfigurator class SshConfigurator : ConfiguratorBase
{ {
Q_OBJECT
public: public:
static QProcessEnvironment prepareEnv(); SshConfigurator(std::shared_ptr<Settings> settings,
static QString convertOpenSShKey(const QString &key); std::shared_ptr<ServerController> serverController, QObject *parent = nullptr);
static void openSshTerminal(const ServerCredentials &credentials);
QProcessEnvironment prepareEnv();
QString convertOpenSShKey(const QString &key);
void openSshTerminal(const ServerCredentials &credentials);
}; };

View file

@ -4,18 +4,26 @@
#include "shadowsocks_configurator.h" #include "shadowsocks_configurator.h"
#include "wireguard_configurator.h" #include "wireguard_configurator.h"
#include "ikev2_configurator.h" #include "ikev2_configurator.h"
#include "ssh_configurator.h"
#include <QFile> #include <QFile>
#include <QJsonObject> #include <QJsonObject>
#include <QJsonDocument> #include <QJsonDocument>
#include "containers/containers_defs.h" #include "containers/containers_defs.h"
#include "settings.h"
#include "utils.h" #include "utils.h"
Settings &VpnConfigurator::m_settings() VpnConfigurator::VpnConfigurator(std::shared_ptr<Settings> settings,
std::shared_ptr<ServerController> serverController, QObject *parent):
ConfiguratorBase(settings, serverController, parent)
{ {
static Settings s; openVpnConfigurator = std::shared_ptr<OpenVpnConfigurator>(new OpenVpnConfigurator(settings, serverController, this));
return s; shadowSocksConfigurator = std::shared_ptr<ShadowSocksConfigurator>(new ShadowSocksConfigurator(settings, serverController, this));
cloakConfigurator = std::shared_ptr<CloakConfigurator>(new CloakConfigurator(settings, serverController, this));
wireguardConfigurator = std::shared_ptr<WireguardConfigurator>(new WireguardConfigurator(settings, serverController, this));
ikev2Configurator = std::shared_ptr<Ikev2Configurator>(new Ikev2Configurator(settings, serverController, this));
sshConfigurator = std::shared_ptr<SshConfigurator>(new SshConfigurator(settings, serverController, this));
} }
QString VpnConfigurator::genVpnProtocolConfig(const ServerCredentials &credentials, QString VpnConfigurator::genVpnProtocolConfig(const ServerCredentials &credentials,
@ -23,19 +31,19 @@ QString VpnConfigurator::genVpnProtocolConfig(const ServerCredentials &credentia
{ {
switch (proto) { switch (proto) {
case Proto::OpenVpn: case Proto::OpenVpn:
return OpenVpnConfigurator::genOpenVpnConfig(credentials, container, containerConfig, errorCode); return openVpnConfigurator->genOpenVpnConfig(credentials, container, containerConfig, errorCode);
case Proto::ShadowSocks: case Proto::ShadowSocks:
return ShadowSocksConfigurator::genShadowSocksConfig(credentials, container, containerConfig, errorCode); return shadowSocksConfigurator->genShadowSocksConfig(credentials, container, containerConfig, errorCode);
case Proto::Cloak: case Proto::Cloak:
return CloakConfigurator::genCloakConfig(credentials, container, containerConfig, errorCode); return cloakConfigurator->genCloakConfig(credentials, container, containerConfig, errorCode);
case Proto::WireGuard: case Proto::WireGuard:
return WireguardConfigurator::genWireguardConfig(credentials, container, containerConfig, errorCode); return wireguardConfigurator->genWireguardConfig(credentials, container, containerConfig, errorCode);
case Proto::Ikev2: case Proto::Ikev2:
return Ikev2Configurator::genIkev2Config(credentials, container, containerConfig, errorCode); return ikev2Configurator->genIkev2Config(credentials, container, containerConfig, errorCode);
default: default:
return ""; return "";
@ -46,20 +54,20 @@ QPair<QString, QString> VpnConfigurator::getDnsForConfig(int serverIndex)
{ {
QPair<QString, QString> dns; QPair<QString, QString> dns;
bool useAmneziaDns = m_settings().useAmneziaDns(); bool useAmneziaDns = m_settings->useAmneziaDns();
const QJsonObject &server = m_settings().server(serverIndex); const QJsonObject &server = m_settings->server(serverIndex);
dns.first = server.value(config_key::dns1).toString(); dns.first = server.value(config_key::dns1).toString();
dns.second = server.value(config_key::dns2).toString(); dns.second = server.value(config_key::dns2).toString();
if (dns.first.isEmpty() || !Utils::checkIPv4Format(dns.first)) { if (dns.first.isEmpty() || !Utils::checkIPv4Format(dns.first)) {
if (useAmneziaDns && m_settings().containers(serverIndex).contains(DockerContainer::Dns)) { if (useAmneziaDns && m_settings->containers(serverIndex).contains(DockerContainer::Dns)) {
dns.first = protocols::dns::amneziaDnsIp; dns.first = protocols::dns::amneziaDnsIp;
} }
else dns.first = m_settings().primaryDns(); else dns.first = m_settings->primaryDns();
} }
if (dns.second.isEmpty() || !Utils::checkIPv4Format(dns.second)) { if (dns.second.isEmpty() || !Utils::checkIPv4Format(dns.second)) {
dns.second = m_settings().secondaryDns(); dns.second = m_settings->secondaryDns();
} }
qDebug() << "VpnConfigurator::getDnsForConfig" << dns.first << dns.second; qDebug() << "VpnConfigurator::getDnsForConfig" << dns.first << dns.second;
@ -83,7 +91,7 @@ QString &VpnConfigurator::processConfigWithLocalSettings(int serverIndex, Docker
processConfigWithDnsSettings(serverIndex, container, proto, config); processConfigWithDnsSettings(serverIndex, container, proto, config);
if (proto == Proto::OpenVpn) { if (proto == Proto::OpenVpn) {
config = OpenVpnConfigurator::processConfigWithLocalSettings(config); config = openVpnConfigurator->processConfigWithLocalSettings(config);
} }
return config; return config;
} }
@ -94,7 +102,7 @@ QString &VpnConfigurator::processConfigWithExportSettings(int serverIndex, Docke
processConfigWithDnsSettings(serverIndex, container, proto, config); processConfigWithDnsSettings(serverIndex, container, proto, config);
if (proto == Proto::OpenVpn) { if (proto == Proto::OpenVpn) {
config = OpenVpnConfigurator::processConfigWithExportSettings(config); config = openVpnConfigurator->processConfigWithExportSettings(config);
} }
return config; return config;
} }

View file

@ -3,29 +3,46 @@
#include <QObject> #include <QObject>
#include "configurator_base.h"
#include "core/defs.h" #include "core/defs.h"
#include "settings.h"
#include "core/servercontroller.h"
class OpenVpnConfigurator;
class ShadowSocksConfigurator;
class CloakConfigurator;
class WireguardConfigurator;
class Ikev2Configurator;
class SshConfigurator;
// Retrieve connection settings from server // Retrieve connection settings from server
class VpnConfigurator class VpnConfigurator : ConfiguratorBase
{ {
Q_OBJECT
public: public:
VpnConfigurator(std::shared_ptr<Settings> settings,
std::shared_ptr<ServerController> serverController, QObject *parent = nullptr);
static QString genVpnProtocolConfig(const ServerCredentials &credentials, DockerContainer container, QString genVpnProtocolConfig(const ServerCredentials &credentials, DockerContainer container,
const QJsonObject &containerConfig, Proto proto, ErrorCode *errorCode = nullptr); const QJsonObject &containerConfig, Proto proto, ErrorCode *errorCode = nullptr);
static QPair<QString, QString> getDnsForConfig(int serverIndex); QPair<QString, QString> getDnsForConfig(int serverIndex);
static QString &processConfigWithDnsSettings(int serverIndex, DockerContainer container, Proto proto, QString &config); QString &processConfigWithDnsSettings(int serverIndex, DockerContainer container, Proto proto, QString &config);
static QString &processConfigWithLocalSettings(int serverIndex, DockerContainer container, Proto proto, QString &config); QString &processConfigWithLocalSettings(int serverIndex, DockerContainer container, Proto proto, QString &config);
static QString &processConfigWithExportSettings(int serverIndex, DockerContainer container, Proto proto, QString &config); QString &processConfigWithExportSettings(int serverIndex, DockerContainer container, Proto proto, QString &config);
// workaround for containers which is not support normal configaration // workaround for containers which is not support normal configaration
static void updateContainerConfigAfterInstallation(DockerContainer container, void updateContainerConfigAfterInstallation(DockerContainer container,
QJsonObject &containerConfig, const QString &stdOut); QJsonObject &containerConfig, const QString &stdOut);
static Settings &m_settings(); std::shared_ptr<ServerController> m_serverController;
std::shared_ptr<OpenVpnConfigurator> openVpnConfigurator;
std::shared_ptr<ShadowSocksConfigurator> shadowSocksConfigurator;
std::shared_ptr<CloakConfigurator> cloakConfigurator;
std::shared_ptr<WireguardConfigurator> wireguardConfigurator;
std::shared_ptr<Ikev2Configurator> ikev2Configurator;
std::shared_ptr<SshConfigurator> sshConfigurator;
}; };
#endif // VPN_CONFIGURATOR_H #endif // VPN_CONFIGURATOR_H

View file

@ -5,19 +5,28 @@
#include <QTemporaryDir> #include <QTemporaryDir>
#include <QDebug> #include <QDebug>
#include <QTemporaryFile> #include <QTemporaryFile>
#include <QJsonDocument>
#include <openssl/rand.h> #include <openssl/rand.h>
#include <openssl/rsa.h> #include <openssl/rsa.h>
#include <openssl/x509.h> #include <openssl/x509.h>
#include <openssl/pem.h> #include <openssl/pem.h>
#include "sftpdefs.h"
#include "core/server_defs.h"
#include "containers/containers_defs.h" #include "containers/containers_defs.h"
#include "core/server_defs.h"
#include "core/scripts_registry.h" #include "core/scripts_registry.h"
#include "core/servercontroller.h"
#include "settings.h"
#include "utils.h" #include "utils.h"
WireguardConfigurator::WireguardConfigurator(std::shared_ptr<Settings> settings, std::shared_ptr<ServerController> serverController, QObject *parent):
ConfiguratorBase(settings, serverController, parent)
{
}
WireguardConfigurator::ConnectionData WireguardConfigurator::genClientKeys() WireguardConfigurator::ConnectionData WireguardConfigurator::genClientKeys()
{ {
// TODO review // TODO review
@ -71,7 +80,7 @@ WireguardConfigurator::ConnectionData WireguardConfigurator::prepareWireguardCon
stdOut += data + "\n"; stdOut += data + "\n";
}; };
ServerController::runContainerScript(credentials, container, script, cbReadStdOut); m_serverController->runContainerScript(credentials, container, script, cbReadStdOut);
stdOut.replace("AllowedIPs = ", ""); stdOut.replace("AllowedIPs = ", "");
stdOut.replace("/32", ""); stdOut.replace("/32", "");
QStringList ips = stdOut.split("\n", Qt::SkipEmptyParts); QStringList ips = stdOut.split("\n", Qt::SkipEmptyParts);
@ -104,14 +113,14 @@ WireguardConfigurator::ConnectionData WireguardConfigurator::prepareWireguardCon
} }
// Get keys // Get keys
connData.serverPubKey = ServerController::getTextFileFromContainer(container, credentials, amnezia::protocols::wireguard::serverPublicKeyPath, &e); connData.serverPubKey = m_serverController->getTextFileFromContainer(container, credentials, amnezia::protocols::wireguard::serverPublicKeyPath, &e);
connData.serverPubKey.replace("\n", ""); connData.serverPubKey.replace("\n", "");
if (e) { if (e) {
if (errorCode) *errorCode = e; if (errorCode) *errorCode = e;
return connData; return connData;
} }
connData.pskKey = ServerController::getTextFileFromContainer(container, credentials, amnezia::protocols::wireguard::serverPskKeyPath, &e); connData.pskKey = m_serverController->getTextFileFromContainer(container, credentials, amnezia::protocols::wireguard::serverPskKeyPath, &e);
connData.pskKey.replace("\n", ""); connData.pskKey.replace("\n", "");
if (e) { if (e) {
@ -129,7 +138,7 @@ WireguardConfigurator::ConnectionData WireguardConfigurator::prepareWireguardCon
arg(connData.pskKey). arg(connData.pskKey).
arg(connData.clientIP); arg(connData.clientIP);
e = ServerController::uploadTextFileToContainer(container, credentials, configPart, e = m_serverController->uploadTextFileToContainer(container, credentials, configPart,
protocols::wireguard::serverConfigPath, QSsh::SftpOverwriteMode::SftpAppendToExisting); protocols::wireguard::serverConfigPath, QSsh::SftpOverwriteMode::SftpAppendToExisting);
if (e) { if (e) {
@ -137,24 +146,18 @@ WireguardConfigurator::ConnectionData WireguardConfigurator::prepareWireguardCon
return connData; return connData;
} }
e = ServerController::runScript(credentials, e = m_serverController->runScript(credentials,
ServerController::replaceVars("sudo docker exec -i $CONTAINER_NAME bash -c 'wg syncconf wg0 <(wg-quick strip /opt/amnezia/wireguard/wg0.conf)'", m_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))); m_serverController->genVarsForScript(credentials, container)));
return connData; return connData;
} }
Settings &WireguardConfigurator::m_settings()
{
static Settings s;
return s;
}
QString WireguardConfigurator::genWireguardConfig(const ServerCredentials &credentials, QString WireguardConfigurator::genWireguardConfig(const ServerCredentials &credentials,
DockerContainer container, const QJsonObject &containerConfig, ErrorCode *errorCode) DockerContainer container, const QJsonObject &containerConfig, ErrorCode *errorCode)
{ {
QString config = ServerController::replaceVars(amnezia::scriptData(ProtocolScriptType::wireguard_template, container), QString config = m_serverController->replaceVars(amnezia::scriptData(ProtocolScriptType::wireguard_template, container),
ServerController::genVarsForScript(credentials, container, containerConfig)); m_serverController->genVarsForScript(credentials, container, containerConfig));
ConnectionData connData = prepareWireguardConfig(credentials, container, containerConfig, errorCode); ConnectionData connData = prepareWireguardConfig(credentials, container, containerConfig, errorCode);
if (errorCode && *errorCode) { if (errorCode && *errorCode) {
@ -182,8 +185,8 @@ QString WireguardConfigurator::genWireguardConfig(const ServerCredentials &crede
QString WireguardConfigurator::processConfigWithLocalSettings(QString config) QString WireguardConfigurator::processConfigWithLocalSettings(QString config)
{ {
// TODO replace DNS if it already set // TODO replace DNS if it already set
config.replace("$PRIMARY_DNS", m_settings().primaryDns()); config.replace("$PRIMARY_DNS", m_settings->primaryDns());
config.replace("$SECONDARY_DNS", m_settings().secondaryDns()); config.replace("$SECONDARY_DNS", m_settings->secondaryDns());
QJsonObject jConfig; QJsonObject jConfig;
jConfig[config_key::config] = config; jConfig[config_key::config] = config;
@ -193,8 +196,8 @@ QString WireguardConfigurator::processConfigWithLocalSettings(QString config)
QString WireguardConfigurator::processConfigWithExportSettings(QString config) QString WireguardConfigurator::processConfigWithExportSettings(QString config)
{ {
config.replace("$PRIMARY_DNS", m_settings().primaryDns()); config.replace("$PRIMARY_DNS", m_settings->primaryDns());
config.replace("$SECONDARY_DNS", m_settings().secondaryDns()); config.replace("$SECONDARY_DNS", m_settings->secondaryDns());
return config; return config;
} }

View file

@ -4,13 +4,15 @@
#include <QObject> #include <QObject>
#include <QProcessEnvironment> #include <QProcessEnvironment>
#include "configurator_base.h"
#include "core/defs.h" #include "core/defs.h"
#include "settings.h"
#include "core/servercontroller.h"
class WireguardConfigurator class WireguardConfigurator : ConfiguratorBase
{ {
Q_OBJECT
public: public:
WireguardConfigurator(std::shared_ptr<Settings> settings,
std::shared_ptr<ServerController> serverController, QObject *parent = nullptr);
struct ConnectionData { struct ConnectionData {
QString clientPrivKey; // client private key QString clientPrivKey; // client private key
@ -21,20 +23,18 @@ public:
QString host; // host ip QString host; // host ip
}; };
static QString genWireguardConfig(const ServerCredentials &credentials, DockerContainer container, QString genWireguardConfig(const ServerCredentials &credentials, DockerContainer container,
const QJsonObject &containerConfig, ErrorCode *errorCode = nullptr); const QJsonObject &containerConfig, ErrorCode *errorCode = nullptr);
static QString processConfigWithLocalSettings(QString config); QString processConfigWithLocalSettings(QString config);
static QString processConfigWithExportSettings(QString config); QString processConfigWithExportSettings(QString config);
private: private:
static ConnectionData prepareWireguardConfig(const ServerCredentials &credentials, ConnectionData prepareWireguardConfig(const ServerCredentials &credentials,
DockerContainer container, const QJsonObject &containerConfig, ErrorCode *errorCode = nullptr); DockerContainer container, const QJsonObject &containerConfig, ErrorCode *errorCode = nullptr);
static ConnectionData genClientKeys(); ConnectionData genClientKeys();
static Settings &m_settings();
}; };
#endif // WIREGUARD_CONFIGURATOR_H #endif // WIREGUARD_CONFIGURATOR_H

View file

@ -18,18 +18,18 @@
#include "containers/containers_defs.h" #include "containers/containers_defs.h"
#include "server_defs.h" #include "server_defs.h"
#include "settings.h"
#include "scripts_registry.h" #include "scripts_registry.h"
#include "utils.h" #include "utils.h"
#include <configurators/vpn_configurator.h> #include <configurators/vpn_configurator.h>
using namespace QSsh; using namespace QSsh;
Settings &ServerController::m_settings() ServerController::ServerController(std::shared_ptr<Settings> settings, QObject *parent) :
m_settings(settings)
{ {
static Settings s;
return s;
} }
ErrorCode ServerController::runScript(const ServerCredentials &credentials, QString script, ErrorCode ServerController::runScript(const ServerCredentials &credentials, QString script,
@ -605,7 +605,7 @@ ErrorCode ServerController::configureContainerWorker(const ServerCredentials &cr
cbReadStdOut, cbReadStdErr); cbReadStdOut, cbReadStdErr);
VpnConfigurator::updateContainerConfigAfterInstallation(container, config, stdOut); m_configurator->updateContainerConfigAfterInstallation(container, config, stdOut);
return e; return e;
} }
@ -698,8 +698,8 @@ ServerController::Vars ServerController::genVarsForScript(const ServerCredential
vars.append({{"$IPSEC_VPN_C2C_TRAFFIC", "no"}}); vars.append({{"$IPSEC_VPN_C2C_TRAFFIC", "no"}});
vars.append({{"$PRIMARY_SERVER_DNS", m_settings().primaryDns()}}); vars.append({{"$PRIMARY_SERVER_DNS", m_settings->primaryDns()}});
vars.append({{"$SECONDARY_SERVER_DNS", m_settings().secondaryDns()}}); vars.append({{"$SECONDARY_SERVER_DNS", m_settings->secondaryDns()}});
// Sftp vars // Sftp vars

View file

@ -7,78 +7,83 @@
#include "sshremoteprocess.h" #include "sshremoteprocess.h"
#include "debug.h" #include "debug.h"
#include "defs.h" #include "defs.h"
#include "settings.h"
#include "containers/containers_defs.h" #include "containers/containers_defs.h"
#include "sftpdefs.h" #include "sftpdefs.h"
class Settings;
class VpnConfigurator;
using namespace amnezia; using namespace amnezia;
class ServerController : public QObject class ServerController : public QObject
{ {
Q_OBJECT Q_OBJECT
public: public:
ServerController(std::shared_ptr<Settings> settings, QObject *parent = nullptr);
typedef QList<QPair<QString, QString>> Vars; typedef QList<QPair<QString, QString>> Vars;
static ErrorCode fromSshConnectionErrorCode(QSsh::SshError error); ErrorCode fromSshConnectionErrorCode(QSsh::SshError error);
// QSsh exitCode and exitStatus are different things // QSsh exitCode and exitStatus are different things
static ErrorCode fromSshProcessExitStatus(int exitStatus); ErrorCode fromSshProcessExitStatus(int exitStatus);
static QSsh::SshConnectionParameters sshParams(const ServerCredentials &credentials); QSsh::SshConnectionParameters sshParams(const ServerCredentials &credentials);
static void disconnectFromHost(const ServerCredentials &credentials); void disconnectFromHost(const ServerCredentials &credentials);
static ErrorCode removeAllContainers(const ServerCredentials &credentials); ErrorCode removeAllContainers(const ServerCredentials &credentials);
static ErrorCode removeContainer(const ServerCredentials &credentials, DockerContainer container); ErrorCode removeContainer(const ServerCredentials &credentials, DockerContainer container);
static ErrorCode setupContainer(const ServerCredentials &credentials, DockerContainer container, QJsonObject &config); ErrorCode setupContainer(const ServerCredentials &credentials, DockerContainer container, QJsonObject &config);
static ErrorCode updateContainer(const ServerCredentials &credentials, DockerContainer container, ErrorCode updateContainer(const ServerCredentials &credentials, DockerContainer container,
const QJsonObject &oldConfig, QJsonObject &newConfig); const QJsonObject &oldConfig, QJsonObject &newConfig);
// create initial config - generate passwords, etc // create initial config - generate passwords, etc
static QJsonObject createContainerInitialConfig(DockerContainer container, int port, TransportProto tp); QJsonObject createContainerInitialConfig(DockerContainer container, int port, TransportProto tp);
static bool isReinstallContainerRequred(DockerContainer container, const QJsonObject &oldConfig, const QJsonObject &newConfig); bool isReinstallContainerRequred(DockerContainer container, const QJsonObject &oldConfig, const QJsonObject &newConfig);
static ErrorCode checkOpenVpnServer(DockerContainer container, const ServerCredentials &credentials); ErrorCode checkOpenVpnServer(DockerContainer container, const ServerCredentials &credentials);
static ErrorCode uploadFileToHost(const ServerCredentials &credentials, const QByteArray &data, ErrorCode uploadFileToHost(const ServerCredentials &credentials, const QByteArray &data,
const QString &remotePath, QSsh::SftpOverwriteMode overwriteMode = QSsh::SftpOverwriteMode::SftpOverwriteExisting); const QString &remotePath, QSsh::SftpOverwriteMode overwriteMode = QSsh::SftpOverwriteMode::SftpOverwriteExisting);
static ErrorCode uploadTextFileToContainer(DockerContainer container, 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); QSsh::SftpOverwriteMode overwriteMode = QSsh::SftpOverwriteMode::SftpOverwriteExisting);
static QByteArray getTextFileFromContainer(DockerContainer container, QByteArray getTextFileFromContainer(DockerContainer container,
const ServerCredentials &credentials, const QString &path, ErrorCode *errorCode = nullptr); const ServerCredentials &credentials, const QString &path, ErrorCode *errorCode = nullptr);
static ErrorCode setupServerFirewall(const ServerCredentials &credentials); ErrorCode setupServerFirewall(const ServerCredentials &credentials);
static QString replaceVars(const QString &script, const Vars &vars); QString replaceVars(const QString &script, const Vars &vars);
static ErrorCode runScript(const ServerCredentials &credentials, QString script, ErrorCode runScript(const ServerCredentials &credentials, QString script,
const std::function<void(const QString &, QSharedPointer<QSsh::SshRemoteProcess>)> &cbReadStdOut = nullptr, const std::function<void(const QString &, QSharedPointer<QSsh::SshRemoteProcess>)> &cbReadStdOut = nullptr,
const std::function<void(const QString &, QSharedPointer<QSsh::SshRemoteProcess>)> &cbReadStdErr = nullptr); const std::function<void(const QString &, QSharedPointer<QSsh::SshRemoteProcess>)> &cbReadStdErr = nullptr);
static ErrorCode runContainerScript(const ServerCredentials &credentials, DockerContainer container, QString script, ErrorCode runContainerScript(const ServerCredentials &credentials, DockerContainer container, QString script,
const std::function<void(const QString &, QSharedPointer<QSsh::SshRemoteProcess>)> &cbReadStdOut = nullptr, const std::function<void(const QString &, QSharedPointer<QSsh::SshRemoteProcess>)> &cbReadStdOut = nullptr,
const std::function<void(const QString &, QSharedPointer<QSsh::SshRemoteProcess>)> &cbReadStdErr = nullptr); const std::function<void(const QString &, QSharedPointer<QSsh::SshRemoteProcess>)> &cbReadStdErr = nullptr);
static Vars genVarsForScript(const ServerCredentials &credentials, DockerContainer container = DockerContainer::None, const QJsonObject &config = QJsonObject()); Vars genVarsForScript(const ServerCredentials &credentials, DockerContainer container = DockerContainer::None, const QJsonObject &config = QJsonObject());
static QString checkSshConnection(const ServerCredentials &credentials, ErrorCode *errorCode = nullptr); QString checkSshConnection(const ServerCredentials &credentials, ErrorCode *errorCode = nullptr);
static QSsh::SshConnection *connectToHost(const QSsh::SshConnectionParameters &sshParams); QSsh::SshConnection *connectToHost(const QSsh::SshConnectionParameters &sshParams);
private: private:
static ErrorCode installDockerWorker(const ServerCredentials &credentials, DockerContainer container); ErrorCode installDockerWorker(const ServerCredentials &credentials, DockerContainer container);
static ErrorCode prepareHostWorker(const ServerCredentials &credentials, DockerContainer container, const QJsonObject &config = QJsonObject()); ErrorCode prepareHostWorker(const ServerCredentials &credentials, DockerContainer container, const QJsonObject &config = QJsonObject());
static ErrorCode buildContainerWorker(const ServerCredentials &credentials, DockerContainer container, const QJsonObject &config = QJsonObject()); ErrorCode buildContainerWorker(const ServerCredentials &credentials, DockerContainer container, const QJsonObject &config = QJsonObject());
static ErrorCode runContainerWorker(const ServerCredentials &credentials, DockerContainer container, QJsonObject &config); ErrorCode runContainerWorker(const ServerCredentials &credentials, DockerContainer container, QJsonObject &config);
static ErrorCode configureContainerWorker(const ServerCredentials &credentials, DockerContainer container, QJsonObject &config); ErrorCode configureContainerWorker(const ServerCredentials &credentials, DockerContainer container, QJsonObject &config);
static ErrorCode startupContainerWorker(const ServerCredentials &credentials, DockerContainer container, const QJsonObject &config = QJsonObject()); ErrorCode startupContainerWorker(const ServerCredentials &credentials, DockerContainer container, const QJsonObject &config = QJsonObject());
static Settings &m_settings(); std::shared_ptr<Settings> m_settings;
std::shared_ptr<VpnConfigurator> m_configurator;
}; };
#endif // SERVERCONTROLLER_H #endif // SERVERCONTROLLER_H

View file

@ -4,7 +4,7 @@
#define APPLICATION_NAME "AmneziaVPN" #define APPLICATION_NAME "AmneziaVPN"
#define SERVICE_NAME "AmneziaVPN-service" #define SERVICE_NAME "AmneziaVPN-service"
#define ORGANIZATION_NAME "AmneziaVPN.ORG" #define ORGANIZATION_NAME "AmneziaVPN.ORG"
#define APP_MAJOR_VERSION "2.0.10" #define APP_MAJOR_VERSION "2.1.0"
#define APP_VERSION "2.0.10.0" #define APP_VERSION "2.1.0.0"
#endif // DEFINES_H #endif // DEFINES_H

View file

@ -1,54 +1,10 @@
#include <QApplication>
#include <QFontDatabase>
#include <QCommandLineParser>
#include <QMessageBox>
#include <QTranslator>
#include <QTimer>
#include <QLoggingCategory> #include <QLoggingCategory>
#include <QGuiApplication>
#include <QQmlApplicationEngine>
#include <QQmlContext>
#include "ui/uilogic.h"
#include <QDebug> #include <QDebug>
#include <QTimer>
#include "ui/pages.h" #include "amnezia_application.h"
#include "ui/pages_logic/AppSettingsLogic.h"
#include "ui/pages_logic/GeneralSettingsLogic.h"
#include "ui/pages_logic/NetworkSettingsLogic.h"
#include "ui/pages_logic/NewServerProtocolsLogic.h"
#include "ui/pages_logic/QrDecoderLogic.h"
#include "ui/pages_logic/ServerConfiguringProgressLogic.h"
#include "ui/pages_logic/ServerContainersLogic.h"
#include "ui/pages_logic/ServerListLogic.h"
#include "ui/pages_logic/ServerSettingsLogic.h"
#include "ui/pages_logic/ServerContainersLogic.h"
#include "ui/pages_logic/ShareConnectionLogic.h"
#include "ui/pages_logic/SitesLogic.h"
#include "ui/pages_logic/StartPageLogic.h"
#include "ui/pages_logic/VpnLogic.h"
#include "ui/pages_logic/WizardLogic.h"
#include "ui/pages_logic/protocols/CloakLogic.h"
#include "ui/pages_logic/protocols/OpenVpnLogic.h"
#include "ui/pages_logic/protocols/ShadowSocksLogic.h"
#include "ui/uilogic.h"
#include "QZXing.h"
#include "platforms/ios/QRCodeReaderBase.h"
#include "debug.h"
#include "defines.h" #include "defines.h"
#if !defined(Q_OS_ANDROID) && !defined(Q_OS_IOS)
#define QAPPLICATION_CLASS QGuiApplication
#include "singleapplication.h"
#undef QAPPLICATION_CLASS
#endif
#ifdef Q_OS_WIN #ifdef Q_OS_WIN
#include "Windows.h" #include "Windows.h"
#endif #endif
@ -58,29 +14,24 @@
#endif #endif
#if defined(Q_OS_IOS) #if defined(Q_OS_IOS)
#include "QtAppDelegate-C-Interface.h" #include "platforms/ios/QtAppDelegate-C-Interface.h"
#endif #endif
static void loadTranslator()
{
QTranslator* translator = new QTranslator;
if (translator->load(QLocale(), QString("amneziavpn"), QLatin1String("_"), QLatin1String(":/translations"))) {
qApp->installTranslator(translator);
}
}
int main(int argc, char *argv[]) int main(int argc, char *argv[])
{ {
QLoggingCategory::setFilterRules(QStringLiteral("qtc.ssh=false")); QLoggingCategory::setFilterRules(QStringLiteral("qtc.ssh=false"));
QGuiApplication::setAttribute(Qt::AA_EnableHighDpiScaling, true); QGuiApplication::setAttribute(Qt::AA_EnableHighDpiScaling, true);
#ifdef Q_OS_WIN #ifdef Q_OS_WIN
AllowSetForegroundWindow(ASFW_ANY); AllowSetForegroundWindow(ASFW_ANY);
#endif #endif
#if !defined(Q_OS_ANDROID) && !defined(Q_OS_IOS)
SingleApplication app(argc, argv, true, SingleApplication::Mode::User | SingleApplication::Mode::SecondaryNotification); #if defined(Q_OS_ANDROID) || defined(Q_OS_IOS)
AmneziaApplication app(argc, argv);
#else
AmneziaApplication app(argc, argv, true, SingleApplication::Mode::User | SingleApplication::Mode::SecondaryNotification);
if (!app.isPrimary()) { if (!app.isPrimary()) {
QTimer::singleShot(1000, &app, [&](){ QTimer::singleShot(1000, &app, [&](){
@ -88,10 +39,9 @@ int main(int argc, char *argv[])
}); });
return app.exec(); return app.exec();
} }
#else
QApplication app(argc, argv);
#endif #endif
// Allow to raise app window if secondary instance launched
#ifdef Q_OS_WIN #ifdef Q_OS_WIN
AllowSetForegroundWindow(0); AllowSetForegroundWindow(0);
#endif #endif
@ -104,147 +54,20 @@ int main(int argc, char *argv[])
QtAppDelegateInitialize(); QtAppDelegateInitialize();
#endif #endif
loadTranslator(); app.registerTypes();
QFontDatabase::addApplicationFont(":/fonts/Lato-Black.ttf");
QFontDatabase::addApplicationFont(":/fonts/Lato-BlackItalic.ttf");
QFontDatabase::addApplicationFont(":/fonts/Lato-Bold.ttf");
QFontDatabase::addApplicationFont(":/fonts/Lato-BoldItalic.ttf");
QFontDatabase::addApplicationFont(":/fonts/Lato-Italic.ttf");
QFontDatabase::addApplicationFont(":/fonts/Lato-Light.ttf");
QFontDatabase::addApplicationFont(":/fonts/Lato-LightItalic.ttf");
QFontDatabase::addApplicationFont(":/fonts/Lato-Regular.ttf");
QFontDatabase::addApplicationFont(":/fonts/Lato-Thin.ttf");
QFontDatabase::addApplicationFont(":/fonts/Lato-ThinItalic.ttf");
app.setApplicationName(APPLICATION_NAME); app.setApplicationName(APPLICATION_NAME);
app.setOrganizationName(ORGANIZATION_NAME); app.setOrganizationName(ORGANIZATION_NAME);
app.setApplicationDisplayName(APPLICATION_NAME); app.setApplicationDisplayName(APPLICATION_NAME);
QCommandLineParser parser; app.loadTranslator();
parser.setApplicationDescription(APPLICATION_NAME); app.loadFonts();
parser.addHelpOption();
parser.addVersionOption();
QCommandLineOption c_autostart {{"a", "autostart"}, "System autostart"}; bool doExec = app.parseCommands();
parser.addOption(c_autostart);
QCommandLineOption c_cleanup {{"c", "cleanup"}, "Cleanup logs"}; if (doExec) {
parser.addOption(c_cleanup); app.init();
return app.exec();
parser.process(app);
if (parser.isSet(c_cleanup)) {
Debug::cleanUp();
QTimer::singleShot(100,[&app]{
app.quit();
});
app.exec();
return 0;
} }
return 0;
Settings settings;
if (settings.isSaveLogs()) {
if (!Debug::init()) {
qWarning() << "Initialization of debug subsystem failed";
}
}
app.setQuitOnLastWindowClosed(false);
QZXing::registerQMLTypes();
qRegisterMetaType<VpnProtocol::VpnConnectionState>("VpnProtocol::VpnConnectionState");
qRegisterMetaType<ServerCredentials>("ServerCredentials");
qRegisterMetaType<DockerContainer>("DockerContainer");
qRegisterMetaType<TransportProto>("TransportProto");
qRegisterMetaType<Proto>("Proto");
qRegisterMetaType<ServiceType>("ServiceType");
qRegisterMetaType<Page>("Page");
qRegisterMetaType<VpnProtocol::VpnConnectionState>("ConnectionState");
qRegisterMetaType<PageProtocolLogicBase *>("PageProtocolLogicBase *");
UiLogic *uiLogic = new UiLogic;
QQmlApplicationEngine *engine = new QQmlApplicationEngine;
declareQmlPageEnum();
declareQmlProtocolEnum();
declareQmlContainerEnum();
qmlRegisterType<PageType>("PageType", 1, 0, "PageType");
qmlRegisterType<QRCodeReader>("QRCodeReader", 1, 0, "QRCodeReader");
QScopedPointer<ContainerProps> containerProps(new ContainerProps);
qmlRegisterSingletonInstance("ContainerProps", 1, 0, "ContainerProps", containerProps.get());
QScopedPointer<ProtocolProps> protocolProps(new ProtocolProps);
qmlRegisterSingletonInstance("ProtocolProps", 1, 0, "ProtocolProps", protocolProps.get());
const QUrl url(QStringLiteral("qrc:/ui/qml/main.qml"));
QObject::connect(engine, &QQmlApplicationEngine::objectCreated,
&app, [url](QObject *obj, const QUrl &objUrl) {
if (!obj && url == objUrl)
QCoreApplication::exit(-1);
}, Qt::QueuedConnection);
engine->rootContext()->setContextProperty("Debug", &Debug::Instance());
engine->rootContext()->setContextProperty("UiLogic", uiLogic);
engine->rootContext()->setContextProperty("AppSettingsLogic", uiLogic->appSettingsLogic());
engine->rootContext()->setContextProperty("GeneralSettingsLogic", uiLogic->generalSettingsLogic());
engine->rootContext()->setContextProperty("NetworkSettingsLogic", uiLogic->networkSettingsLogic());
engine->rootContext()->setContextProperty("NewServerProtocolsLogic", uiLogic->newServerProtocolsLogic());
engine->rootContext()->setContextProperty("QrDecoderLogic", uiLogic->qrDecoderLogic());
engine->rootContext()->setContextProperty("ServerConfiguringProgressLogic", uiLogic->serverConfiguringProgressLogic());
engine->rootContext()->setContextProperty("ServerListLogic", uiLogic->serverListLogic());
engine->rootContext()->setContextProperty("ServerSettingsLogic", uiLogic->serverSettingsLogic());
engine->rootContext()->setContextProperty("ServerContainersLogic", uiLogic->serverprotocolsLogic());
engine->rootContext()->setContextProperty("ShareConnectionLogic", uiLogic->shareConnectionLogic());
engine->rootContext()->setContextProperty("SitesLogic", uiLogic->sitesLogic());
engine->rootContext()->setContextProperty("StartPageLogic", uiLogic->startPageLogic());
engine->rootContext()->setContextProperty("VpnLogic", uiLogic->vpnLogic());
engine->rootContext()->setContextProperty("WizardLogic", uiLogic->wizardLogic());
#if defined(Q_OS_IOS)
setStartPageLogic(uiLogic->startPageLogic());
#endif
engine->load(url);
QObject::connect(&app, &QCoreApplication::aboutToQuit, uiLogic, [&engine, uiLogic](){
QObject::disconnect(engine, 0,0,0);
delete engine;
QObject::disconnect(uiLogic, 0,0,0);
delete uiLogic;
});
if (engine->rootObjects().size() > 0) {
uiLogic->setQmlRoot(engine->rootObjects().at(0));
}
#ifdef Q_OS_WIN
if (parser.isSet("a")) uiLogic->showOnStartup();
else emit uiLogic->show();
#else
uiLogic->showOnStartup();
#endif
// TODO - fix
#if !defined(Q_OS_ANDROID) && !defined(Q_OS_IOS)
if (app.isPrimary()) {
QObject::connect(&app, &SingleApplication::instanceStarted, uiLogic, [&](){
qDebug() << "Secondary instance started, showing this window instead";
emit uiLogic->show();
emit uiLogic->raise();
});
}
#endif
return app.exec();
} }

View file

@ -1,5 +1,5 @@
#include "MobileUtils.h" #include "MobileUtils.h"
void MobileUtils::shareText(const QStringList& filesToSend) { void MobileUtils::shareText(const QStringList&) {}
}

View file

@ -12,6 +12,7 @@ public:
public slots: public slots:
static void shareText(const QStringList& filesToSend); static void shareText(const QStringList& filesToSend);
}; };
#endif // MOBILEUTILS_H #endif // MOBILEUTILS_H

View file

@ -1,6 +1,9 @@
#include "MobileUtils.h" #include "MobileUtils.h"
#include <UIKit/UIKit.h> #include <UIKit/UIKit.h>
#include <Security/Security.h>
#include <QDebug>
static UIViewController* getViewController() { static UIViewController* getViewController() {
NSArray *windows = [[UIApplication sharedApplication]windows]; NSArray *windows = [[UIApplication sharedApplication]windows];
@ -31,3 +34,4 @@ void MobileUtils::shareText(const QStringList& filesToSend) {
popController.sourceView = qtController.view; popController.sourceView = qtController.view;
} }
} }

View file

@ -199,7 +199,7 @@ ErrorCode Ikev2Protocol::start()
setLastError(ErrorCode::AmneziaServiceConnectionFailed); setLastError(ErrorCode::AmneziaServiceConnectionFailed);
return ErrorCode::AmneziaServiceConnectionFailed; return ErrorCode::AmneziaServiceConnectionFailed;
} }
certInstallProcess->setProgram("certutil"); certInstallProcess->setProgram(PermittedProcess::CertUtil);
QStringList arguments({"-f" , "-importpfx", QStringList arguments({"-f" , "-importpfx",
"-p", m_config[config_key::password].toString(), "-p", m_config[config_key::password].toString(),
certFile.fileName(), "NoExport" certFile.fileName(), "NoExport"

View file

@ -1,5 +1,4 @@
#include "openvpnovercloakprotocol.h" #include "openvpnovercloakprotocol.h"
#include "core/servercontroller.h"
#include "utils.h" #include "utils.h"
#include "containers/containers_defs.h" #include "containers/containers_defs.h"

View file

@ -1,8 +1,9 @@
#include <QCoreApplication> #include <QCoreApplication>
#include <QFileInfo> #include <QFileInfo>
#include <QProcess> #include <QProcess>
#include <QRegularExpression>
#include <QTcpSocket> #include <QTcpSocket>
#include <QTcpServer>
#include <QRandomGenerator>
#include "debug.h" #include "debug.h"
#include "defines.h" #include "defines.h"
@ -122,6 +123,21 @@ void OpenVpnProtocol::sendManagementCommand(const QString& command)
} }
} }
uint OpenVpnProtocol::selectMgmtPort()
{
for (int i = 0; i < 100; ++i) {
quint32 port = QRandomGenerator::global()->generate();
port = (double)(65000-15001) * port / UINT32_MAX + 15001;
QTcpServer s;
bool ok = s.listen(QHostAddress::LocalHost, port);
if (ok) return port;
}
return m_managementPort;
}
void OpenVpnProtocol::updateRouteGateway(QString line) void OpenVpnProtocol::updateRouteGateway(QString line)
{ {
// TODO: fix for macos // TODO: fix for macos
@ -132,24 +148,13 @@ void OpenVpnProtocol::updateRouteGateway(QString line)
qDebug() << "Set VPN route gateway" << m_routeGateway; qDebug() << "Set VPN route gateway" << m_routeGateway;
} }
QString OpenVpnProtocol::openVpnExecPath() const
{
#ifdef Q_OS_WIN
return Utils::executable("openvpn/openvpn", true);
#elif defined Q_OS_LINUX
return Utils::usrExecutable("openvpn");
#else
return Utils::executable("/openvpn", true);
#endif
}
ErrorCode OpenVpnProtocol::start() ErrorCode OpenVpnProtocol::start()
{ {
#ifndef Q_OS_IOS #ifndef Q_OS_IOS
//qDebug() << "Start OpenVPN connection"; //qDebug() << "Start OpenVPN connection";
OpenVpnProtocol::stop(); OpenVpnProtocol::stop();
if (!QFileInfo::exists(openVpnExecPath())) { if (!QFileInfo::exists(Utils::openVpnExecPath())) {
setLastError(ErrorCode::OpenVpnExecutableMissing); setLastError(ErrorCode::OpenVpnExecutableMissing);
return lastError(); return lastError();
} }
@ -162,7 +167,10 @@ ErrorCode OpenVpnProtocol::start()
// QString vpnLogFileNamePath = Utils::systemLogPath() + "/openvpn.log"; // QString vpnLogFileNamePath = Utils::systemLogPath() + "/openvpn.log";
// Utils::createEmptyFile(vpnLogFileNamePath); // Utils::createEmptyFile(vpnLogFileNamePath);
if (!m_managementServer.start(m_managementHost, m_managementPort)) { uint mgmtPort = selectMgmtPort();
qDebug() << "OpenVpnProtocol::start mgmt port selected:" << mgmtPort;
if (!m_managementServer.start(m_managementHost, mgmtPort)) {
setLastError(ErrorCode::OpenVpnManagementServerError); setLastError(ErrorCode::OpenVpnManagementServerError);
return lastError(); return lastError();
} }
@ -183,9 +191,9 @@ ErrorCode OpenVpnProtocol::start()
setLastError(ErrorCode::AmneziaServiceConnectionFailed); setLastError(ErrorCode::AmneziaServiceConnectionFailed);
return ErrorCode::AmneziaServiceConnectionFailed; return ErrorCode::AmneziaServiceConnectionFailed;
} }
m_openVpnProcess->setProgram(openVpnExecPath()); m_openVpnProcess->setProgram(PermittedProcess::OpenVPN);
QStringList arguments({"--config" , configPath(), QStringList arguments({"--config" , configPath(),
"--management", m_managementHost, QString::number(m_managementPort), "--management", m_managementHost, QString::number(mgmtPort),
"--management-client"/*, "--log", vpnLogFileNamePath */ "--management-client"/*, "--log", vpnLogFileNamePath */
}); });
m_openVpnProcess->setArguments(arguments); m_openVpnProcess->setArguments(arguments);

View file

@ -30,7 +30,6 @@ protected slots:
private: private:
QString configPath() const; QString configPath() const;
QString openVpnExecPath() const;
bool openVpnProcessIsRunning() const; bool openVpnProcessIsRunning() const;
bool sendTermSignal(); bool sendTermSignal();
void readOpenVpnConfiguration(const QJsonObject &configuration); void readOpenVpnConfiguration(const QJsonObject &configuration);
@ -47,6 +46,8 @@ private:
QString m_configFileName; QString m_configFileName;
QTemporaryFile m_configFile; QTemporaryFile m_configFile;
uint selectMgmtPort();
private: private:
void updateRouteGateway(QString line); void updateRouteGateway(QString line);
void updateVpnGateway(const QString &line); void updateVpnGateway(const QString &line);

View file

@ -1,5 +1,4 @@
#include "shadowsocksvpnprotocol.h" #include "shadowsocksvpnprotocol.h"
#include "core/servercontroller.h"
#include "debug.h" #include "debug.h"
#include "utils.h" #include "utils.h"

View file

@ -1,7 +1,6 @@
#include <QCoreApplication> #include <QCoreApplication>
#include <QFileInfo> #include <QFileInfo>
#include <QProcess> #include <QProcess>
#include <QRegularExpression>
#include <QTcpSocket> #include <QTcpSocket>
#include <QThread> #include <QThread>
@ -12,25 +11,20 @@
WireguardProtocol::WireguardProtocol(const QJsonObject &configuration, QObject* parent) : WireguardProtocol::WireguardProtocol(const QJsonObject &configuration, QObject* parent) :
VpnProtocol(configuration, parent) VpnProtocol(configuration, parent)
{ {
//m_configFile.setFileTemplate(QDir::tempPath() + QDir::separator() + serviceName() + ".conf");
m_configFile.setFileName(QDir::tempPath() + QDir::separator() + serviceName() + ".conf"); m_configFile.setFileName(QDir::tempPath() + QDir::separator() + serviceName() + ".conf");
readWireguardConfiguration(configuration); readWireguardConfiguration(configuration);
} }
WireguardProtocol::~WireguardProtocol() WireguardProtocol::~WireguardProtocol()
{ {
//qDebug() << "WireguardProtocol::~WireguardProtocol() 1";
WireguardProtocol::stop(); WireguardProtocol::stop();
QThread::msleep(200); QThread::msleep(200);
//qDebug() << "WireguardProtocol::~WireguardProtocol() 2";
} }
void WireguardProtocol::stop() void WireguardProtocol::stop()
{ {
//qDebug() << "WireguardProtocol::stop() 1";
#ifndef Q_OS_IOS #ifndef Q_OS_IOS
if (!QFileInfo::exists(wireguardExecPath())) { if (!QFileInfo::exists(Utils::wireguardExecPath())) {
qCritical() << "Wireguard executable missing!"; qCritical() << "Wireguard executable missing!";
setLastError(ErrorCode::ExecutableMissing); setLastError(ErrorCode::ExecutableMissing);
return; return;
@ -51,7 +45,7 @@ void WireguardProtocol::stop()
return; return;
} }
m_wireguardStopProcess->setProgram(wireguardExecPath()); m_wireguardStopProcess->setProgram(PermittedProcess::Wireguard);
QStringList arguments({"--remove", configPath()}); QStringList arguments({"--remove", configPath()});
@ -74,7 +68,6 @@ void WireguardProtocol::stop()
setConnectionState(VpnProtocol::Disconnected); setConnectionState(VpnProtocol::Disconnected);
#endif #endif
//qDebug() << "WireguardProtocol::stop() 2";
} }
void WireguardProtocol::readWireguardConfiguration(const QJsonObject &configuration) void WireguardProtocol::readWireguardConfiguration(const QJsonObject &configuration)
@ -97,11 +90,6 @@ void WireguardProtocol::readWireguardConfiguration(const QJsonObject &configurat
} }
//bool WireguardProtocol::openVpnProcessIsRunning() const
//{
// return Utils::processIsRunning("openvpn");
//}
QString WireguardProtocol::configPath() const QString WireguardProtocol::configPath() const
{ {
return m_configFileName; return m_configFileName;
@ -117,31 +105,17 @@ void WireguardProtocol::updateRouteGateway(QString line)
qDebug() << "Set VPN route gateway" << m_routeGateway; qDebug() << "Set VPN route gateway" << m_routeGateway;
} }
QString WireguardProtocol::wireguardExecPath() const
{
#ifdef Q_OS_WIN
return Utils::executable("wireguard/wireguard-service", true);
#elif defined Q_OS_LINUX
return Utils::usrExecutable("wg");
#else
return Utils::executable("/wireguard", true);
#endif
}
ErrorCode WireguardProtocol::start() ErrorCode WireguardProtocol::start()
{ {
//qDebug() << "WireguardProtocol::start() 1";
#ifndef Q_OS_IOS #ifndef Q_OS_IOS
if (!m_isConfigLoaded) { if (!m_isConfigLoaded) {
setLastError(ErrorCode::ConfigMissing); setLastError(ErrorCode::ConfigMissing);
return lastError(); return lastError();
} }
//qDebug() << "Start Wireguard connection";
WireguardProtocol::stop(); WireguardProtocol::stop();
if (!QFileInfo::exists(wireguardExecPath())) { if (!QFileInfo::exists(Utils::wireguardExecPath())) {
setLastError(ErrorCode::ExecutableMissing); setLastError(ErrorCode::ExecutableMissing);
return lastError(); return lastError();
} }
@ -156,7 +130,6 @@ ErrorCode WireguardProtocol::start()
m_wireguardStartProcess = IpcClient::CreatePrivilegedProcess(); m_wireguardStartProcess = IpcClient::CreatePrivilegedProcess();
if (!m_wireguardStartProcess) { if (!m_wireguardStartProcess) {
//qWarning() << "IpcProcess replica is not created!";
setLastError(ErrorCode::AmneziaServiceConnectionFailed); setLastError(ErrorCode::AmneziaServiceConnectionFailed);
return ErrorCode::AmneziaServiceConnectionFailed; return ErrorCode::AmneziaServiceConnectionFailed;
} }
@ -168,7 +141,7 @@ ErrorCode WireguardProtocol::start()
return ErrorCode::AmneziaServiceConnectionFailed; return ErrorCode::AmneziaServiceConnectionFailed;
} }
m_wireguardStartProcess->setProgram(wireguardExecPath()); m_wireguardStartProcess->setProgram(PermittedProcess::Wireguard);
QStringList arguments({"--add", configPath()}); QStringList arguments({"--add", configPath()});
@ -210,8 +183,6 @@ ErrorCode WireguardProtocol::start()
m_wireguardStartProcess->start(); m_wireguardStartProcess->start();
m_wireguardStartProcess->waitForFinished(10000); m_wireguardStartProcess->waitForFinished(10000);
//qDebug() << "WireguardProtocol::start() 2";
return ErrorCode::NoError; return ErrorCode::NoError;
#else #else
return ErrorCode::NotImplementedError; return ErrorCode::NotImplementedError;

View file

@ -23,8 +23,6 @@ public:
private: private:
QString configPath() const; QString configPath() const;
QString wireguardExecPath() const;
//bool openVpnProcessIsRunning() const;
void readWireguardConfiguration(const QJsonObject &configuration); void readWireguardConfiguration(const QJsonObject &configuration);
void updateRouteGateway(QString line); void updateRouteGateway(QString line);

View file

@ -159,5 +159,6 @@
<file>ui/qml/Controls/SvgButtonType.qml</file> <file>ui/qml/Controls/SvgButtonType.qml</file>
<file>ui/qml/Pages/PageQrDecoderIos.qml</file> <file>ui/qml/Pages/PageQrDecoderIos.qml</file>
<file>server_scripts/website_tor/Dockerfile</file> <file>server_scripts/website_tor/Dockerfile</file>
<file>ui/qml/Pages/PageViewConfig.qml</file>
</qresource> </qresource>
</RCC> </RCC>

View file

@ -270,6 +270,6 @@ print G "done."
sed -i '' '/<string>Original<\/string>/d' AmneziaVPN.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings sed -i '' '/<string>Original<\/string>/d' AmneziaVPN.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings
fi fi
print Y "Opening in XCode..." # print Y "Opening in XCode..."
open AmneziaVPN.xcodeproj # open AmneziaVPN.xcodeproj
print G "All done!" print G "All done!"

254
client/secure_qsettings.cpp Normal file
View file

@ -0,0 +1,254 @@
#include "secure_qsettings.h"
#include "platforms/ios/MobileUtils.h"
#include <QDataStream>
#include <QDebug>
#include <QEventLoop>
#include <QJsonDocument>
#include <QJsonObject>
#include <QTimer>
#include "utils.h"
#include <QRandomGenerator>
#include "QAead.h"
#include "QBlockCipher.h"
using namespace QKeychain;
SecureQSettings::SecureQSettings(const QString &organization, const QString &application, QObject *parent)
: QObject{parent},
m_settings(organization, application, parent),
encryptedKeys({"Servers/serversList"})
{
bool encrypted = m_settings.value("Conf/encrypted").toBool();
// convert settings to encrypted for if updated to >= 2.1.0
if (encryptionRequired() && ! encrypted) {
for (const QString &key : m_settings.allKeys()) {
if (encryptedKeys.contains(key)) {
const QVariant &val = value(key);
setValue(key, val);
}
}
m_settings.setValue("Conf/encrypted", true);
m_settings.sync();
}
}
QVariant SecureQSettings::value(const QString &key, const QVariant &defaultValue) const
{
QMutexLocker locker(&mutex);
if (m_cache.contains(key)) {
return m_cache.value(key);
}
if (!m_settings.contains(key)) return defaultValue;
QVariant retVal;
// check if value is not encrypted, v. < 2.0.x
retVal = m_settings.value(key);
if (retVal.isValid()) {
if (retVal.userType() == QVariant::ByteArray &&
retVal.toByteArray().mid(0, magicString.size()) == magicString) {
if (getEncKey().isEmpty() || getEncIv().isEmpty()) {
qCritical() << "SecureQSettings::setValue Decryption requested, but key is empty";
return {};
}
QByteArray encryptedValue = retVal.toByteArray().mid(magicString.size());
QByteArray decryptedValue = decryptText(encryptedValue);
QDataStream ds(&decryptedValue, QIODevice::ReadOnly);
ds >> retVal;
if (!retVal.isValid()) {
qWarning() << "SecureQSettings::value settings decryption failed";
retVal = QVariant();
}
}
}
else {
qWarning() << "SecureQSettings::value invalid QVariant value";
retVal = QVariant();
}
m_cache.insert(key, retVal);
return retVal;
}
void SecureQSettings::setValue(const QString &key, const QVariant &value)
{
QMutexLocker locker(&mutex);
if (encryptionRequired() && encryptedKeys.contains(key)) {
if (!getEncKey().isEmpty() && !getEncIv().isEmpty()) {
QByteArray decryptedValue;
{
QDataStream ds(&decryptedValue, QIODevice::WriteOnly);
ds << value;
}
QByteArray encryptedValue = encryptText(decryptedValue);
m_settings.setValue(key, magicString + encryptedValue);
}
else {
qCritical() << "SecureQSettings::setValue Encryption required, but key is empty";
return;
}
}
else {
m_settings.setValue(key, value);
}
m_cache.insert(key, value);
sync();
}
void SecureQSettings::remove(const QString &key)
{
QMutexLocker locker(&mutex);
m_settings.remove(key);
m_cache.remove(key);
sync();
}
void SecureQSettings::sync()
{
m_settings.sync();
}
QByteArray SecureQSettings::backupAppConfig() const
{
QJsonObject cfg;
for (const QString &key : m_settings.allKeys()) {
cfg.insert(key, QJsonValue::fromVariant(value(key)));
}
return QJsonDocument(cfg).toJson();
}
bool SecureQSettings::restoreAppConfig(const QByteArray &json)
{
QJsonObject cfg = QJsonDocument::fromJson(json).object();
if (cfg.isEmpty()) return false;
for (const QString &key : cfg.keys()) {
setValue(key, cfg.value(key).toVariant());
}
sync();
return true;
}
QByteArray SecureQSettings::encryptText(const QByteArray& value) const
{
QSimpleCrypto::QBlockCipher cipher;
return cipher.encryptAesBlockCipher(value, getEncKey(), getEncIv());
}
QByteArray SecureQSettings::decryptText(const QByteArray& ba) const
{
QSimpleCrypto::QBlockCipher cipher;
return cipher.decryptAesBlockCipher(ba, getEncKey(), getEncIv());
}
bool SecureQSettings::encryptionRequired() const
{
// TODO: review on linux
return true;
}
QByteArray SecureQSettings::getEncKey() const
{
// load keys from system key storage
m_key = getSecTag(settingsKeyTag);
if (m_key.isEmpty()) {
// Create new key
QSimpleCrypto::QBlockCipher cipher;
QByteArray key = cipher.generateSecureRandomBytes(32);
if (key.isEmpty()) {
qCritical() << "SecureQSettings::getEncKey Unable to generate new enc key";
}
setSecTag(settingsKeyTag, key);
// check
m_key = getSecTag(settingsKeyTag);
if (key != m_key) {
qCritical() << "SecureQSettings::getEncKey Unable to store key in keychain" << key.size() << m_key.size();
return {};
}
}
return m_key;
}
QByteArray SecureQSettings::getEncIv() const
{
// load keys from system key storage
m_iv = getSecTag(settingsIvTag);
if (m_iv.isEmpty()) {
// Create new IV
QSimpleCrypto::QBlockCipher cipher;
QByteArray iv = cipher.generateSecureRandomBytes(32);
if (iv.isEmpty()) {
qCritical() << "SecureQSettings::getEncIv Unable to generate new enc IV";
}
setSecTag(settingsIvTag, iv);
// check
m_iv = getSecTag(settingsIvTag);
if (iv != m_iv) {
qCritical() << "SecureQSettings::getEncIv Unable to store IV in keychain" << iv.size() << m_iv.size();
return {};
}
}
return m_iv;
}
QByteArray SecureQSettings::getSecTag(const QString &tag)
{
ReadPasswordJob job(keyChainName);
job.setAutoDelete(false);
job.setKey(tag);
QEventLoop loop;
job.connect(&job, SIGNAL(finished(QKeychain::Job*)), &loop, SLOT(quit()));
job.start();
loop.exec();
if ( job.error() ) {
qCritical() << "SecureQSettings::getSecTag Error:" << job.errorString();
}
return job.binaryData();
}
void SecureQSettings::setSecTag(const QString &tag, const QByteArray &data)
{
WritePasswordJob job(keyChainName);
job.setAutoDelete(false);
job.setKey(tag);
job.setBinaryData(data);
QEventLoop loop;
QTimer::singleShot(1000, &loop, SLOT(quit()));
job.connect(&job, SIGNAL(finished(QKeychain::Job*)), &loop, SLOT(quit()));
job.start();
loop.exec();
if (job.error()) {
qCritical() << "SecureQSettings::setSecTag Error:" << job.errorString();
}
}

56
client/secure_qsettings.h Normal file
View file

@ -0,0 +1,56 @@
#ifndef SECUREQSETTINGS_H
#define SECUREQSETTINGS_H
#include <QSettings>
#include <QObject>
#include <QMutex>
#include <QMutexLocker>
#include "keychain.h"
constexpr const char* settingsKeyTag = "settingsKeyTag";
constexpr const char* settingsIvTag = "settingsIvTag";
constexpr const char* keyChainName = "AmneziaVPN-Keychain";
class SecureQSettings : public QObject
{
public:
explicit SecureQSettings(const QString &organization, const QString &application = QString(), QObject *parent = nullptr);
QVariant value(const QString &key, const QVariant &defaultValue = QVariant()) const;
void setValue(const QString &key, const QVariant &value);
void remove(const QString &key);
void sync();
QByteArray backupAppConfig() const;
bool restoreAppConfig(const QByteArray &json);
QByteArray encryptText(const QByteArray &value) const;
QByteArray decryptText(const QByteArray& ba) const;
bool encryptionRequired() const;
QByteArray getEncKey() const;
QByteArray getEncIv() const;
static QByteArray getSecTag(const QString &tag);
static void setSecTag(const QString &tag, const QByteArray &data);
private:
QSettings m_settings;
mutable QMap<QString, QVariant> m_cache;
QStringList encryptedKeys; // encode only key listed here
mutable QByteArray m_key;
mutable QByteArray m_iv;
const QByteArray magicString { "EncData" }; // Magic keyword used for mark encrypted QByteArray
mutable QMutex mutex;
};
#endif // SECUREQSETTINGS_H

View file

@ -2,15 +2,15 @@
#include "settings.h" #include "settings.h"
#include "utils.h" #include "utils.h"
#include <QDebug>
#include "containers/containers_defs.h" #include "containers/containers_defs.h"
const char Settings::cloudFlareNs1[] = "1.1.1.1"; const char Settings::cloudFlareNs1[] = "1.1.1.1";
const char Settings::cloudFlareNs2[] = "1.0.0.1"; const char Settings::cloudFlareNs2[] = "1.0.0.1";
Settings::Settings(QObject* parent) : Settings::Settings(QObject* parent) :
QObject(parent), QObject(parent),
m_settings (ORGANIZATION_NAME, APPLICATION_NAME, this) m_settings(ORGANIZATION_NAME, APPLICATION_NAME, this)
{ {
// Import old settings // Import old settings
if (serversCount() == 0) { if (serversCount() == 0) {
@ -178,7 +178,6 @@ void Settings::clearLastConnectionConfig(int serverIndex, DockerContainer contai
QJsonObject c = protocolConfig(serverIndex, container, proto); QJsonObject c = protocolConfig(serverIndex, container, proto);
c.remove(config_key::last_config); c.remove(config_key::last_config);
setProtocolConfig(serverIndex, container, proto, c); setProtocolConfig(serverIndex, container, proto, c);
qDebug() << "Settings::clearLastConnectionConfig for" << serverIndex << container << proto;
} }
bool Settings::haveAuthData(int serverIndex) const bool Settings::haveAuthData(int serverIndex) const
@ -292,60 +291,10 @@ void Settings::removeVpnSites(RouteMode mode, const QStringList &sites)
setVpnSites(mode, sitesMap); 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::primaryDns() const { return m_settings.value("Conf/primaryDns", cloudFlareNs1).toString(); }
QString Settings::secondaryDns() const { return m_settings.value("Conf/secondaryDns", cloudFlareNs2).toString(); } QString Settings::secondaryDns() const { return m_settings.value("Conf/secondaryDns", cloudFlareNs2).toString(); }
//void Settings::setServerCredentials(const ServerCredentials &credentials)
//{
// setServerName(credentials.hostName);
// setServerPort(credentials.port);
// setUserName(credentials.userName);
// setPassword(credentials.password);
//}
ServerCredentials Settings::defaultServerCredentials() const ServerCredentials Settings::defaultServerCredentials() const
{ {
return serverCredentials(defaultServerIndex()); return serverCredentials(defaultServerIndex());

View file

@ -11,6 +11,7 @@
#include "core/defs.h" #include "core/defs.h"
#include "containers/containers_defs.h" #include "containers/containers_defs.h"
#include "secure_qsettings.h"
using namespace amnezia; using namespace amnezia;
@ -25,7 +26,6 @@ public:
ServerCredentials defaultServerCredentials() const; ServerCredentials defaultServerCredentials() const;
ServerCredentials serverCredentials(int index) const; ServerCredentials serverCredentials(int index) const;
//void setServerCredentials(const ServerCredentials &credentials);
QJsonArray serversArray() const { return QJsonDocument::fromJson(m_settings.value("Servers/serversList").toByteArray()).array(); } QJsonArray serversArray() const { return QJsonDocument::fromJson(m_settings.value("Servers/serversList").toByteArray()).array(); }
void setServersArray(const QJsonArray &servers) { m_settings.setValue("Servers/serversList", QJsonDocument(servers).toJson()); } void setServersArray(const QJsonArray &servers) { m_settings.setValue("Servers/serversList", QJsonDocument(servers).toJson()); }
@ -110,13 +110,11 @@ public:
// static constexpr char openNicNs5[] = "94.103.153.176"; // static constexpr char openNicNs5[] = "94.103.153.176";
// static constexpr char openNicNs13[] = "144.76.103.143"; // static constexpr char openNicNs13[] = "144.76.103.143";
QByteArray backupAppConfig() const { return m_settings.backupAppConfig(); }
public: bool restoreAppConfig(const QByteArray &cfg) { return m_settings.restoreAppConfig(cfg); }
private: private:
QSettings m_settings; SecureQSettings m_settings;
}; };

View file

@ -1,6 +1,7 @@
#include "containers_model.h" #include "containers_model.h"
ContainersModel::ContainersModel(QObject *parent) : ContainersModel::ContainersModel(std::shared_ptr<Settings> settings, QObject *parent) :
m_settings(settings),
QAbstractListModel(parent) QAbstractListModel(parent)
{ {
@ -37,13 +38,13 @@ QVariant ContainersModel::data(const QModelIndex &index, int role) const
return ContainerProps::containerDescriptions().value(c); return ContainerProps::containerDescriptions().value(c);
} }
if (role == DefaultRole) { if (role == DefaultRole) {
return c == m_settings.defaultContainer(m_selectedServerIndex); return c == m_settings->defaultContainer(m_selectedServerIndex);
} }
if (role == ServiceTypeRole) { if (role == ServiceTypeRole) {
return ContainerProps::containerService(c); return ContainerProps::containerService(c);
} }
if (role == IsInstalledRole) { if (role == IsInstalledRole) {
return m_settings.containers(m_selectedServerIndex).contains(c); return m_settings->containers(m_selectedServerIndex).contains(c);
} }
return QVariant(); return QVariant();
} }

View file

@ -13,7 +13,7 @@ class ContainersModel : public QAbstractListModel
{ {
Q_OBJECT Q_OBJECT
public: public:
ContainersModel(QObject *parent = nullptr); ContainersModel(std::shared_ptr<Settings> settings, QObject *parent = nullptr);
public: public:
enum SiteRoles { enum SiteRoles {
NameRole = Qt::UserRole + 1, NameRole = Qt::UserRole + 1,
@ -33,7 +33,7 @@ protected:
private: private:
int m_selectedServerIndex; int m_selectedServerIndex;
Settings m_settings; std::shared_ptr<Settings> m_settings;
}; };
#endif // CONTAINERS_MODEL_H #endif // CONTAINERS_MODEL_H

View file

@ -1,6 +1,7 @@
#include "protocols_model.h" #include "protocols_model.h"
ProtocolsModel::ProtocolsModel(QObject *parent) : ProtocolsModel::ProtocolsModel(std::shared_ptr<Settings> settings, QObject *parent) :
m_settings(settings),
QAbstractListModel(parent) QAbstractListModel(parent)
{ {

View file

@ -13,7 +13,7 @@ class ProtocolsModel : public QAbstractListModel
{ {
Q_OBJECT Q_OBJECT
public: public:
ProtocolsModel(QObject *parent = nullptr); ProtocolsModel(std::shared_ptr<Settings> settings, QObject *parent = nullptr);
public: public:
enum SiteRoles { enum SiteRoles {
NameRole = Qt::UserRole + 1, NameRole = Qt::UserRole + 1,
@ -34,7 +34,7 @@ protected:
private: private:
int m_selectedServerIndex; int m_selectedServerIndex;
DockerContainer m_selectedDockerContainer; DockerContainer m_selectedDockerContainer;
Settings m_settings; std::shared_ptr<Settings> m_settings;
}; };
#endif // PROTOCOLS_MODEL_H #endif // PROTOCOLS_MODEL_H

View file

@ -1,7 +1,8 @@
#include "sites_model.h" #include "sites_model.h"
SitesModel::SitesModel(Settings::RouteMode mode, QObject *parent) SitesModel::SitesModel(std::shared_ptr<Settings> settings, Settings::RouteMode mode, QObject *parent)
: QAbstractListModel(parent), : QAbstractListModel(parent),
m_settings(settings),
m_mode(mode) m_mode(mode)
{ {
} }
@ -68,7 +69,7 @@ void SitesModel::genCache() const
qDebug() << "SitesModel::genCache"; qDebug() << "SitesModel::genCache";
m_ipsCache.clear(); m_ipsCache.clear();
const QVariantMap &sites = m_settings.vpnSites(m_mode); const QVariantMap &sites = m_settings->vpnSites(m_mode);
auto i = sites.constBegin(); auto i = sites.constBegin();
while (i != sites.constEnd()) { while (i != sites.constEnd()) {
m_ipsCache.append(qMakePair(i.key(), i.value().toString())); m_ipsCache.append(qMakePair(i.key(), i.value().toString()));

View file

@ -15,7 +15,7 @@ public:
IpRole IpRole
}; };
explicit SitesModel(Settings::RouteMode mode, QObject *parent = nullptr); explicit SitesModel(std::shared_ptr<Settings> settings, Settings::RouteMode mode, QObject *parent = nullptr);
void resetCache(); void resetCache();
// Basic functionality: // Basic functionality:
@ -32,7 +32,7 @@ private:
private: private:
Settings::RouteMode m_mode; Settings::RouteMode m_mode;
Settings m_settings; std::shared_ptr<Settings> m_settings;
mutable QVector<QPair<QString, QString>> m_ipsCache; mutable QVector<QPair<QString, QString>> m_ipsCache;
mutable bool m_cacheReady = false; mutable bool m_cacheReady = false;

View file

@ -24,7 +24,7 @@ enum class Page {Start = 0, NewServer, NewServerProtocols, Vpn,
Wizard, WizardLow, WizardMedium, WizardHigh, WizardVpnMode, ServerConfiguringProgress, Wizard, WizardLow, WizardMedium, WizardHigh, WizardVpnMode, ServerConfiguringProgress,
GeneralSettings, AppSettings, NetworkSettings, ServerSettings, GeneralSettings, AppSettings, NetworkSettings, ServerSettings,
ServerContainers, ServersList, ShareConnection, Sites, ServerContainers, ServersList, ShareConnection, Sites,
ProtocolSettings, ProtocolShare, QrDecoder, QrDecoderIos, About}; ProtocolSettings, ProtocolShare, QrDecoder, QrDecoderIos, About, ViewConfig};
Q_ENUM_NS(Page) Q_ENUM_NS(Page)
static void declareQmlPageEnum() { static void declareQmlPageEnum() {

View file

@ -7,6 +7,7 @@
#include <QDesktopServices> #include <QDesktopServices>
#include <QFileDialog> #include <QFileDialog>
#include <QMessageBox>
#include <QStandardPaths> #include <QStandardPaths>
using namespace amnezia; using namespace amnezia;
@ -25,9 +26,9 @@ AppSettingsLogic::AppSettingsLogic(UiLogic *logic, QObject *parent):
void AppSettingsLogic::onUpdatePage() void AppSettingsLogic::onUpdatePage()
{ {
set_checkBoxAutostartChecked(Autostart::isAutostart()); set_checkBoxAutostartChecked(Autostart::isAutostart());
set_checkBoxAutoConnectChecked(m_settings.isAutoConnect()); set_checkBoxAutoConnectChecked(m_settings->isAutoConnect());
set_checkBoxStartMinimizedChecked(m_settings.isStartMinimized()); set_checkBoxStartMinimizedChecked(m_settings->isStartMinimized());
set_checkBoxSaveLogsChecked(m_settings.isSaveLogs()); set_checkBoxSaveLogsChecked(m_settings->isSaveLogs());
QString ver = QString("%1: %2 (%3)") QString ver = QString("%1: %2 (%3)")
.arg(tr("Software version")) .arg(tr("Software version"))
@ -46,17 +47,17 @@ void AppSettingsLogic::onCheckBoxAutostartToggled(bool checked)
void AppSettingsLogic::onCheckBoxAutoconnectToggled(bool checked) void AppSettingsLogic::onCheckBoxAutoconnectToggled(bool checked)
{ {
m_settings.setAutoConnect(checked); m_settings->setAutoConnect(checked);
} }
void AppSettingsLogic::onCheckBoxStartMinimizedToggled(bool checked) void AppSettingsLogic::onCheckBoxStartMinimizedToggled(bool checked)
{ {
m_settings.setStartMinimized(checked); m_settings->setStartMinimized(checked);
} }
void AppSettingsLogic::onCheckBoxSaveLogsCheckedToggled(bool checked) void AppSettingsLogic::onCheckBoxSaveLogsCheckedToggled(bool checked)
{ {
m_settings.setSaveLogs(checked); m_settings->setSaveLogs(checked);
} }
void AppSettingsLogic::onPushButtonOpenLogsClicked() void AppSettingsLogic::onPushButtonOpenLogsClicked()
@ -74,3 +75,32 @@ void AppSettingsLogic::onPushButtonClearLogsClicked()
Debug::clearLogs(); Debug::clearLogs();
Debug::clearServiceLogs(); Debug::clearServiceLogs();
} }
void AppSettingsLogic::onPushButtonBackupAppConfigClicked()
{
uiLogic()->saveTextFile("Backup application config", "AmneziaVPN.backup", ".backup", m_settings->backupAppConfig());
}
void AppSettingsLogic::onPushButtonRestoreAppConfigClicked()
{
QString fileName = QFileDialog::getOpenFileName(nullptr, tr("Open backup"),
QStandardPaths::writableLocation(QStandardPaths::DocumentsLocation), "*.backup");
if (fileName.isEmpty()) return;
QFile file(fileName);
file.open(QIODevice::ReadOnly);
QByteArray data = file.readAll();
bool ok = m_settings->restoreAppConfig(data);
if (ok) {
emit uiLogic()->goToPage(Page::Vpn);
emit uiLogic()->setStartPage(Page::Vpn);
}
else {
QMessageBox::warning(nullptr, APPLICATION_NAME,
tr("Can't import config, file is corrupted."));
}
}

View file

@ -25,6 +25,10 @@ public:
Q_INVOKABLE void onPushButtonExportLogsClicked(); Q_INVOKABLE void onPushButtonExportLogsClicked();
Q_INVOKABLE void onPushButtonClearLogsClicked(); Q_INVOKABLE void onPushButtonClearLogsClicked();
Q_INVOKABLE void onPushButtonBackupAppConfigClicked();
Q_INVOKABLE void onPushButtonRestoreAppConfigClicked();
public: public:
explicit AppSettingsLogic(UiLogic *uiLogic, QObject *parent = nullptr); explicit AppSettingsLogic(UiLogic *uiLogic, QObject *parent = nullptr);
~AppSettingsLogic() = default; ~AppSettingsLogic() = default;

View file

@ -12,28 +12,28 @@ GeneralSettingsLogic::GeneralSettingsLogic(UiLogic *logic, QObject *parent):
void GeneralSettingsLogic::onUpdatePage() void GeneralSettingsLogic::onUpdatePage()
{ {
uiLogic()->selectedServerIndex = m_settings.defaultServerIndex(); uiLogic()->selectedServerIndex = m_settings->defaultServerIndex();
uiLogic()->selectedDockerContainer = m_settings.defaultContainer(m_settings.defaultServerIndex()); uiLogic()->selectedDockerContainer = m_settings->defaultContainer(m_settings->defaultServerIndex());
set_pushButtonGeneralSettingsShareConnectionEnable(m_settings.haveAuthData(m_settings.defaultServerIndex())); set_pushButtonGeneralSettingsShareConnectionEnable(m_settings->haveAuthData(m_settings->defaultServerIndex()));
} }
void GeneralSettingsLogic::onPushButtonGeneralSettingsServerSettingsClicked() void GeneralSettingsLogic::onPushButtonGeneralSettingsServerSettingsClicked()
{ {
uiLogic()->selectedServerIndex = m_settings.defaultServerIndex(); uiLogic()->selectedServerIndex = m_settings->defaultServerIndex();
uiLogic()->selectedDockerContainer = m_settings.defaultContainer(m_settings.defaultServerIndex()); uiLogic()->selectedDockerContainer = m_settings->defaultContainer(m_settings->defaultServerIndex());
emit uiLogic()->goToPage(Page::ServerSettings); emit uiLogic()->goToPage(Page::ServerSettings);
} }
void GeneralSettingsLogic::onPushButtonGeneralSettingsShareConnectionClicked() void GeneralSettingsLogic::onPushButtonGeneralSettingsShareConnectionClicked()
{ {
uiLogic()->selectedServerIndex = m_settings.defaultServerIndex(); uiLogic()->selectedServerIndex = m_settings->defaultServerIndex();
uiLogic()->selectedDockerContainer = m_settings.defaultContainer(uiLogic()->selectedServerIndex); uiLogic()->selectedDockerContainer = m_settings->defaultContainer(uiLogic()->selectedServerIndex);
qobject_cast<ProtocolsModel *>(uiLogic()->protocolsModel())->setSelectedServerIndex(uiLogic()->selectedServerIndex); qobject_cast<ProtocolsModel *>(uiLogic()->protocolsModel())->setSelectedServerIndex(uiLogic()->selectedServerIndex);
qobject_cast<ProtocolsModel *>(uiLogic()->protocolsModel())->setSelectedDockerContainer(uiLogic()->selectedDockerContainer); qobject_cast<ProtocolsModel *>(uiLogic()->protocolsModel())->setSelectedDockerContainer(uiLogic()->selectedDockerContainer);
uiLogic()->shareConnectionLogic()->updateSharingPage(uiLogic()->selectedServerIndex, uiLogic()->selectedDockerContainer); uiLogic()->pageLogic<ShareConnectionLogic>()->updateSharingPage(uiLogic()->selectedServerIndex, uiLogic()->selectedDockerContainer);
emit uiLogic()->goToPage(Page::ShareConnection); emit uiLogic()->goToPage(Page::ShareConnection);
} }

View file

@ -1,6 +1,7 @@
#include "NetworkSettingsLogic.h" #include "NetworkSettingsLogic.h"
#include "defines.h" #include "defines.h"
#include "settings.h"
#include "utils.h" #include "utils.h"
NetworkSettingsLogic::NetworkSettingsLogic(UiLogic *logic, QObject *parent): NetworkSettingsLogic::NetworkSettingsLogic(UiLogic *logic, QObject *parent):
@ -13,39 +14,39 @@ NetworkSettingsLogic::NetworkSettingsLogic(UiLogic *logic, QObject *parent):
void NetworkSettingsLogic::onUpdatePage() void NetworkSettingsLogic::onUpdatePage()
{ {
set_checkBoxUseAmneziaDnsChecked(m_settings.useAmneziaDns()); set_checkBoxUseAmneziaDnsChecked(m_settings->useAmneziaDns());
set_lineEditDns1Text(m_settings.primaryDns()); set_lineEditDns1Text(m_settings->primaryDns());
set_lineEditDns2Text(m_settings.secondaryDns()); set_lineEditDns2Text(m_settings->secondaryDns());
} }
void NetworkSettingsLogic::onLineEditDns1EditFinished(const QString &text) void NetworkSettingsLogic::onLineEditDns1EditFinished(const QString &text)
{ {
if (ipAddressRegex().exactMatch(text)) { if (ipAddressRegex().exactMatch(text)) {
m_settings.setPrimaryDns(text); m_settings->setPrimaryDns(text);
} }
} }
void NetworkSettingsLogic::onLineEditDns2EditFinished(const QString &text) void NetworkSettingsLogic::onLineEditDns2EditFinished(const QString &text)
{ {
if (ipAddressRegex().exactMatch(text)) { if (ipAddressRegex().exactMatch(text)) {
m_settings.setSecondaryDns(text); m_settings->setSecondaryDns(text);
} }
} }
void NetworkSettingsLogic::onPushButtonResetDns1Clicked() void NetworkSettingsLogic::onPushButtonResetDns1Clicked()
{ {
m_settings.setPrimaryDns(m_settings.cloudFlareNs1); m_settings->setPrimaryDns(m_settings->cloudFlareNs1);
onUpdatePage(); onUpdatePage();
} }
void NetworkSettingsLogic::onPushButtonResetDns2Clicked() void NetworkSettingsLogic::onPushButtonResetDns2Clicked()
{ {
m_settings.setSecondaryDns(m_settings.cloudFlareNs2); m_settings->setSecondaryDns(m_settings->cloudFlareNs2);
onUpdatePage(); onUpdatePage();
} }
void NetworkSettingsLogic::onCheckBoxUseAmneziaDnsToggled(bool checked) void NetworkSettingsLogic::onCheckBoxUseAmneziaDnsToggled(bool checked)
{ {
m_settings.setUseAmneziaDns(checked); m_settings->setUseAmneziaDns(checked);
} }

View file

@ -2,6 +2,7 @@
#define NEW_SERVER_PROTOCOLS_LOGIC_H #define NEW_SERVER_PROTOCOLS_LOGIC_H
#include "PageLogicBase.h" #include "PageLogicBase.h"
#include "containers/containers_defs.h"
class UiLogic; class UiLogic;

View file

@ -1,11 +1,17 @@
#include "PageLogicBase.h" #include "PageLogicBase.h"
#include "ui/uilogic.h"
#include "settings.h"
#include "configurators/vpn_configurator.h"
PageLogicBase::PageLogicBase(UiLogic *logic, QObject *parent): PageLogicBase::PageLogicBase(UiLogic *logic, QObject *parent):
QObject(parent), QObject(parent),
m_pageEnabled{true}, m_pageEnabled{true},
m_uiLogic(logic) m_uiLogic(logic)
{ {
m_settings = logic->m_settings;
m_configurator = logic->m_configurator;
m_serverController = logic->m_serverController;
} }

View file

@ -1,14 +1,15 @@
#ifndef PAGE_LOGIC_BASE_H #ifndef PAGE_LOGIC_BASE_H
#define PAGE_LOGIC_BASE_H #define PAGE_LOGIC_BASE_H
#include "settings.h"
#include "../pages.h" #include "../pages.h"
#include "../property_helper.h" #include "../property_helper.h"
using namespace amnezia;
using namespace PageEnumNS; using namespace PageEnumNS;
class UiLogic; class UiLogic;
class Settings;
class VpnConfigurator;
class ServerController;
class PageLogicBase : public QObject class PageLogicBase : public QObject
{ {
@ -22,10 +23,12 @@ public:
Q_INVOKABLE virtual void onUpdatePage() {} Q_INVOKABLE virtual void onUpdatePage() {}
protected: protected:
UiLogic *m_uiLogic;
UiLogic *uiLogic() const { return m_uiLogic; } UiLogic *uiLogic() const { return m_uiLogic; }
Settings m_settings; std::shared_ptr<Settings> m_settings;
UiLogic *m_uiLogic; std::shared_ptr<VpnConfigurator> m_configurator;
std::shared_ptr<ServerController> m_serverController;
signals: signals:
void updatePage(); void updatePage();

View file

@ -54,7 +54,7 @@ void QrDecoderLogic::onDetectedQrCode(const QString &code)
data.append(m_chunks.value(i)); data.append(m_chunks.value(i));
} }
bool ok = uiLogic()->startPageLogic()->importConnectionFromQr(data); bool ok = uiLogic()->pageLogic<StartPageLogic>()->importConnectionFromQr(data);
if (ok) { if (ok) {
set_detectingEnabled(false); set_detectingEnabled(false);
emit stopDecode(); emit stopDecode();
@ -67,7 +67,7 @@ void QrDecoderLogic::onDetectedQrCode(const QString &code)
} }
} }
else { else {
bool ok = uiLogic()->startPageLogic()->importConnectionFromQr(ba); bool ok = uiLogic()->pageLogic<StartPageLogic>()->importConnectionFromQr(ba);
if (ok) { if (ok) {
set_detectingEnabled(false); set_detectingEnabled(false);
emit stopDecode(); emit stopDecode();

View file

@ -3,6 +3,9 @@
#include <functional> #include <functional>
#include "PageLogicBase.h" #include "PageLogicBase.h"
#include "core/defs.h"
using namespace amnezia;
class UiLogic; class UiLogic;

View file

@ -36,64 +36,64 @@ void ServerContainersLogic::onPushButtonProtoSettingsClicked(DockerContainer c,
{ {
qDebug()<< "ServerContainersLogic::onPushButtonProtoSettingsClicked" << c << p; qDebug()<< "ServerContainersLogic::onPushButtonProtoSettingsClicked" << c << p;
uiLogic()->selectedDockerContainer = c; uiLogic()->selectedDockerContainer = c;
uiLogic()->protocolLogic(p)->updateProtocolPage(m_settings.protocolConfig(uiLogic()->selectedServerIndex, uiLogic()->selectedDockerContainer, p), uiLogic()->protocolLogic(p)->updateProtocolPage(m_settings->protocolConfig(uiLogic()->selectedServerIndex, uiLogic()->selectedDockerContainer, p),
uiLogic()->selectedDockerContainer, uiLogic()->selectedDockerContainer,
m_settings.haveAuthData(uiLogic()->selectedServerIndex)); m_settings->haveAuthData(uiLogic()->selectedServerIndex));
emit uiLogic()->goToProtocolPage(p); emit uiLogic()->goToProtocolPage(p);
} }
void ServerContainersLogic::onPushButtonDefaultClicked(DockerContainer c) void ServerContainersLogic::onPushButtonDefaultClicked(DockerContainer c)
{ {
if (m_settings.defaultContainer(uiLogic()->selectedServerIndex) == c) return; if (m_settings->defaultContainer(uiLogic()->selectedServerIndex) == c) return;
m_settings.setDefaultContainer(uiLogic()->selectedServerIndex, c); m_settings->setDefaultContainer(uiLogic()->selectedServerIndex, c);
uiLogic()->onUpdateAllPages(); uiLogic()->onUpdateAllPages();
if (uiLogic()->selectedServerIndex != m_settings.defaultServerIndex()) return; if (uiLogic()->selectedServerIndex != m_settings->defaultServerIndex()) return;
if (!uiLogic()->m_vpnConnection) return; if (!uiLogic()->m_vpnConnection) return;
if (!uiLogic()->m_vpnConnection->isConnected()) return; if (!uiLogic()->m_vpnConnection->isConnected()) return;
uiLogic()->vpnLogic()->onDisconnect(); uiLogic()->pageLogic<VpnLogic>()->onDisconnect();
uiLogic()->vpnLogic()->onConnect(); uiLogic()->pageLogic<VpnLogic>()->onConnect();
} }
void ServerContainersLogic::onPushButtonShareClicked(DockerContainer c) void ServerContainersLogic::onPushButtonShareClicked(DockerContainer c)
{ {
uiLogic()->shareConnectionLogic()->updateSharingPage(uiLogic()->selectedServerIndex, c); uiLogic()->pageLogic<ShareConnectionLogic>()->updateSharingPage(uiLogic()->selectedServerIndex, c);
emit uiLogic()->goToPage(Page::ShareConnection); emit uiLogic()->goToPage(Page::ShareConnection);
} }
void ServerContainersLogic::onPushButtonRemoveClicked(DockerContainer container) void ServerContainersLogic::onPushButtonRemoveClicked(DockerContainer container)
{ {
//buttonSetEnabledFunc(false); //buttonSetEnabledFunc(false);
ErrorCode e = ServerController::removeContainer(m_settings.serverCredentials(uiLogic()->selectedServerIndex), container); ErrorCode e = m_serverController->removeContainer(m_settings->serverCredentials(uiLogic()->selectedServerIndex), container);
m_settings.removeContainerConfig(uiLogic()->selectedServerIndex, container); m_settings->removeContainerConfig(uiLogic()->selectedServerIndex, container);
//buttonSetEnabledFunc(true); //buttonSetEnabledFunc(true);
if (m_settings.defaultContainer(uiLogic()->selectedServerIndex) == container) { if (m_settings->defaultContainer(uiLogic()->selectedServerIndex) == container) {
const auto &c = m_settings.containers(uiLogic()->selectedServerIndex); const auto &c = m_settings->containers(uiLogic()->selectedServerIndex);
if (c.isEmpty()) m_settings.setDefaultContainer(uiLogic()->selectedServerIndex, DockerContainer::None); if (c.isEmpty()) m_settings->setDefaultContainer(uiLogic()->selectedServerIndex, DockerContainer::None);
else m_settings.setDefaultContainer(uiLogic()->selectedServerIndex, c.keys().first()); else m_settings->setDefaultContainer(uiLogic()->selectedServerIndex, c.keys().first());
} }
uiLogic()->onUpdateAllPages(); uiLogic()->onUpdateAllPages();
} }
void ServerContainersLogic::onPushButtonContinueClicked(DockerContainer c, int port, TransportProto tp) void ServerContainersLogic::onPushButtonContinueClicked(DockerContainer c, int port, TransportProto tp)
{ {
QJsonObject config = ServerController::createContainerInitialConfig(c, port, tp); QJsonObject config = m_serverController->createContainerInitialConfig(c, port, tp);
emit uiLogic()->goToPage(Page::ServerConfiguringProgress); emit uiLogic()->goToPage(Page::ServerConfiguringProgress);
qApp->processEvents(); qApp->processEvents();
ErrorCode e = uiLogic()->serverConfiguringProgressLogic()->doInstallAction([this, c, &config](){ ErrorCode e = uiLogic()->pageLogic<ServerConfiguringProgressLogic>()->doInstallAction([this, c, &config](){
return ServerController::setupContainer(m_settings.serverCredentials(uiLogic()->selectedServerIndex), c, config); return m_serverController->setupContainer(m_settings->serverCredentials(uiLogic()->selectedServerIndex), c, config);
}); });
if (!e) { if (!e) {
m_settings.setContainerConfig(uiLogic()->selectedServerIndex, c, config); m_settings->setContainerConfig(uiLogic()->selectedServerIndex, c, config);
if (ContainerProps::containerService(c) == ServiceType::Vpn) { if (ContainerProps::containerService(c) == ServiceType::Vpn) {
m_settings.setDefaultContainer(uiLogic()->selectedServerIndex, c); m_settings->setDefaultContainer(uiLogic()->selectedServerIndex, c);
} }
} }

View file

@ -2,6 +2,7 @@
#define SERVER_CONTAINERS_LOGIC_H #define SERVER_CONTAINERS_LOGIC_H
#include "PageLogicBase.h" #include "PageLogicBase.h"
#include "containers/containers_defs.h"
class UiLogic; class UiLogic;

View file

@ -13,7 +13,7 @@ ServerListLogic::ServerListLogic(UiLogic *logic, QObject *parent):
void ServerListLogic::onServerListPushbuttonDefaultClicked(int index) void ServerListLogic::onServerListPushbuttonDefaultClicked(int index)
{ {
m_settings.setDefaultServer(index); m_settings->setDefaultServer(index);
uiLogic()->onUpdateAllPages(); uiLogic()->onUpdateAllPages();
} }
@ -25,8 +25,8 @@ void ServerListLogic::onServerListPushbuttonSettingsClicked(int index)
void ServerListLogic::onUpdatePage() void ServerListLogic::onUpdatePage()
{ {
const QJsonArray &servers = m_settings.serversArray(); const QJsonArray &servers = m_settings->serversArray();
int defaultServer = m_settings.defaultServerIndex(); int defaultServer = m_settings->defaultServerIndex();
std::vector<ServerModelContent> serverListContent; std::vector<ServerModelContent> serverListContent;
for(int i = 0; i < servers.size(); i++) { for(int i = 0; i < servers.size(); i++) {
ServerModelContent c; ServerModelContent c;

View file

@ -26,10 +26,10 @@ void ServerSettingsLogic::onUpdatePage()
{ {
set_labelWaitInfoVisible(false); set_labelWaitInfoVisible(false);
set_labelWaitInfoText(""); set_labelWaitInfoText("");
set_pushButtonClearVisible(m_settings.haveAuthData(uiLogic()->selectedServerIndex)); set_pushButtonClearVisible(m_settings->haveAuthData(uiLogic()->selectedServerIndex));
set_pushButtonClearClientCacheVisible(m_settings.haveAuthData(uiLogic()->selectedServerIndex)); set_pushButtonClearClientCacheVisible(m_settings->haveAuthData(uiLogic()->selectedServerIndex));
set_pushButtonShareFullVisible(m_settings.haveAuthData(uiLogic()->selectedServerIndex)); set_pushButtonShareFullVisible(m_settings->haveAuthData(uiLogic()->selectedServerIndex));
const QJsonObject &server = m_settings.server(uiLogic()->selectedServerIndex); const QJsonObject &server = m_settings->server(uiLogic()->selectedServerIndex);
const QString &port = server.value(config_key::port).toString(); const QString &port = server.value(config_key::port).toString();
set_labelServerText(QString("%1@%2%3%4") set_labelServerText(QString("%1@%2%3%4")
.arg(server.value(config_key::userName).toString()) .arg(server.value(config_key::userName).toString())
@ -38,7 +38,7 @@ void ServerSettingsLogic::onUpdatePage()
.arg(port)); .arg(port));
set_lineEditDescriptionText(server.value(config_key::description).toString()); set_lineEditDescriptionText(server.value(config_key::description).toString());
DockerContainer selectedContainer = m_settings.defaultContainer(uiLogic()->selectedServerIndex); DockerContainer selectedContainer = m_settings->defaultContainer(uiLogic()->selectedServerIndex);
QString selectedContainerName = ContainerProps::containerHumanNames().value(selectedContainer); QString selectedContainerName = ContainerProps::containerHumanNames().value(selectedContainer);
set_labelCurrentVpnProtocolText(tr("Service: ") + selectedContainerName); set_labelCurrentVpnProtocolText(tr("Service: ") + selectedContainerName);
} }
@ -48,14 +48,14 @@ void ServerSettingsLogic::onPushButtonClearServer()
set_pageEnabled(false); set_pageEnabled(false);
set_pushButtonClearText(tr("Uninstalling Amnezia software...")); set_pushButtonClearText(tr("Uninstalling Amnezia software..."));
if (m_settings.defaultServerIndex() == uiLogic()->selectedServerIndex) { if (m_settings->defaultServerIndex() == uiLogic()->selectedServerIndex) {
uiLogic()->vpnLogic()->onDisconnect(); uiLogic()->pageLogic<VpnLogic>()->onDisconnect();
} }
ErrorCode e = ServerController::removeAllContainers(m_settings.serverCredentials(uiLogic()->selectedServerIndex)); ErrorCode e = m_serverController->removeAllContainers(m_settings->serverCredentials(uiLogic()->selectedServerIndex));
ServerController::disconnectFromHost(m_settings.serverCredentials(uiLogic()->selectedServerIndex)); m_serverController->disconnectFromHost(m_settings->serverCredentials(uiLogic()->selectedServerIndex));
if (e) { if (e) {
uiLogic()->setDialogConnectErrorText( uiLogic()->set_dialogConnectErrorText(
tr("Error occurred while configuring server.") + "\n" + tr("Error occurred while configuring server.") + "\n" +
errorString(e) + "\n" + errorString(e) + "\n" +
tr("See logs for details.")); tr("See logs for details."));
@ -66,8 +66,8 @@ void ServerSettingsLogic::onPushButtonClearServer()
set_labelWaitInfoText(tr("Amnezia server successfully uninstalled")); set_labelWaitInfoText(tr("Amnezia server successfully uninstalled"));
} }
m_settings.setContainers(uiLogic()->selectedServerIndex, {}); m_settings->setContainers(uiLogic()->selectedServerIndex, {});
m_settings.setDefaultContainer(uiLogic()->selectedServerIndex, DockerContainer::None); m_settings->setDefaultContainer(uiLogic()->selectedServerIndex, DockerContainer::None);
set_pageEnabled(true); set_pageEnabled(true);
set_pushButtonClearText(tr("Clear server from Amnezia software")); set_pushButtonClearText(tr("Clear server from Amnezia software"));
@ -75,27 +75,27 @@ void ServerSettingsLogic::onPushButtonClearServer()
void ServerSettingsLogic::onPushButtonForgetServer() void ServerSettingsLogic::onPushButtonForgetServer()
{ {
if (m_settings.defaultServerIndex() == uiLogic()->selectedServerIndex && uiLogic()->m_vpnConnection->isConnected()) { if (m_settings->defaultServerIndex() == uiLogic()->selectedServerIndex && uiLogic()->m_vpnConnection->isConnected()) {
uiLogic()->vpnLogic()->onDisconnect(); uiLogic()->pageLogic<VpnLogic>()->onDisconnect();
} }
m_settings.removeServer(uiLogic()->selectedServerIndex); m_settings->removeServer(uiLogic()->selectedServerIndex);
if (m_settings.defaultServerIndex() == uiLogic()->selectedServerIndex) { if (m_settings->defaultServerIndex() == uiLogic()->selectedServerIndex) {
m_settings.setDefaultServer(0); m_settings->setDefaultServer(0);
} }
else if (m_settings.defaultServerIndex() > uiLogic()->selectedServerIndex) { else if (m_settings->defaultServerIndex() > uiLogic()->selectedServerIndex) {
m_settings.setDefaultServer(m_settings.defaultServerIndex() - 1); m_settings->setDefaultServer(m_settings->defaultServerIndex() - 1);
} }
if (m_settings.serversCount() == 0) { if (m_settings->serversCount() == 0) {
m_settings.setDefaultServer(-1); m_settings->setDefaultServer(-1);
} }
uiLogic()->selectedServerIndex = -1; uiLogic()->selectedServerIndex = -1;
uiLogic()->onUpdateAllPages(); uiLogic()->onUpdateAllPages();
if (m_settings.serversCount() == 0) { if (m_settings->serversCount() == 0) {
uiLogic()->setStartPage(Page::Start); uiLogic()->setStartPage(Page::Start);
} }
else { else {
@ -107,9 +107,9 @@ void ServerSettingsLogic::onPushButtonClearClientCacheClicked()
{ {
set_pushButtonClearClientCacheText(tr("Cache cleared")); set_pushButtonClearClientCacheText(tr("Cache cleared"));
const auto &containers = m_settings.containers(uiLogic()->selectedServerIndex); const auto &containers = m_settings->containers(uiLogic()->selectedServerIndex);
for (DockerContainer container: containers.keys()) { for (DockerContainer container: containers.keys()) {
m_settings.clearLastConnectionConfig(uiLogic()->selectedServerIndex, container); m_settings->clearLastConnectionConfig(uiLogic()->selectedServerIndex, container);
} }
QTimer::singleShot(3000, this, [this]() { QTimer::singleShot(3000, this, [this]() {
@ -120,14 +120,14 @@ void ServerSettingsLogic::onPushButtonClearClientCacheClicked()
void ServerSettingsLogic::onLineEditDescriptionEditingFinished() void ServerSettingsLogic::onLineEditDescriptionEditingFinished()
{ {
const QString &newText = lineEditDescriptionText(); const QString &newText = lineEditDescriptionText();
QJsonObject server = m_settings.server(uiLogic()->selectedServerIndex); QJsonObject server = m_settings->server(uiLogic()->selectedServerIndex);
server.insert(config_key::description, newText); server.insert(config_key::description, newText);
m_settings.editServer(uiLogic()->selectedServerIndex, server); m_settings->editServer(uiLogic()->selectedServerIndex, server);
uiLogic()->onUpdateAllPages(); uiLogic()->onUpdateAllPages();
} }
void ServerSettingsLogic::onPushButtonShareFullClicked() void ServerSettingsLogic::onPushButtonShareFullClicked()
{ {
uiLogic()->shareConnectionLogic()->updateSharingPage(uiLogic()->selectedServerIndex, DockerContainer::None); uiLogic()->pageLogic<ShareConnectionLogic>()->updateSharingPage(uiLogic()->selectedServerIndex, DockerContainer::None);
emit uiLogic()->goToShareProtocolPage(Proto::Any); emit uiLogic()->goToShareProtocolPage(Proto::Any);
} }

View file

@ -21,6 +21,7 @@
#include "defines.h" #include "defines.h"
#include "core/defs.h" #include "core/defs.h"
#include "core/errorstrings.h" #include "core/errorstrings.h"
#include "core/servercontroller.h"
#include <functional> #include <functional>
#include "../uilogic.h" #include "../uilogic.h"
@ -73,19 +74,19 @@ void ShareConnectionLogic::onPushButtonShareAmneziaGenerateClicked()
// Full access // Full access
if (shareFullAccess()) { if (shareFullAccess()) {
serverConfig = m_settings.server(serverIndex); serverConfig = m_settings->server(serverIndex);
} }
// Container share // Container share
else { else {
ServerCredentials credentials = m_settings.serverCredentials(serverIndex); ServerCredentials credentials = m_settings->serverCredentials(serverIndex);
QJsonObject containerConfig = m_settings.containerConfig(serverIndex, container); QJsonObject containerConfig = m_settings->containerConfig(serverIndex, container);
containerConfig.insert(config_key::container, ContainerProps::containerToString(container)); containerConfig.insert(config_key::container, ContainerProps::containerToString(container));
ErrorCode e = ErrorCode::NoError; ErrorCode e = ErrorCode::NoError;
for (Proto p: ContainerProps::protocolsForContainer(container)) { for (Proto p: ContainerProps::protocolsForContainer(container)) {
QJsonObject protoConfig = m_settings.protocolConfig(serverIndex, container, p); QJsonObject protoConfig = m_settings->protocolConfig(serverIndex, container, p);
QString cfg = VpnConfigurator::genVpnProtocolConfig(credentials, container, containerConfig, p, &e); QString cfg = m_configurator->genVpnProtocolConfig(credentials, container, containerConfig, p, &e);
if (e) { if (e) {
cfg = "Error generating config"; cfg = "Error generating config";
break; break;
@ -96,14 +97,14 @@ void ShareConnectionLogic::onPushButtonShareAmneziaGenerateClicked()
QByteArray ba; QByteArray ba;
if (!e) { if (!e) {
serverConfig = m_settings.server(serverIndex); serverConfig = m_settings->server(serverIndex);
serverConfig.remove(config_key::userName); serverConfig.remove(config_key::userName);
serverConfig.remove(config_key::password); serverConfig.remove(config_key::password);
serverConfig.remove(config_key::port); serverConfig.remove(config_key::port);
serverConfig.insert(config_key::containers, QJsonArray {containerConfig}); serverConfig.insert(config_key::containers, QJsonArray {containerConfig});
serverConfig.insert(config_key::defaultContainer, ContainerProps::containerToString(container)); serverConfig.insert(config_key::defaultContainer, ContainerProps::containerToString(container));
auto dns = VpnConfigurator::getDnsForConfig(serverIndex); auto dns = m_configurator->getDnsForConfig(serverIndex);
serverConfig.insert(config_key::dns1, dns.first); serverConfig.insert(config_key::dns1, dns.first);
serverConfig.insert(config_key::dns2, dns.second); serverConfig.insert(config_key::dns2, dns.second);
@ -129,13 +130,13 @@ void ShareConnectionLogic::onPushButtonShareOpenVpnGenerateClicked()
{ {
int serverIndex = uiLogic()->selectedServerIndex; int serverIndex = uiLogic()->selectedServerIndex;
DockerContainer container = uiLogic()->selectedDockerContainer; DockerContainer container = uiLogic()->selectedDockerContainer;
ServerCredentials credentials = m_settings.serverCredentials(serverIndex); ServerCredentials credentials = m_settings->serverCredentials(serverIndex);
const QJsonObject &containerConfig = m_settings.containerConfig(serverIndex, container); const QJsonObject &containerConfig = m_settings->containerConfig(serverIndex, container);
ErrorCode e = ErrorCode::NoError; ErrorCode e = ErrorCode::NoError;
QString cfg = OpenVpnConfigurator::genOpenVpnConfig(credentials, container, containerConfig, &e); QString cfg = m_configurator->openVpnConfigurator->genOpenVpnConfig(credentials, container, containerConfig, &e);
cfg = VpnConfigurator::processConfigWithExportSettings(serverIndex, container, Proto::OpenVpn, cfg); cfg = m_configurator->processConfigWithExportSettings(serverIndex, container, Proto::OpenVpn, cfg);
set_textEditShareOpenVpnCodeText(QJsonDocument::fromJson(cfg.toUtf8()).object()[config_key::config].toString()); set_textEditShareOpenVpnCodeText(QJsonDocument::fromJson(cfg.toUtf8()).object()[config_key::config].toString());
} }
@ -144,16 +145,16 @@ void ShareConnectionLogic::onPushButtonShareShadowSocksGenerateClicked()
{ {
int serverIndex = uiLogic()->selectedServerIndex; int serverIndex = uiLogic()->selectedServerIndex;
DockerContainer container = uiLogic()->selectedDockerContainer; DockerContainer container = uiLogic()->selectedDockerContainer;
ServerCredentials credentials = m_settings.serverCredentials(serverIndex); ServerCredentials credentials = m_settings->serverCredentials(serverIndex);
QJsonObject protoConfig = m_settings.protocolConfig(serverIndex, container, Proto::ShadowSocks); QJsonObject protoConfig = m_settings->protocolConfig(serverIndex, container, Proto::ShadowSocks);
QString cfg = protoConfig.value(config_key::last_config).toString(); QString cfg = protoConfig.value(config_key::last_config).toString();
if (cfg.isEmpty()) { if (cfg.isEmpty()) {
const QJsonObject &containerConfig = m_settings.containerConfig(serverIndex, container); const QJsonObject &containerConfig = m_settings->containerConfig(serverIndex, container);
ErrorCode e = ErrorCode::NoError; ErrorCode e = ErrorCode::NoError;
cfg = ShadowSocksConfigurator::genShadowSocksConfig(credentials, container, containerConfig, &e); cfg = m_configurator->shadowSocksConfigurator->genShadowSocksConfig(credentials, container, containerConfig, &e);
} }
QJsonObject ssConfig = QJsonDocument::fromJson(cfg.toUtf8()).object(); QJsonObject ssConfig = QJsonDocument::fromJson(cfg.toUtf8()).object();
@ -186,16 +187,16 @@ void ShareConnectionLogic::onPushButtonShareCloakGenerateClicked()
{ {
int serverIndex = uiLogic()->selectedServerIndex; int serverIndex = uiLogic()->selectedServerIndex;
DockerContainer container = uiLogic()->selectedDockerContainer; DockerContainer container = uiLogic()->selectedDockerContainer;
ServerCredentials credentials = m_settings.serverCredentials(serverIndex); ServerCredentials credentials = m_settings->serverCredentials(serverIndex);
QJsonObject protoConfig = m_settings.protocolConfig(serverIndex, container, Proto::Cloak); QJsonObject protoConfig = m_settings->protocolConfig(serverIndex, container, Proto::Cloak);
QString cfg = protoConfig.value(config_key::last_config).toString(); QString cfg = protoConfig.value(config_key::last_config).toString();
if (cfg.isEmpty()) { if (cfg.isEmpty()) {
const QJsonObject &containerConfig = m_settings.containerConfig(serverIndex, container); const QJsonObject &containerConfig = m_settings->containerConfig(serverIndex, container);
ErrorCode e = ErrorCode::NoError; ErrorCode e = ErrorCode::NoError;
cfg = CloakConfigurator::genCloakConfig(credentials, container, containerConfig, &e); cfg = m_configurator->cloakConfigurator->genCloakConfig(credentials, container, containerConfig, &e);
} }
QJsonObject cloakConfig = QJsonDocument::fromJson(cfg.toUtf8()).object(); QJsonObject cloakConfig = QJsonDocument::fromJson(cfg.toUtf8()).object();
@ -209,19 +210,19 @@ void ShareConnectionLogic::onPushButtonShareWireGuardGenerateClicked()
{ {
int serverIndex = uiLogic()->selectedServerIndex; int serverIndex = uiLogic()->selectedServerIndex;
DockerContainer container = uiLogic()->selectedDockerContainer; DockerContainer container = uiLogic()->selectedDockerContainer;
ServerCredentials credentials = m_settings.serverCredentials(serverIndex); ServerCredentials credentials = m_settings->serverCredentials(serverIndex);
const QJsonObject &containerConfig = m_settings.containerConfig(serverIndex, container); const QJsonObject &containerConfig = m_settings->containerConfig(serverIndex, container);
ErrorCode e = ErrorCode::NoError; ErrorCode e = ErrorCode::NoError;
QString cfg = WireguardConfigurator::genWireguardConfig(credentials, container, containerConfig, &e); QString cfg = m_configurator->wireguardConfigurator->genWireguardConfig(credentials, container, containerConfig, &e);
if (e) { if (e) {
QMessageBox::warning(nullptr, APPLICATION_NAME, QMessageBox::warning(nullptr, APPLICATION_NAME,
tr("Error occurred while configuring server.") + "\n" + tr("Error occurred while configuring server.") + "\n" +
errorString(e)); errorString(e));
return; return;
} }
cfg = VpnConfigurator::processConfigWithExportSettings(serverIndex, container, Proto::WireGuard, cfg); cfg = m_configurator->processConfigWithExportSettings(serverIndex, container, Proto::WireGuard, cfg);
cfg = QJsonDocument::fromJson(cfg.toUtf8()).object()[config_key::config].toString(); cfg = QJsonDocument::fromJson(cfg.toUtf8()).object()[config_key::config].toString();
set_textEditShareWireGuardCodeText(cfg); set_textEditShareWireGuardCodeText(cfg);
@ -235,22 +236,20 @@ void ShareConnectionLogic::onPushButtonShareIkev2GenerateClicked()
{ {
int serverIndex = uiLogic()->selectedServerIndex; int serverIndex = uiLogic()->selectedServerIndex;
DockerContainer container = uiLogic()->selectedDockerContainer; DockerContainer container = uiLogic()->selectedDockerContainer;
ServerCredentials credentials = m_settings.serverCredentials(serverIndex); ServerCredentials credentials = m_settings->serverCredentials(serverIndex);
//const QJsonObject &containerConfig = m_settings.containerConfig(serverIndex, container); Ikev2Configurator::ConnectionData connData = m_configurator->ikev2Configurator->prepareIkev2Config(credentials, container);
Ikev2Configurator::ConnectionData connData = Ikev2Configurator::prepareIkev2Config(credentials, container); QString cfg = m_configurator->ikev2Configurator->genIkev2Config(connData);
cfg = m_configurator->processConfigWithExportSettings(serverIndex, container, Proto::Ikev2, cfg);
QString cfg = Ikev2Configurator::genIkev2Config(connData);
cfg = VpnConfigurator::processConfigWithExportSettings(serverIndex, container, Proto::Ikev2, cfg);
cfg = QJsonDocument::fromJson(cfg.toUtf8()).object()[config_key::cert].toString(); cfg = QJsonDocument::fromJson(cfg.toUtf8()).object()[config_key::cert].toString();
set_textEditShareIkev2CertText(cfg); set_textEditShareIkev2CertText(cfg);
QString mobileCfg = Ikev2Configurator::genMobileConfig(connData); QString mobileCfg = m_configurator->ikev2Configurator->genMobileConfig(connData);
set_textEditShareIkev2MobileConfigText(mobileCfg); set_textEditShareIkev2MobileConfigText(mobileCfg);
QString strongSwanCfg = Ikev2Configurator::genStrongSwanConfig(connData); QString strongSwanCfg = m_configurator->ikev2Configurator->genStrongSwanConfig(connData);
set_textEditShareIkev2StrongSwanConfigText(strongSwanCfg); set_textEditShareIkev2StrongSwanConfigText(strongSwanCfg);
} }

View file

@ -2,6 +2,7 @@
#define SHARE_CONNECTION_LOGIC_H #define SHARE_CONNECTION_LOGIC_H
#include "PageLogicBase.h" #include "PageLogicBase.h"
#include "containers/containers_defs.h"
class UiLogic; class UiLogic;

View file

@ -18,13 +18,13 @@ SitesLogic::SitesLogic(UiLogic *logic, QObject *parent):
m_tableViewSitesModel{nullptr}, m_tableViewSitesModel{nullptr},
m_lineEditSitesAddCustomText{} m_lineEditSitesAddCustomText{}
{ {
sitesModels.insert(Settings::VpnOnlyForwardSites, new SitesModel(Settings::VpnOnlyForwardSites)); sitesModels.insert(Settings::VpnOnlyForwardSites, new SitesModel(m_settings, Settings::VpnOnlyForwardSites));
sitesModels.insert(Settings::VpnAllExceptSites, new SitesModel(Settings::VpnAllExceptSites)); sitesModels.insert(Settings::VpnAllExceptSites, new SitesModel(m_settings, Settings::VpnAllExceptSites));
} }
void SitesLogic::onUpdatePage() void SitesLogic::onUpdatePage()
{ {
Settings::RouteMode m = m_settings.routeMode(); Settings::RouteMode m = m_settings->routeMode();
if (m == Settings::VpnAllSites) return; if (m == Settings::VpnAllSites) return;
if (m == Settings::VpnOnlyForwardSites) { if (m == Settings::VpnOnlyForwardSites) {
@ -40,10 +40,10 @@ void SitesLogic::onUpdatePage()
void SitesLogic::onPushButtonAddCustomSitesClicked() void SitesLogic::onPushButtonAddCustomSitesClicked()
{ {
if (uiLogic()->vpnLogic()->radioButtonVpnModeAllSitesChecked()) { if (uiLogic()->pageLogic<VpnLogic>()->radioButtonVpnModeAllSitesChecked()) {
return; return;
} }
Settings::RouteMode mode = m_settings.routeMode(); Settings::RouteMode mode = m_settings->routeMode();
QString newSite = lineEditSitesAddCustomText(); QString newSite = lineEditSitesAddCustomText();
@ -60,7 +60,7 @@ void SitesLogic::onPushButtonAddCustomSitesClicked()
} }
const auto &cbProcess = [this, mode](const QString &newSite, const QString &ip) { const auto &cbProcess = [this, mode](const QString &newSite, const QString &ip) {
m_settings.addVpnSite(mode, newSite, ip); m_settings->addVpnSite(mode, newSite, ip);
if (!ip.isEmpty()) { if (!ip.isEmpty()) {
uiLogic()->m_vpnConnection->addRoutes(QStringList() << ip); uiLogic()->m_vpnConnection->addRoutes(QStringList() << ip);
@ -100,7 +100,7 @@ void SitesLogic::onPushButtonAddCustomSitesClicked()
void SitesLogic::onPushButtonSitesDeleteClicked(QStringList items) void SitesLogic::onPushButtonSitesDeleteClicked(QStringList items)
{ {
Settings::RouteMode mode = m_settings.routeMode(); Settings::RouteMode mode = m_settings->routeMode();
auto siteModel = qobject_cast<SitesModel*> (tableViewSitesModel()); auto siteModel = qobject_cast<SitesModel*> (tableViewSitesModel());
if (!siteModel || items.isEmpty()) { if (!siteModel || items.isEmpty()) {
@ -121,7 +121,7 @@ void SitesLogic::onPushButtonSitesDeleteClicked(QStringList items)
} }
} }
m_settings.removeVpnSites(mode, sites); m_settings->removeVpnSites(mode, sites);
if (uiLogic()->m_vpnConnection->connectionState() == VpnProtocol::Connected) { if (uiLogic()->m_vpnConnection->connectionState() == VpnProtocol::Connected) {
uiLogic()->m_vpnConnection->deleteRoutes(ips); uiLogic()->m_vpnConnection->deleteRoutes(ips);
@ -139,7 +139,7 @@ void SitesLogic::onPushButtonSitesImportClicked(const QString& fileName)
return; return;
} }
Settings::RouteMode mode = m_settings.routeMode(); Settings::RouteMode mode = m_settings->routeMode();
QStringList ips; QStringList ips;
QMap<QString, QString> sites; QMap<QString, QString> sites;
@ -187,8 +187,8 @@ void SitesLogic::onPushButtonSitesImportClicked(const QString& fileName)
} }
m_settings.addVpnIps(mode, ips); m_settings->addVpnIps(mode, ips);
m_settings.addVpnSites(mode, sites); m_settings->addVpnSites(mode, sites);
uiLogic()->m_vpnConnection->addRoutes(QStringList() << ips); uiLogic()->m_vpnConnection->addRoutes(QStringList() << ips);
uiLogic()->m_vpnConnection->flushDns(); uiLogic()->m_vpnConnection->flushDns();
@ -198,9 +198,9 @@ void SitesLogic::onPushButtonSitesImportClicked(const QString& fileName)
void SitesLogic::onPushButtonSitesExportClicked() void SitesLogic::onPushButtonSitesExportClicked()
{ {
Settings::RouteMode mode = m_settings.routeMode(); Settings::RouteMode mode = m_settings->routeMode();
QVariantMap sites = m_settings.vpnSites(mode); QVariantMap sites = m_settings->vpnSites(mode);
QString data; QString data;
for (auto s : sites.keys()) { for (auto s : sites.keys()) {

View file

@ -2,6 +2,7 @@
#define SITES_LOGIC_H #define SITES_LOGIC_H
#include "PageLogicBase.h" #include "PageLogicBase.h"
#include "settings.h"
class UiLogic; class UiLogic;
class SitesModel; class SitesModel;

View file

@ -1,6 +1,9 @@
#include "StartPageLogic.h" #include "StartPageLogic.h"
#include "ViewConfigLogic.h"
#include "core/errorstrings.h" #include "core/errorstrings.h"
#include "configurators/ssh_configurator.h" #include "configurators/ssh_configurator.h"
#include "configurators/vpn_configurator.h"
#include "../uilogic.h" #include "../uilogic.h"
#include "utils.h" #include "utils.h"
@ -16,15 +19,8 @@ StartPageLogic::StartPageLogic(UiLogic *logic, QObject *parent):
m_pushButtonConnectEnabled{true}, m_pushButtonConnectEnabled{true},
m_pushButtonConnectText{tr("Connect")}, m_pushButtonConnectText{tr("Connect")},
m_pushButtonConnectKeyChecked{false}, m_pushButtonConnectKeyChecked{false},
m_lineEditStartExistingCodeText{},
m_textEditSshKeyText{},
m_lineEditIpText{},
m_lineEditPasswordText{},
m_lineEditLoginText{},
m_labelWaitInfoVisible{true}, m_labelWaitInfoVisible{true},
m_labelWaitInfoText{},
m_pushButtonBackFromStartVisible{true}, m_pushButtonBackFromStartVisible{true},
m_pushButtonConnectVisible{true},
m_ipAddressPortRegex{Utils::ipAddressPortRegExp()} m_ipAddressPortRegex{Utils::ipAddressPortRegExp()}
{ {
@ -41,7 +37,6 @@ void StartPageLogic::onUpdatePage()
set_labelWaitInfoVisible(false); set_labelWaitInfoVisible(false);
set_labelWaitInfoText(""); set_labelWaitInfoText("");
set_pushButtonConnectVisible(true);
set_pushButtonConnectKeyChecked(false); set_pushButtonConnectKeyChecked(false);
@ -50,8 +45,6 @@ void StartPageLogic::onUpdatePage()
void StartPageLogic::onPushButtonConnect() void StartPageLogic::onPushButtonConnect()
{ {
// uiLogic()->goToPage(Page::NewServer);
// return;
if (pushButtonConnectKeyChecked()){ if (pushButtonConnectKeyChecked()){
if (lineEditIpText().isEmpty() || if (lineEditIpText().isEmpty() ||
lineEditLoginText().isEmpty() || lineEditLoginText().isEmpty() ||
@ -68,7 +61,6 @@ void StartPageLogic::onPushButtonConnect()
return; return;
} }
} }
qDebug() << "UiLogic::onPushButtonConnect checking new server";
ServerCredentials serverCredentials; ServerCredentials serverCredentials;
serverCredentials.hostName = lineEditIpText(); serverCredentials.hostName = lineEditIpText();
@ -85,7 +77,7 @@ void StartPageLogic::onPushButtonConnect()
} }
if (key.contains("OPENSSH") && key.contains("BEGIN") && key.contains("PRIVATE KEY")) { if (key.contains("OPENSSH") && key.contains("BEGIN") && key.contains("PRIVATE KEY")) {
key = SshConfigurator::convertOpenSShKey(key); key = m_configurator->sshConfigurator->convertOpenSShKey(key);
} }
serverCredentials.password = key; serverCredentials.password = key;
@ -99,7 +91,7 @@ void StartPageLogic::onPushButtonConnect()
ErrorCode e = ErrorCode::NoError; ErrorCode e = ErrorCode::NoError;
#ifdef Q_DEBUG #ifdef Q_DEBUG
//QString output = ServerController::checkSshConnection(serverCredentials, &e); //QString output = m_serverController->checkSshConnection(serverCredentials, &e);
#else #else
QString output; QString output;
#endif #endif
@ -153,19 +145,10 @@ bool StartPageLogic::importConnection(const QJsonObject &profile)
credentials.userName = profile.value(config_key::userName).toString(); credentials.userName = profile.value(config_key::userName).toString();
credentials.password = profile.value(config_key::password).toString(); credentials.password = profile.value(config_key::password).toString();
// qDebug() << QString("Added server %3@%1:%2").
// arg(credentials.hostName).
// arg(credentials.port).
// arg(credentials.userName);
//qDebug() << QString("Password") << credentials.password;
if (credentials.isValid() || profile.contains(config_key::containers)) { if (credentials.isValid() || profile.contains(config_key::containers)) {
m_settings.addServer(profile); // check config
m_settings.setDefaultServer(m_settings.serversCount() - 1); uiLogic()->pageLogic<ViewConfigLogic>()->set_configJson(profile);
emit uiLogic()->goToPage(Page::ViewConfig);
emit uiLogic()->goToPage(Page::Vpn);
emit uiLogic()->setStartPage(Page::Vpn);
} }
else { else {
qDebug() << "Failed to import profile"; qDebug() << "Failed to import profile";
@ -174,8 +157,8 @@ bool StartPageLogic::importConnection(const QJsonObject &profile)
} }
if (!profile.contains(config_key::containers)) { if (!profile.contains(config_key::containers)) {
uiLogic()->selectedServerIndex = m_settings.defaultServerIndex(); uiLogic()->selectedServerIndex = m_settings->defaultServerIndex();
uiLogic()->selectedDockerContainer = m_settings.defaultContainer(uiLogic()->selectedServerIndex); uiLogic()->selectedDockerContainer = m_settings->defaultContainer(uiLogic()->selectedServerIndex);
uiLogic()->onUpdateAllPages(); uiLogic()->onUpdateAllPages();
emit uiLogic()->goToPage(Page::ServerContainers); emit uiLogic()->goToPage(Page::ServerContainers);
@ -209,7 +192,6 @@ bool StartPageLogic::importConnectionFromCode(QString code)
bool StartPageLogic::importConnectionFromQr(const QByteArray &data) bool StartPageLogic::importConnectionFromQr(const QByteArray &data)
{ {
qDebug() << "StartPageLogic::importConnectionFromQr" << data;
QJsonObject dataObj = QJsonDocument::fromJson(data).object(); QJsonObject dataObj = QJsonDocument::fromJson(data).object();
if (!dataObj.isEmpty()) { if (!dataObj.isEmpty()) {
return importConnection(dataObj); return importConnection(dataObj);

View file

@ -20,7 +20,6 @@ class StartPageLogic : public PageLogicBase
AUTO_PROPERTY(bool, labelWaitInfoVisible) AUTO_PROPERTY(bool, labelWaitInfoVisible)
AUTO_PROPERTY(QString, labelWaitInfoText) AUTO_PROPERTY(QString, labelWaitInfoText)
AUTO_PROPERTY(bool, pushButtonBackFromStartVisible) AUTO_PROPERTY(bool, pushButtonBackFromStartVisible)
AUTO_PROPERTY(bool, pushButtonConnectVisible)
READONLY_PROPERTY(QRegExp, ipAddressPortRegex) READONLY_PROPERTY(QRegExp, ipAddressPortRegex)
public: public:

View file

@ -0,0 +1,67 @@
#include "ViewConfigLogic.h"
#include "core/errorstrings.h"
#include "../uilogic.h"
ViewConfigLogic::ViewConfigLogic(UiLogic *logic, QObject *parent):
PageLogicBase(logic, parent)
{
}
void ViewConfigLogic::onUpdatePage()
{
set_configText(QJsonDocument(configJson()).toJson());
m_openVpnLastConfigs = m_openVpnMalStrings =
"<style> \
div { line-height: 0.5; } \
</style><div>";
m_warningStringNumber = 3;
m_warningActive = false;
const QJsonArray &containers = configJson()[config_key::containers].toArray();
int i = 0;
for (const QJsonValue &v: containers) {
QString cfg_json = v.toObject()[ProtocolProps::protoToString(Proto::OpenVpn)]
.toObject()[config_key::last_config].toString();
QString openvpn_cfg = QJsonDocument::fromJson(cfg_json.toUtf8()).object()[config_key::config]
.toString();
openvpn_cfg.replace("\r", "");
QStringList lines = openvpn_cfg.split("\n");
for (const QString &l: lines) {
i++;
QRegularExpressionMatch match = m_re.match(l);
if (dangerousTags.contains(match.captured(0))) {
QString t = QString("<p><font color=\"red\">%1</font>").arg(l);
m_openVpnLastConfigs.append(t + "\n");
m_openVpnMalStrings.append(t);
if (m_warningStringNumber == 3) m_warningStringNumber = i - 3;
m_warningActive = true;
qDebug() << "ViewConfigLogic : malicious scripts warning:" << l;
}
else {
m_openVpnLastConfigs.append("<p>" + l + "&nbsp;\n");
}
}
}
emit openVpnLastConfigsChanged(m_openVpnLastConfigs);
emit openVpnMalStringsChanged(m_openVpnMalStrings);
emit warningStringNumberChanged(m_warningStringNumber);
emit warningActiveChanged(m_warningActive);
}
void ViewConfigLogic::importConfig()
{
m_settings->addServer(configJson());
m_settings->setDefaultServer(m_settings->serversCount() - 1);
emit uiLogic()->goToPage(Page::Vpn);
emit uiLogic()->setStartPage(Page::Vpn);
}

View file

@ -0,0 +1,47 @@
#ifndef VIEW_CONFIG_LOGIC_H
#define VIEW_CONFIG_LOGIC_H
#include "PageLogicBase.h"
#include <QJsonObject>
class UiLogic;
class ViewConfigLogic : public PageLogicBase
{
Q_OBJECT
AUTO_PROPERTY(QString, configText)
AUTO_PROPERTY(QString, openVpnLastConfigs)
AUTO_PROPERTY(QString, openVpnMalStrings)
AUTO_PROPERTY(QJsonObject, configJson)
AUTO_PROPERTY(int, warningStringNumber)
AUTO_PROPERTY(bool, warningActive)
public:
Q_INVOKABLE void onUpdatePage() override;
Q_INVOKABLE void importConfig();
public:
explicit ViewConfigLogic(UiLogic *uiLogic, QObject *parent = nullptr);
~ViewConfigLogic() = default;
private:
QRegularExpression m_re {"(\\w+-\\w+|\\w+)"};
// https://github.com/OpenVPN/openvpn/blob/master/doc/man-sections/script-options.rst
QStringList dangerousTags {
"up",
"tls-verify",
"ipchange",
"client-connect",
"route-up",
"route-pre-down",
"client-disconnect",
"down",
"learn-address",
"auth-user-pass-verify"
};
};
#endif // VIEW_CONFIG_LOGIC_H

View file

@ -33,7 +33,7 @@ VpnLogic::VpnLogic(UiLogic *logic, QObject *parent):
connect(this, &VpnLogic::connectToVpn, uiLogic()->m_vpnConnection, &VpnConnection::connectToVpn, Qt::QueuedConnection); connect(this, &VpnLogic::connectToVpn, uiLogic()->m_vpnConnection, &VpnConnection::connectToVpn, Qt::QueuedConnection);
connect(this, &VpnLogic::disconnectFromVpn, uiLogic()->m_vpnConnection, &VpnConnection::disconnectFromVpn, Qt::QueuedConnection); connect(this, &VpnLogic::disconnectFromVpn, uiLogic()->m_vpnConnection, &VpnConnection::disconnectFromVpn, Qt::QueuedConnection);
if (m_settings.isAutoConnect() && m_settings.defaultServerIndex() >= 0) { if (m_settings->isAutoConnect() && m_settings->defaultServerIndex() >= 0) {
QTimer::singleShot(1000, this, [this](){ QTimer::singleShot(1000, this, [this](){
set_pushButtonConnectEnabled(false); set_pushButtonConnectEnabled(false);
onConnect(); onConnect();
@ -47,20 +47,20 @@ VpnLogic::VpnLogic(UiLogic *logic, QObject *parent):
void VpnLogic::onUpdatePage() void VpnLogic::onUpdatePage()
{ {
Settings::RouteMode mode = m_settings.routeMode(); Settings::RouteMode mode = m_settings->routeMode();
DockerContainer selectedContainer = m_settings.defaultContainer(m_settings.defaultServerIndex()); DockerContainer selectedContainer = m_settings->defaultContainer(m_settings->defaultServerIndex());
set_isCustomRoutesSupported (selectedContainer == DockerContainer::OpenVpn || set_isCustomRoutesSupported (selectedContainer == DockerContainer::OpenVpn ||
selectedContainer == DockerContainer::ShadowSocks|| selectedContainer == DockerContainer::ShadowSocks||
selectedContainer == DockerContainer::Cloak); selectedContainer == DockerContainer::Cloak);
set_isContainerHaveAuthData(m_settings.haveAuthData(m_settings.defaultServerIndex())); set_isContainerHaveAuthData(m_settings->haveAuthData(m_settings->defaultServerIndex()));
set_radioButtonVpnModeAllSitesChecked(mode == Settings::VpnAllSites || !isCustomRoutesSupported()); set_radioButtonVpnModeAllSitesChecked(mode == Settings::VpnAllSites || !isCustomRoutesSupported());
set_radioButtonVpnModeForwardSitesChecked(mode == Settings::VpnOnlyForwardSites && isCustomRoutesSupported()); set_radioButtonVpnModeForwardSitesChecked(mode == Settings::VpnOnlyForwardSites && isCustomRoutesSupported());
set_radioButtonVpnModeExceptSitesChecked(mode == Settings::VpnAllExceptSites && isCustomRoutesSupported()); set_radioButtonVpnModeExceptSitesChecked(mode == Settings::VpnAllExceptSites && isCustomRoutesSupported());
const QJsonObject &server = uiLogic()->m_settings.defaultServer(); const QJsonObject &server = uiLogic()->m_settings->defaultServer();
QString serverString = QString("%2 (%3)") QString serverString = QString("%2 (%3)")
.arg(server.value(config_key::description).toString()) .arg(server.value(config_key::description).toString())
.arg(server.value(config_key::hostName).toString()); .arg(server.value(config_key::hostName).toString());
@ -69,7 +69,7 @@ void VpnLogic::onUpdatePage()
QString selectedContainerName = ContainerProps::containerHumanNames().value(selectedContainer); QString selectedContainerName = ContainerProps::containerHumanNames().value(selectedContainer);
set_labelCurrentService(selectedContainerName); set_labelCurrentService(selectedContainerName);
auto dns = VpnConfigurator::getDnsForConfig(m_settings.defaultServerIndex()); auto dns = m_configurator->getDnsForConfig(m_settings->defaultServerIndex());
set_amneziaDnsEnabled(dns.first == protocols::dns::amneziaDnsIp); set_amneziaDnsEnabled(dns.first == protocols::dns::amneziaDnsIp);
if (dns.first == protocols::dns::amneziaDnsIp) { if (dns.first == protocols::dns::amneziaDnsIp) {
set_labelCurrentDns("On your server"); set_labelCurrentDns("On your server");
@ -93,19 +93,19 @@ void VpnLogic::onUpdatePage()
void VpnLogic::onRadioButtonVpnModeAllSitesClicked() void VpnLogic::onRadioButtonVpnModeAllSitesClicked()
{ {
m_settings.setRouteMode(Settings::VpnAllSites); m_settings->setRouteMode(Settings::VpnAllSites);
onUpdatePage(); onUpdatePage();
} }
void VpnLogic::onRadioButtonVpnModeForwardSitesClicked() void VpnLogic::onRadioButtonVpnModeForwardSitesClicked()
{ {
m_settings.setRouteMode(Settings::VpnOnlyForwardSites); m_settings->setRouteMode(Settings::VpnOnlyForwardSites);
onUpdatePage(); onUpdatePage();
} }
void VpnLogic::onRadioButtonVpnModeExceptSitesClicked() void VpnLogic::onRadioButtonVpnModeExceptSitesClicked()
{ {
m_settings.setRouteMode(Settings::VpnAllExceptSites); m_settings->setRouteMode(Settings::VpnAllExceptSites);
onUpdatePage(); onUpdatePage();
} }
@ -203,11 +203,11 @@ void VpnLogic::onPushButtonConnectClicked()
void VpnLogic::onConnect() void VpnLogic::onConnect()
{ {
int serverIndex = m_settings.defaultServerIndex(); int serverIndex = m_settings->defaultServerIndex();
ServerCredentials credentials = m_settings.serverCredentials(serverIndex); ServerCredentials credentials = m_settings->serverCredentials(serverIndex);
DockerContainer container = m_settings.defaultContainer(serverIndex); DockerContainer container = m_settings->defaultContainer(serverIndex);
if (m_settings.containers(serverIndex).isEmpty()) { if (m_settings->containers(serverIndex).isEmpty()) {
set_labelErrorText(tr("VPN Protocols is not installed.\n Please install VPN container at first")); set_labelErrorText(tr("VPN Protocols is not installed.\n Please install VPN container at first"));
set_pushButtonConnectChecked(false); set_pushButtonConnectChecked(false);
return; return;
@ -220,7 +220,7 @@ void VpnLogic::onConnect()
} }
const QJsonObject &containerConfig = m_settings.containerConfig(serverIndex, container); const QJsonObject &containerConfig = m_settings->containerConfig(serverIndex, container);
onConnectWorker(serverIndex, credentials, container, containerConfig); onConnectWorker(serverIndex, credentials, container, containerConfig);
} }
@ -233,14 +233,6 @@ void VpnLogic::onConnectWorker(int serverIndex, const ServerCredentials &credent
qApp->processEvents(); qApp->processEvents();
emit connectToVpn(serverIndex, credentials, container, containerConfig); emit connectToVpn(serverIndex, credentials, container, containerConfig);
// if (errorCode) {
// //ui->pushButton_connect->setChecked(false);
// uiLogic()->setDialogConnectErrorText(errorString(errorCode));
// emit uiLogic()->showConnectErrorDialog();
// return;
// }
} }
void VpnLogic::onDisconnect() void VpnLogic::onDisconnect()

View file

@ -55,9 +55,9 @@ void WizardLogic::onPushButtonVpnModeFinishClicked()
auto containers = getInstallConfigsFromWizardPage(); auto containers = getInstallConfigsFromWizardPage();
uiLogic()->installServer(containers); uiLogic()->installServer(containers);
if (checkBoxVpnModeChecked()) { if (checkBoxVpnModeChecked()) {
m_settings.setRouteMode(Settings::VpnOnlyForwardSites); m_settings->setRouteMode(Settings::VpnOnlyForwardSites);
} else { } else {
m_settings.setRouteMode(Settings::VpnAllSites); m_settings->setRouteMode(Settings::VpnAllSites);
} }
} }

View file

@ -2,6 +2,7 @@
#define WIZARD_LOGIC_H #define WIZARD_LOGIC_H
#include "PageLogicBase.h" #include "PageLogicBase.h"
#include "containers/containers_defs.h"
class UiLogic; class UiLogic;

View file

@ -52,10 +52,10 @@ QJsonObject CloakLogic::getProtocolConfigFromPage(QJsonObject oldConfig)
void CloakLogic::onPushButtonSaveClicked() void CloakLogic::onPushButtonSaveClicked()
{ {
QJsonObject protocolConfig = m_settings.protocolConfig(uiLogic()->selectedServerIndex, uiLogic()->selectedDockerContainer, Proto::Cloak); QJsonObject protocolConfig = m_settings->protocolConfig(uiLogic()->selectedServerIndex, uiLogic()->selectedDockerContainer, Proto::Cloak);
protocolConfig = getProtocolConfigFromPage(protocolConfig); protocolConfig = getProtocolConfigFromPage(protocolConfig);
QJsonObject containerConfig = m_settings.containerConfig(uiLogic()->selectedServerIndex, uiLogic()->selectedDockerContainer); QJsonObject containerConfig = m_settings->containerConfig(uiLogic()->selectedServerIndex, uiLogic()->selectedDockerContainer);
QJsonObject newContainerConfig = containerConfig; QJsonObject newContainerConfig = containerConfig;
newContainerConfig.insert(ProtocolProps::protoToString(Proto::Cloak), protocolConfig); newContainerConfig.insert(ProtocolProps::protoToString(Proto::Cloak), protocolConfig);
@ -89,14 +89,14 @@ void CloakLogic::onPushButtonSaveClicked()
}; };
ErrorCode e = uiLogic()->doInstallAction([this, containerConfig, &newContainerConfig](){ ErrorCode e = uiLogic()->doInstallAction([this, containerConfig, &newContainerConfig](){
return ServerController::updateContainer(m_settings.serverCredentials(uiLogic()->selectedServerIndex), uiLogic()->selectedDockerContainer, containerConfig, newContainerConfig); return m_serverController->updateContainer(m_settings->serverCredentials(uiLogic()->selectedServerIndex), uiLogic()->selectedDockerContainer, containerConfig, newContainerConfig);
}, },
page_func, progressBar_reset, page_func, progressBar_reset,
pushButton_save_func, label_info_func); pushButton_save_func, label_info_func);
if (!e) { if (!e) {
m_settings.setContainerConfig(uiLogic()->selectedServerIndex, uiLogic()->selectedDockerContainer, newContainerConfig); m_settings->setContainerConfig(uiLogic()->selectedServerIndex, uiLogic()->selectedDockerContainer, newContainerConfig);
m_settings.clearLastConnectionConfig(uiLogic()->selectedServerIndex, uiLogic()->selectedDockerContainer); m_settings->clearLastConnectionConfig(uiLogic()->selectedServerIndex, uiLogic()->selectedDockerContainer);
} }
qDebug() << "Protocol saved with code:" << e << "for" << uiLogic()->selectedServerIndex << uiLogic()->selectedDockerContainer; qDebug() << "Protocol saved with code:" << e << "for" << uiLogic()->selectedServerIndex << uiLogic()->selectedDockerContainer;

View file

@ -32,7 +32,6 @@ public:
QJsonObject getProtocolConfigFromPage(QJsonObject oldConfig) override; QJsonObject getProtocolConfigFromPage(QJsonObject oldConfig) override;
private: private:
Settings m_settings;
UiLogic *m_uiLogic; UiLogic *m_uiLogic;
}; };

View file

@ -81,10 +81,10 @@ void OpenVpnLogic::updateProtocolPage(const QJsonObject &openvpnConfig, DockerCo
void OpenVpnLogic::onPushButtonProtoOpenVpnSaveClicked() void OpenVpnLogic::onPushButtonProtoOpenVpnSaveClicked()
{ {
QJsonObject protocolConfig = m_settings.protocolConfig(uiLogic()->selectedServerIndex, uiLogic()->selectedDockerContainer, Proto::OpenVpn); QJsonObject protocolConfig = m_settings->protocolConfig(uiLogic()->selectedServerIndex, uiLogic()->selectedDockerContainer, Proto::OpenVpn);
protocolConfig = getProtocolConfigFromPage(protocolConfig); protocolConfig = getProtocolConfigFromPage(protocolConfig);
QJsonObject containerConfig = m_settings.containerConfig(uiLogic()->selectedServerIndex, uiLogic()->selectedDockerContainer); QJsonObject containerConfig = m_settings->containerConfig(uiLogic()->selectedServerIndex, uiLogic()->selectedDockerContainer);
QJsonObject newContainerConfig = containerConfig; QJsonObject newContainerConfig = containerConfig;
newContainerConfig.insert(ProtocolProps::protoToString(Proto::OpenVpn), protocolConfig); newContainerConfig.insert(ProtocolProps::protoToString(Proto::OpenVpn), protocolConfig);
@ -118,14 +118,14 @@ void OpenVpnLogic::onPushButtonProtoOpenVpnSaveClicked()
}; };
ErrorCode e = uiLogic()->doInstallAction([this, containerConfig, &newContainerConfig](){ ErrorCode e = uiLogic()->doInstallAction([this, containerConfig, &newContainerConfig](){
return ServerController::updateContainer(m_settings.serverCredentials(uiLogic()->selectedServerIndex), uiLogic()->selectedDockerContainer, containerConfig, newContainerConfig); return m_serverController->updateContainer(m_settings->serverCredentials(uiLogic()->selectedServerIndex), uiLogic()->selectedDockerContainer, containerConfig, newContainerConfig);
}, },
page_proto_openvpn, progressBar_proto_openvpn_reset, page_proto_openvpn, progressBar_proto_openvpn_reset,
pushButton_proto_openvpn_save, label_proto_openvpn_info); pushButton_proto_openvpn_save, label_proto_openvpn_info);
if (!e) { if (!e) {
m_settings.setContainerConfig(uiLogic()->selectedServerIndex, uiLogic()->selectedDockerContainer, newContainerConfig); m_settings->setContainerConfig(uiLogic()->selectedServerIndex, uiLogic()->selectedDockerContainer, newContainerConfig);
m_settings.clearLastConnectionConfig(uiLogic()->selectedServerIndex, uiLogic()->selectedDockerContainer); m_settings->clearLastConnectionConfig(uiLogic()->selectedServerIndex, uiLogic()->selectedDockerContainer);
} }
qDebug() << "Protocol saved with code:" << e << "for" << uiLogic()->selectedServerIndex << uiLogic()->selectedDockerContainer; qDebug() << "Protocol saved with code:" << e << "for" << uiLogic()->selectedServerIndex << uiLogic()->selectedDockerContainer;
} }

View file

@ -44,7 +44,6 @@ public:
QJsonObject getProtocolConfigFromPage(QJsonObject oldConfig) override; QJsonObject getProtocolConfigFromPage(QJsonObject oldConfig) override;
private: private:
Settings m_settings;
UiLogic *m_uiLogic; UiLogic *m_uiLogic;
}; };

View file

@ -5,7 +5,6 @@
#include <QStandardPaths> #include <QStandardPaths>
#include "OtherProtocolsLogic.h" #include "OtherProtocolsLogic.h"
#include "core/servercontroller.h"
#include <functional> #include <functional>
#include "../../uilogic.h" #include "../../uilogic.h"
#include "utils.h" #include "utils.h"
@ -82,7 +81,7 @@ void OtherProtocolsLogic::onPushButtonSftpMountDriveClicked()
{ {
QString mountPath; QString mountPath;
QString cmd; QString cmd;
QString host = m_settings.serverCredentials(uiLogic()->selectedServerIndex).hostName; QString host = m_settings->serverCredentials(uiLogic()->selectedServerIndex).hostName;
#ifdef Q_OS_WINDOWS #ifdef Q_OS_WINDOWS

View file

@ -31,7 +31,6 @@ public:
//QJsonObject getProtocolConfigFromPage(QJsonObject oldConfig) override; //QJsonObject getProtocolConfigFromPage(QJsonObject oldConfig) override;
private: private:
Settings m_settings;
UiLogic *m_uiLogic; UiLogic *m_uiLogic;
#ifdef AMNEZIA_DESKTOP #ifdef AMNEZIA_DESKTOP

View file

@ -46,10 +46,9 @@ QJsonObject ShadowSocksLogic::getProtocolConfigFromPage(QJsonObject oldConfig)
void ShadowSocksLogic::onPushButtonSaveClicked() void ShadowSocksLogic::onPushButtonSaveClicked()
{ {
QJsonObject protocolConfig = m_settings.protocolConfig(uiLogic()->selectedServerIndex, uiLogic()->selectedDockerContainer, Proto::ShadowSocks); QJsonObject protocolConfig = m_settings->protocolConfig(uiLogic()->selectedServerIndex, uiLogic()->selectedDockerContainer, Proto::ShadowSocks);
//protocolConfig = getShadowSocksConfigFromPage(protocolConfig);
QJsonObject containerConfig = m_settings.containerConfig(uiLogic()->selectedServerIndex, uiLogic()->selectedDockerContainer); QJsonObject containerConfig = m_settings->containerConfig(uiLogic()->selectedServerIndex, uiLogic()->selectedDockerContainer);
QJsonObject newContainerConfig = containerConfig; QJsonObject newContainerConfig = containerConfig;
newContainerConfig.insert(ProtocolProps::protoToString(Proto::ShadowSocks), protocolConfig); newContainerConfig.insert(ProtocolProps::protoToString(Proto::ShadowSocks), protocolConfig);
UiLogic::PageFunc page_proto_shadowsocks; UiLogic::PageFunc page_proto_shadowsocks;
@ -82,14 +81,14 @@ void ShadowSocksLogic::onPushButtonSaveClicked()
}; };
ErrorCode e = uiLogic()->doInstallAction([this, containerConfig, &newContainerConfig](){ ErrorCode e = uiLogic()->doInstallAction([this, containerConfig, &newContainerConfig](){
return ServerController::updateContainer(m_settings.serverCredentials(uiLogic()->selectedServerIndex), uiLogic()->selectedDockerContainer, containerConfig, newContainerConfig); return m_serverController->updateContainer(m_settings->serverCredentials(uiLogic()->selectedServerIndex), uiLogic()->selectedDockerContainer, containerConfig, newContainerConfig);
}, },
page_proto_shadowsocks, progressBar_reset, page_proto_shadowsocks, progressBar_reset,
pushButton_proto_shadowsocks_save, label_proto_shadowsocks_info); pushButton_proto_shadowsocks_save, label_proto_shadowsocks_info);
if (!e) { if (!e) {
m_settings.setContainerConfig(uiLogic()->selectedServerIndex, uiLogic()->selectedDockerContainer, newContainerConfig); m_settings->setContainerConfig(uiLogic()->selectedServerIndex, uiLogic()->selectedDockerContainer, newContainerConfig);
m_settings.clearLastConnectionConfig(uiLogic()->selectedServerIndex, uiLogic()->selectedDockerContainer); m_settings->clearLastConnectionConfig(uiLogic()->selectedServerIndex, uiLogic()->selectedDockerContainer);
} }
qDebug() << "Protocol saved with code:" << e << "for" << uiLogic()->selectedServerIndex << uiLogic()->selectedDockerContainer; qDebug() << "Protocol saved with code:" << e << "for" << uiLogic()->selectedServerIndex << uiLogic()->selectedDockerContainer;
} }

View file

@ -30,7 +30,6 @@ public:
QJsonObject getProtocolConfigFromPage(QJsonObject oldConfig) override; QJsonObject getProtocolConfigFromPage(QJsonObject oldConfig) override;
private: private:
Settings m_settings;
UiLogic *m_uiLogic; UiLogic *m_uiLogic;
}; };

View file

@ -14,7 +14,7 @@
} \ } \
Q_SIGNAL void NAME ## Changed(TYPE value);\ Q_SIGNAL void NAME ## Changed(TYPE value);\
private: \ private: \
TYPE m_ ## NAME; TYPE m_ ## NAME{};
#define READONLY_PROPERTY(TYPE, NAME) \ #define READONLY_PROPERTY(TYPE, NAME) \
Q_PROPERTY(TYPE NAME READ NAME CONSTANT ) \ Q_PROPERTY(TYPE NAME READ NAME CONSTANT ) \
@ -22,6 +22,6 @@
TYPE NAME() const { return m_ ## NAME ; } \ TYPE NAME() const { return m_ ## NAME ; } \
private: \ private: \
void NAME(TYPE value) {m_ ## NAME = value; } \ void NAME(TYPE value) {m_ ## NAME = value; } \
TYPE m_ ## NAME; TYPE m_ ## NAME{};
#endif // PROPERTY_HELPER_H #endif // PROPERTY_HELPER_H

View file

@ -107,7 +107,7 @@ PageBase {
BlueButtonType { BlueButtonType {
Layout.fillWidth: true Layout.fillWidth: true
Layout.topMargin: 15 Layout.topMargin: 10
Layout.preferredHeight: 41 Layout.preferredHeight: 41
text: qsTr("Export logs") text: qsTr("Export logs")
onClicked: { onClicked: {
@ -117,7 +117,7 @@ PageBase {
BlueButtonType { BlueButtonType {
Layout.fillWidth: true Layout.fillWidth: true
Layout.topMargin: 15 Layout.topMargin: 10
Layout.preferredHeight: 41 Layout.preferredHeight: 41
property string start_text: qsTr("Clear logs") property string start_text: qsTr("Clear logs")
@ -135,6 +135,31 @@ PageBase {
AppSettingsLogic.onPushButtonClearLogsClicked() AppSettingsLogic.onPushButtonClearLogsClicked()
} }
} }
LabelType {
Layout.fillWidth: true
Layout.topMargin: 30
text: qsTr("Backup and restore configuration")
}
BlueButtonType {
Layout.fillWidth: true
Layout.topMargin: 10
Layout.preferredHeight: 41
text: qsTr("Backup app config")
onClicked: {
AppSettingsLogic.onPushButtonBackupAppConfigClicked()
}
}
BlueButtonType {
Layout.fillWidth: true
Layout.topMargin: 10
Layout.preferredHeight: 41
text: qsTr("Restore app config")
onClicked: {
AppSettingsLogic.onPushButtonRestoreAppConfigClicked()
}
}
} }
} }

View file

@ -1,462 +1,439 @@
import QtQuick 2.12 import QtQuick 2.12
import QtQuick.Controls 2.12 import QtQuick.Controls 2.12
import QtQuick.Dialogs 1.1 import QtQuick.Dialogs 1.1
import QtQuick.Layouts 1.15 import QtQuick.Layouts 1.15
import SortFilterProxyModel 0.2 import SortFilterProxyModel 0.2
import ContainerProps 1.0 import ContainerProps 1.0
import ProtocolProps 1.0 import ProtocolProps 1.0
import PageEnum 1.0 import PageEnum 1.0
import ProtocolEnum 1.0 import ProtocolEnum 1.0
import "./" import "./"
import "../Controls" import "../Controls"
import "../Config" import "../Config"
import "InstallSettings" import "InstallSettings"
PageBase { PageBase {
id: root id: root
page: PageEnum.ServerContainers page: PageEnum.ServerContainers
logic: ServerContainersLogic logic: ServerContainersLogic
enabled: ServerContainersLogic.pageEnabled enabled: ServerContainersLogic.pageEnabled
function resetPage() { function resetPage() {
container_selector.selectedIndex = -1 container_selector.selectedIndex = -1
} }
Connections { Connections {
target: logic target: logic
function onUpdatePage() { function onUpdatePage() {
root.resetPage() root.resetPage()
} }
} }
BackButton { BackButton {
id: back id: back
} }
Caption { Caption {
id: caption id: caption
text: container_selector.selectedIndex > 0 ? qsTr("Install new service") : qsTr("Installed services") text: container_selector.selectedIndex > 0 ? qsTr("Install new service") : qsTr("Installed services")
} }
SelectContainer { SelectContainer {
id: container_selector id: container_selector
onAboutToHide: { onAboutToHide: {
pageLoader.focus = true pageLoader.focus = true
} }
onContainerSelected: { onContainerSelected: {
var containerProto = ContainerProps.defaultProtocol(c_index) var containerProto = ContainerProps.defaultProtocol(c_index)
if (ProtocolProps.defaultPort(containerProto) < 0) { if (ProtocolProps.defaultPort(containerProto) < 0) {
tf_port_num.enabled = false tf_port_num.enabled = false
tf_port_num.text = qsTr("Default") tf_port_num.text = qsTr("Default")
} }
else tf_port_num.text = ProtocolProps.defaultPort(containerProto) else tf_port_num.text = ProtocolProps.defaultPort(containerProto)
cb_port_proto.currentIndex = ProtocolProps.defaultTransportProto(containerProto) cb_port_proto.currentIndex = ProtocolProps.defaultTransportProto(containerProto)
tf_port_num.enabled = ProtocolProps.defaultPortChangeable(containerProto) tf_port_num.enabled = ProtocolProps.defaultPortChangeable(containerProto)
cb_port_proto.enabled = ProtocolProps.defaultTransportProtoChangeable(containerProto) cb_port_proto.enabled = ProtocolProps.defaultTransportProtoChangeable(containerProto)
} }
} }
Column { Column {
id: c1 id: c1
visible: container_selector.selectedIndex > 0 visible: container_selector.selectedIndex > 0
width: parent.width width: parent.width
anchors.top: caption.bottom anchors.top: caption.bottom
anchors.topMargin: 10 anchors.topMargin: 10
Caption { Caption {
font.pixelSize: 22 font.pixelSize: 22
text: UiLogic.containerName(container_selector.selectedIndex) text: UiLogic.containerName(container_selector.selectedIndex)
} }
Text { Text {
width: parent.width width: parent.width
anchors.topMargin: 10 anchors.topMargin: 10
padding: 10 padding: 10
font.family: "Lato" font.family: "Lato"
font.styleName: "normal" font.styleName: "normal"
font.pixelSize: 16 font.pixelSize: 16
color: "#181922" color: "#181922"
horizontalAlignment: Text.AlignHCenter horizontalAlignment: Text.AlignHCenter
verticalAlignment: Text.AlignVCenter verticalAlignment: Text.AlignVCenter
wrapMode: Text.Wrap wrapMode: Text.Wrap
text: UiLogic.containerDesc(container_selector.selectedIndex) text: UiLogic.containerDesc(container_selector.selectedIndex)
} }
} }
Rectangle { Rectangle {
id: frame_settings id: frame_settings
visible: container_selector.selectedIndex > 0 visible: container_selector.selectedIndex > 0
width: parent.width width: parent.width
anchors.top: c1.bottom anchors.top: c1.bottom
anchors.topMargin: 10 anchors.topMargin: 10
border.width: 1 border.width: 1
border.color: "lightgray" border.color: "lightgray"
anchors.bottomMargin: 5 anchors.bottomMargin: 5
anchors.horizontalCenter: parent.horizontalCenter anchors.horizontalCenter: parent.horizontalCenter
radius: 2 radius: 2
Grid { Grid {
id: grid id: grid
visible: container_selector.selectedIndex > 0 visible: container_selector.selectedIndex > 0
anchors.fill: parent anchors.fill: parent
columns: 2 columns: 2
horizontalItemAlignment: Grid.AlignHCenter horizontalItemAlignment: Grid.AlignHCenter
verticalItemAlignment: Grid.AlignVCenter verticalItemAlignment: Grid.AlignVCenter
topPadding: 5 topPadding: 5
leftPadding: 10 leftPadding: 10
spacing: 5 spacing: 5
LabelType { LabelType {
width: 130 width: 130
text: qsTr("Port") text: qsTr("Port")
} }
TextFieldType { TextFieldType {
id: tf_port_num id: tf_port_num
width: parent.width - 130 - parent.spacing - parent.leftPadding * 2 width: parent.width - 130 - parent.spacing - parent.leftPadding * 2
} }
LabelType { LabelType {
width: 130 width: 130
text: qsTr("Network Protocol") text: qsTr("Network Protocol")
} }
ComboBoxType { ComboBoxType {
id: cb_port_proto id: cb_port_proto
width: parent.width - 130 - parent.spacing - parent.leftPadding * 2 width: parent.width - 130 - parent.spacing - parent.leftPadding * 2
model: [ model: [
qsTr("udp"), qsTr("udp"),
qsTr("tcp"), qsTr("tcp"),
] ]
} }
} }
} }
BlueButtonType { BlueButtonType {
id: pb_cancel_add id: pb_cancel_add
visible: container_selector.selectedIndex > 0 visible: container_selector.selectedIndex > 0
anchors.horizontalCenter: parent.horizontalCenter anchors.horizontalCenter: parent.horizontalCenter
anchors.bottom: pb_continue_add.top anchors.bottom: pb_continue_add.top
anchors.bottomMargin: 20 anchors.bottomMargin: 20
width: parent.width - 40 width: parent.width - 40
height: 40 height: 40
text: qsTr("Cancel") text: qsTr("Cancel")
font.pixelSize: 16 font.pixelSize: 16
onClicked: container_selector.selectedIndex = -1 onClicked: container_selector.selectedIndex = -1
} }
BlueButtonType { BlueButtonType {
id: pb_continue_add id: pb_continue_add
visible: container_selector.selectedIndex > 0 visible: container_selector.selectedIndex > 0
anchors.horizontalCenter: parent.horizontalCenter anchors.horizontalCenter: parent.horizontalCenter
anchors.bottom: parent.bottom anchors.bottom: parent.bottom
anchors.bottomMargin: 20 anchors.bottomMargin: 20
width: parent.width - 40 width: parent.width - 40
height: 40 height: 40
text: qsTr("Continue") text: qsTr("Continue")
font.pixelSize: 16 font.pixelSize: 16
onClicked: { onClicked: {
let cont = container_selector.selectedIndex let cont = container_selector.selectedIndex
let tp = ProtocolProps.transportProtoFromString(cb_port_proto.currentText) let tp = ProtocolProps.transportProtoFromString(cb_port_proto.currentText)
let port = tf_port_num.text let port = tf_port_num.text
ServerContainersLogic.onPushButtonContinueClicked(cont, port, tp) ServerContainersLogic.onPushButtonContinueClicked(cont, port, tp)
} }
} }
Flickable { Flickable {
visible: container_selector.selectedIndex <= 0 visible: container_selector.selectedIndex <= 0
clip: true clip: true
width: parent.width width: parent.width
anchors.top: caption.bottom anchors.top: caption.bottom
anchors.bottom: pb_add_container.top anchors.bottom: pb_add_container.top
contentHeight: col.height contentHeight: col.height
Column { Column {
visible: container_selector.selectedIndex <= 0 visible: container_selector.selectedIndex <= 0
id: col id: col
anchors { anchors {
left: parent.left; left: parent.left;
right: parent.right; right: parent.right;
} }
topPadding: 20 topPadding: 20
spacing: 10 spacing: 10
Caption { Caption {
id: cap1 id: cap1
text: qsTr("Installed Protocols and Services") text: qsTr("Installed Protocols and Services")
font.pixelSize: 20 font.pixelSize: 20
} }
SortFilterProxyModel { SortFilterProxyModel {
id: proxyContainersModel id: proxyContainersModel
sourceModel: UiLogic.containersModel sourceModel: UiLogic.containersModel
filters: ValueFilter { filters: ValueFilter {
roleName: "is_installed_role" roleName: "is_installed_role"
value: true value: true
} }
} }
SortFilterProxyModel { SortFilterProxyModel {
id: proxyProtocolsModel id: proxyProtocolsModel
sourceModel: UiLogic.protocolsModel sourceModel: UiLogic.protocolsModel
filters: ValueFilter { filters: ValueFilter {
roleName: "is_installed_role" roleName: "is_installed_role"
value: true value: true
} }
} }
ListView { ListView {
id: tb_c id: tb_c
x: 10 x: 10
width: parent.width - 10 width: parent.width - 10
height: tb_c.contentItem.height height: tb_c.contentItem.height
currentIndex: -1 currentIndex: -1
spacing: 5 spacing: 5
clip: true clip: true
interactive: false interactive: false
model: proxyContainersModel model: proxyContainersModel
delegate: Item { delegate: Item {
implicitWidth: tb_c.width - 10 implicitWidth: tb_c.width - 10
implicitHeight: c_item.height implicitHeight: c_item.height
Item { Item {
id: c_item id: c_item
width: parent.width width: parent.width
height: row_container.height + tb_p.height height: row_container.height + tb_p.height
anchors.left: parent.left anchors.left: parent.left
Rectangle { Rectangle {
anchors.top: parent.top anchors.top: parent.top
width: parent.width width: parent.width
height: 1 height: 1
color: "lightgray" color: "lightgray"
visible: index !== tb_c.currentIndex visible: index !== tb_c.currentIndex
} }
Rectangle { Rectangle {
anchors.top: row_container.top anchors.top: row_container.top
anchors.bottom: row_container.bottom anchors.bottom: row_container.bottom
anchors.left: parent.left anchors.left: parent.left
anchors.right: parent.right anchors.right: parent.right
color: "#63B4FB" color: "#63B4FB"
visible: index === tb_c.currentIndex visible: index === tb_c.currentIndex
} }
RowLayout { RowLayout {
id: row_container id: row_container
//width: parent.width anchors.left: parent.left
anchors.left: parent.left anchors.right: parent.right
anchors.right: parent.right
Text {
// anchors.top: lb_container_name.top id: lb_container_name
// anchors.bottom: lb_container_name.bottom text: name_role
font.pixelSize: 17
Text { color: "#100A44"
id: lb_container_name topPadding: 16
text: name_role bottomPadding: 12
font.pixelSize: 17 leftPadding: 10
//font.bold: true verticalAlignment: Text.AlignVCenter
color: "#100A44" wrapMode: Text.WordWrap
topPadding: 5 Layout.fillWidth: true
bottomPadding: 5
leftPadding: 10 MouseArea {
verticalAlignment: Text.AlignVCenter enabled: col.visible
wrapMode: Text.WordWrap anchors.top: lb_container_name.top
Layout.fillWidth: true anchors.bottom: lb_container_name.bottom
anchors.left: parent.left
MouseArea { anchors.right: parent.right
enabled: col.visible propagateComposedEvents: true
anchors.top: lb_container_name.top onClicked: {
anchors.bottom: lb_container_name.bottom if (tb_c.currentIndex === index) tb_c.currentIndex = -1
anchors.left: parent.left else tb_c.currentIndex = index
anchors.right: parent.right
propagateComposedEvents: true UiLogic.protocolsModel.setSelectedDockerContainer(proxyContainersModel.mapToSource(index))
onClicked: { }
if (tb_c.currentIndex === index) tb_c.currentIndex = -1 }
else tb_c.currentIndex = index }
UiLogic.protocolsModel.setSelectedDockerContainer(proxyContainersModel.mapToSource(index)) ImageButtonType {
} id: button_remove
} visible: index === tb_c.currentIndex
} Layout.alignment: Qt.AlignRight
checkable: true
ImageButtonType { icon.source: "qrc:/images/delete.png"
id: button_remove implicitWidth: 30
visible: index === tb_c.currentIndex implicitHeight: 30
Layout.alignment: Qt.AlignRight
checkable: true checked: default_role
icon.source: "qrc:/images/delete.png"
implicitWidth: 30 MessageDialog {
implicitHeight: 30 id: dialogRemove
standardButtons: StandardButton.Yes | StandardButton.Cancel
checked: default_role title: "AmneziaVPN"
text: qsTr("Remove container") + " " + name_role + "?" + "\n" + qsTr("This action will erase all data of this container on the server.")
MessageDialog { onAccepted: {
id: dialogRemove tb_c.currentIndex = -1
standardButtons: StandardButton.Yes | StandardButton.Cancel ServerContainersLogic.onPushButtonRemoveClicked(proxyContainersModel.mapToSource(index))
title: "AmneziaVPN" }
text: qsTr("Remove container") + " " + name_role + "?" + "\n" + qsTr("This action will erase all data of this container on the server.") }
onAccepted: {
tb_c.currentIndex = -1 onClicked: dialogRemove.open()
ServerContainersLogic.onPushButtonRemoveClicked(proxyContainersModel.mapToSource(index))
} VisibleBehavior on visible { }
} }
onClicked: dialogRemove.open() ImageButtonType {
id: button_share
VisibleBehavior on visible { } visible: index === tb_c.currentIndex
} Layout.alignment: Qt.AlignRight
icon.source: "qrc:/images/share.png"
ImageButtonType { implicitWidth: 30
id: button_share implicitHeight: 30
visible: index === tb_c.currentIndex onClicked: {
Layout.alignment: Qt.AlignRight ServerContainersLogic.onPushButtonShareClicked(proxyContainersModel.mapToSource(index))
icon.source: "qrc:/images/share.png" }
implicitWidth: 30
implicitHeight: 30 VisibleBehavior on visible { }
onClicked: { }
ServerContainersLogic.onPushButtonShareClicked(proxyContainersModel.mapToSource(index))
} ImageButtonType {
id: button_default
VisibleBehavior on visible { } visible: service_type_role == ProtocolEnum.Vpn
}
Layout.alignment: Qt.AlignRight
ImageButtonType { checkable: true
id: button_default img.source: checked ? "qrc:/images/check.png" : "qrc:/images/uncheck.png"
visible: service_type_role == ProtocolEnum.Vpn implicitWidth: 30
implicitHeight: 30
Layout.alignment: Qt.AlignRight
checkable: true checked: default_role
img.source: checked ? "qrc:/images/check.png" : "qrc:/images/uncheck.png" onClicked: {
implicitWidth: 30 ServerContainersLogic.onPushButtonDefaultClicked(proxyContainersModel.mapToSource(index))
implicitHeight: 30 }
}
checked: default_role }
onClicked: {
ServerContainersLogic.onPushButtonDefaultClicked(proxyContainersModel.mapToSource(index))
} ListView {
} id: tb_p
} currentIndex: -1
x: 10
anchors.top: row_container.bottom
ListView {
id: tb_p width: parent.width - 40
currentIndex: -1 height: index === tb_c.currentIndex ? tb_p.contentItem.height : 0
visible: index === tb_c.currentIndex implicitHeight: height
x: 10
anchors.top: row_container.bottom spacing: 0
clip: true
width: parent.width - 40 interactive: false
height: visible ? tb_p.contentItem.height : 0 model: proxyProtocolsModel
spacing: 0
clip: true Behavior on height {
interactive: false NumberAnimation {
model: proxyProtocolsModel duration: 200
}
VisibleBehavior on visible { } }
delegate: Item {
delegate: Item { id: dp_item
id: dp_item
implicitWidth: tb_p.width - 10
implicitWidth: tb_p.width - 10 implicitHeight: p_item.height
implicitHeight: p_item.height Item {
Item { id: p_item
id: p_item width: parent.width
width: parent.width height: lb_protocol_name.height
height: lb_protocol_name.height anchors.left: parent.left
anchors.left: parent.left Rectangle {
Rectangle { anchors.top: parent.top
anchors.top: parent.top width: parent.width
width: parent.width height: 1
height: 1 color: "lightgray"
color: "lightgray" visible: index > 0
visible: index !== tb_p.currentIndex }
}
// Rectangle { SettingButtonType {
// anchors.top: lb_protocol_name.top id: lb_protocol_name
// anchors.bottom: lb_protocol_name.bottom topPadding: 10
// width: parent.width bottomPadding: 10
// color: "#63B4FB" anchors.left: parent.left
// visible: index === tb_p.currentIndex anchors.leftMargin: 10
// }
width: parent.width
// Text { height: 45
// id: lb_protocol_name text: qsTr(name_role + " settings")
// text: name_role textItem.font.pixelSize: 16
// font.pixelSize: 16 icon.source: "qrc:/images/settings.png"
// topPadding: 5 onClicked: {
// bottomPadding: 5 tb_p.currentIndex = index
// leftPadding: 10 ServerContainersLogic.onPushButtonProtoSettingsClicked(
// verticalAlignment: Text.AlignVCenter proxyContainersModel.mapToSource(tb_c.currentIndex),
// wrapMode: Text.WordWrap proxyProtocolsModel.mapToSource(tb_p.currentIndex))
// } }
}
SettingButtonType { }
id: lb_protocol_name }
}
// anchors.top: lb_protocol_name.top }
// anchors.bottom: lb_protocol_name.bottom }
topPadding: 10 }
bottomPadding: 10 }
leftPadding: 10 }
anchors.left: parent.left
BlueButtonType {
width: parent.width id: pb_add_container
height: 30 visible: container_selector.selectedIndex < 0
text: qsTr(name_role + " settings")
textItem.font.pixelSize: 16 anchors.horizontalCenter: parent.horizontalCenter
icon.source: "qrc:/images/settings.png" anchors.bottom: parent.bottom
onClicked: { anchors.topMargin: 10
tb_p.currentIndex = index anchors.bottomMargin: 20
ServerContainersLogic.onPushButtonProtoSettingsClicked(
proxyContainersModel.mapToSource(tb_c.currentIndex), width: parent.width - 40
proxyProtocolsModel.mapToSource(tb_p.currentIndex)) height: 40
} text: qsTr("Install new protocols container")
} font.pixelSize: 16
} onClicked: container_selector.visible ? container_selector.close() : container_selector.open()
}
} }
} }
}
}
}
}
BlueButtonType {
id: pb_add_container
visible: container_selector.selectedIndex < 0
anchors.horizontalCenter: parent.horizontalCenter
anchors.bottom: parent.bottom
anchors.topMargin: 10
anchors.bottomMargin: 20
width: parent.width - 40
height: 40
text: qsTr("Install new protocols container")
font.pixelSize: 16
onClicked: container_selector.visible ? container_selector.close() : container_selector.open()
}
}

View file

@ -59,7 +59,7 @@ PageBase {
text: qsTr("Share for Amnezia") text: qsTr("Share for Amnezia")
height: 40 height: 40
width: tb_c.width - 10 width: tb_c.width - 10
onClicked: UiLogic.onGotoShareProtocolPage(ProtocolEnum.Any) onClicked: UiLogic.goToShareProtocolPage(ProtocolEnum.Any)
} }
ListView { ListView {
@ -82,7 +82,7 @@ PageBase {
text: qsTr("Share for ") + name_role text: qsTr("Share for ") + name_role
height: 40 height: 40
width: tb_c.width - 10 width: tb_c.width - 10
onClicked: UiLogic.onGotoShareProtocolPage(proxyProtocolsModel.mapToSource(index)) onClicked: UiLogic.goToShareProtocolPage(proxyProtocolsModel.mapToSource(index))
} }
} }
} }

View file

@ -119,7 +119,6 @@ PageBase {
anchors.topMargin: 40 anchors.topMargin: 40
text: qsTr("Open file") text: qsTr("Open file")
visible: StartPageLogic.pushButtonConnectVisible
onClicked: { onClicked: {
StartPageLogic.onPushButtonImportOpenFile() StartPageLogic.onPushButtonImportOpenFile()
} }
@ -133,7 +132,6 @@ PageBase {
anchors.topMargin: 10 anchors.topMargin: 10
text: qsTr("Scan QR code") text: qsTr("Scan QR code")
visible: StartPageLogic.pushButtonConnectVisible
onClicked: { onClicked: {
if (Qt.platform.os == "ios") { if (Qt.platform.os == "ios") {
UiLogic.goToPage(PageEnum.QrDecoderIos) UiLogic.goToPage(PageEnum.QrDecoderIos)
@ -144,7 +142,19 @@ PageBase {
enabled: StartPageLogic.pushButtonConnectEnabled enabled: StartPageLogic.pushButtonConnectEnabled
} }
BlueButtonType {
id: btn_restore_cfg
anchors.horizontalCenter: parent.horizontalCenter
anchors.top: qr_code_import.bottom
anchors.topMargin: 30
visible: UiLogic.pagesStackDepth == 1
enabled: StartPageLogic.pushButtonConnectEnabled
text: qsTr("Restore app config")
onClicked: {
AppSettingsLogic.onPushButtonRestoreAppConfigClicked()
}
}
} }
@ -270,7 +280,6 @@ PageBase {
anchors.topMargin: 10 anchors.topMargin: 10
text: StartPageLogic.pushButtonConnectText text: StartPageLogic.pushButtonConnectText
visible: StartPageLogic.pushButtonConnectVisible
onClicked: { onClicked: {
StartPageLogic.onPushButtonConnect() StartPageLogic.onPushButtonConnect()
} }

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