diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml
index 63bda344..220fbd79 100644
--- a/.github/workflows/deploy.yml
+++ b/.github/workflows/deploy.yml
@@ -10,12 +10,12 @@ env:
jobs:
Build-Linux-Ubuntu:
- name: 'Build-Linux-Ubuntu'
runs-on: ubuntu-20.04
env:
QT_VERSION: 6.6.2
QIF_VERSION: 4.7
+ PROD_AGW_PUBLIC_KEY: ${{ secrets.PROD_AGW_PUBLIC_KEY }}
steps:
- name: 'Install Qt'
@@ -75,13 +75,13 @@ jobs:
# ------------------------------------------------------
Build-Windows:
- name: Build-Windows
runs-on: windows-latest
env:
QT_VERSION: 6.6.2
QIF_VERSION: 4.7
BUILD_ARCH: 64
+ PROD_AGW_PUBLIC_KEY: ${{ secrets.PROD_AGW_PUBLIC_KEY }}
steps:
- name: 'Get sources'
@@ -137,13 +137,13 @@ jobs:
# ------------------------------------------------------
Build-iOS:
- name: 'Build-iOS'
runs-on: macos-13
env:
QT_VERSION: 6.6.2
CC: cc
CXX: c++
+ PROD_AGW_PUBLIC_KEY: ${{ secrets.PROD_AGW_PUBLIC_KEY }}
steps:
- name: 'Setup xcode'
@@ -228,13 +228,13 @@ jobs:
# ------------------------------------------------------
Build-MacOS:
- name: 'Build-MacOS'
runs-on: macos-latest
env:
# Keep compat with MacOS 10.15 aka Catalina by Qt 6.4
QT_VERSION: 6.4.3
QIF_VERSION: 4.6
+ PROD_AGW_PUBLIC_KEY: ${{ secrets.PROD_AGW_PUBLIC_KEY }}
steps:
- name: 'Setup xcode'
@@ -293,13 +293,13 @@ jobs:
# ------------------------------------------------------
Build-Android:
- name: 'Build-Android'
runs-on: ubuntu-latest
env:
ANDROID_BUILD_PLATFORM: android-34
QT_VERSION: 6.6.2
QT_MODULES: 'qtremoteobjects qt5compat qtimageformats qtshadertools'
+ PROD_AGW_PUBLIC_KEY: ${{ secrets.PROD_AGW_PUBLIC_KEY }}
steps:
- name: 'Install desktop Qt'
@@ -439,3 +439,21 @@ jobs:
path: deploy/build/AmneziaVPN-release.aab
compression-level: 0
retention-days: 7
+
+ Extra:
+ runs-on: ubuntu-latest
+ steps:
+ - name: Search a corresponding PR
+ uses: octokit/request-action@v2.x
+ id: pull_request
+ with:
+ route: GET /repos/${{ github.repository }}/pulls
+ head: ${{ github.repository_owner }}:${{ github.ref_name }}
+ env:
+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+
+ - name: Add PR link to build summary
+ if: ${{ fromJSON(steps.pull_request.outputs.data)[0].number != '' }}
+ run: |
+ echo "Pull request:" >> $GITHUB_STEP_SUMMARY
+ echo "[[#${{ fromJSON(steps.pull_request.outputs.data)[0].number }}] ${{ fromJSON(steps.pull_request.outputs.data)[0].title }}](${{ fromJSON(steps.pull_request.outputs.data)[0].html_url }})" >> $GITHUB_STEP_SUMMARY
diff --git a/.github/workflows/tag-deploy.yml b/.github/workflows/tag-deploy.yml
index b88390f4..e117a6c6 100644
--- a/.github/workflows/tag-deploy.yml
+++ b/.github/workflows/tag-deploy.yml
@@ -15,6 +15,7 @@ jobs:
env:
QT_VERSION: 6.4.1
QIF_VERSION: 4.5
+ PROD_AGW_PUBLIC_KEY: ${{ secrets.PROD_AGW_PUBLIC_KEY }}
steps:
- name: 'Install desktop Qt'
diff --git a/.gitmodules b/.gitmodules
index 78d45e25..3ceaa56e 100644
--- a/.gitmodules
+++ b/.gitmodules
@@ -13,3 +13,6 @@
[submodule "client/3rd/amneziawg-apple"]
path = client/3rd/amneziawg-apple
url = https://github.com/amnezia-vpn/amneziawg-apple
+[submodule "client/3rd/QSimpleCrypto"]
+ path = client/3rd/QSimpleCrypto
+ url = https://github.com/amnezia-vpn/QSimpleCrypto.git
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 53dc9ed2..41e05838 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -2,7 +2,7 @@ cmake_minimum_required(VERSION 3.25.0 FATAL_ERROR)
set(PROJECT AmneziaVPN)
-project(${PROJECT} VERSION 4.6.0.4
+project(${PROJECT} VERSION 4.7.0.0
DESCRIPTION "AmneziaVPN"
HOMEPAGE_URL "https://amnezia.org/"
)
@@ -11,7 +11,7 @@ string(TIMESTAMP CURRENT_DATE "%Y-%m-%d")
set(RELEASE_DATE "${CURRENT_DATE}")
set(APP_MAJOR_VERSION ${CMAKE_PROJECT_VERSION_MAJOR}.${CMAKE_PROJECT_VERSION_MINOR}.${CMAKE_PROJECT_VERSION_PATCH})
-set(APP_ANDROID_VERSION_CODE 55)
+set(APP_ANDROID_VERSION_CODE 57)
if(${CMAKE_SYSTEM_NAME} STREQUAL "Linux")
set(MZ_PLATFORM_NAME "linux")
diff --git a/README.md b/README.md
index 2e43e856..e4a6bf0c 100644
--- a/README.md
+++ b/README.md
@@ -10,10 +10,10 @@ Amnezia is an open-source VPN client, with a key feature that enables you to dep
-
-
-
-
+
+
+
+
@@ -28,11 +28,12 @@ Amnezia is an open-source VPN client, with a key feature that enables you to dep
## Features
-- Very easy to use - enter your IP address, SSH login, and password, and Amnezia will automatically install VPN docker containers to your server and connect to the VPN.
-- OpenVPN, Shadowsocks, WireGuard, and IKEv2 protocols support.
-- Masking VPN with OpenVPN over Cloak plugin
-- Split tunneling support - add any sites to the client to enable VPN only for them (only for desktops)
+- Very easy to use - enter your IP address, SSH login, password and Amnezia will automatically install VPN docker containers to your server and connect to the VPN.
+- Classic VPN-protocols: OpenVPN, WireGuard and IKEv2 protocols.
+- Protocols with traffic Masking (Obfuscation): OpenVPN over [Cloak](https://github.com/cbeuw/Cloak) plugin, Shadowsocks (OpenVPN over Shadowsocks), [AmneziaWG](https://docs.amnezia.org/documentation/amnezia-wg/) and XRay.
+- Split tunneling support - add any sites to the client to enable VPN only for them or add Apps (only for Android and Desktop).
- Windows, MacOS, Linux, Android, iOS releases.
+- Support for AmneziaWG protocol configuration on [Keenetic beta firmware](https://docs.keenetic.com/ua/air/kn-1611/en/6319-latest-development-release.html#UUID-186c4108-5afd-c10b-f38a-cdff6c17fab3_section-idm33192196168192-improved).
## Links
@@ -41,7 +42,8 @@ Amnezia is an open-source VPN client, with a key feature that enables you to dep
- [https://t.me/amnezia_vpn_en](https://t.me/amnezia_vpn_en) - Telegram support channel (English)
- [https://t.me/amnezia_vpn_ir](https://t.me/amnezia_vpn_ir) - Telegram support channel (Farsi)
- [https://t.me/amnezia_vpn_mm](https://t.me/amnezia_vpn_mm) - Telegram support channel (Myanmar)
-- [https://t.me/amnezia_vpn](https://t.me/amnezia_vpn) - Telegram support channel (Russian)
+- [https://t.me/amnezia_vpn](https://t.me/amnezia_vpn) - Telegram support channel (Russian)
+- [https://vpnpay.io/en/amnezia-premium/](https://vpnpay.io/en/amnezia-premium/) - Amnezia Premium
## Tech
@@ -154,9 +156,11 @@ The Android app has the following requirements:
* Android platform SDK 33
* CMake 3.25.0
-After you have installed QT, QT Creator, and Android Studio, you need to configure QT Creator correctly. Click in the top menu bar on `QT Creator` -> `Preferences` -> `Devices` and select the tab `Android`.
- * set path to JDK 11
- * set path to Android SDK ($ANDROID_HOME)
+After you have installed QT, QT Creator, and Android Studio, you need to configure QT Creator correctly.
+
+- Click in the top menu bar on `QT Creator` -> `Preferences` -> `Devices` and select the tab `Android`.
+- Set path to JDK 11
+- Set path to Android SDK (`$ANDROID_HOME`)
In case you get errors regarding missing SDK or 'SDK manager not running', you cannot fix them by correcting the paths. If you have some spare GBs on your disk, you can let QT Creator install all requirements by choosing an empty folder for `Android SDK location` and clicking on `Set Up SDK`. Be aware: This will install a second Android SDK and NDK on your machine!
Double-check that the right CMake version is configured: Click on `QT Creator` -> `Preferences` and click on the side menu on `Kits`. Under the center content view's `Kits` tab, you'll find an entry for `CMake Tool`. If the default selected CMake version is lower than 3.25.0, install on your system CMake >= 3.25.0 and choose `System CMake at ` from the drop-down list. If this entry is missing, you either have not installed CMake yet or QT Creator hasn't found the path to it. In that case, click in the preferences window on the side menu item `CMake`, then on the tab `Tools` in the center content view, and finally on the button `Add` to set the path to your installed CMake.
@@ -179,6 +183,7 @@ GPL v3.0
Patreon: [https://www.patreon.com/amneziavpn](https://www.patreon.com/amneziavpn)
+Bitcoin: bc1q26eevjcg9j0wuyywd2e3uc9cs2w58lpkpjxq6p
USDT BEP20: 0x6abD576765a826f87D1D95183438f9408C901bE4
USDT TRC20: TELAitazF1MZGmiNjTcnxDjEiH5oe7LC9d
XMR: 48spms39jt1L2L5vyw2RQW6CXD6odUd4jFu19GZcDyKKQV9U88wsJVjSbL4CfRys37jVMdoaWVPSvezCQPhHXUW5UKLqUp3
diff --git a/client/3rd-prebuilt b/client/3rd-prebuilt
index ff8445c8..c38a587f 160000
--- a/client/3rd-prebuilt
+++ b/client/3rd-prebuilt
@@ -1 +1 @@
-Subproject commit ff8445c8aa1cda38497bb6f6cb0e520f5a3c8de0
+Subproject commit c38a587fcda89bab4009560d36239fa8de74705e
diff --git a/client/3rd/OpenVPNAdapter b/client/3rd/OpenVPNAdapter
index 7c821a8d..dea60409 160000
--- a/client/3rd/OpenVPNAdapter
+++ b/client/3rd/OpenVPNAdapter
@@ -1 +1 @@
-Subproject commit 7c821a8d5c1ad5ad94e0763b4f25a875b5a6fe1b
+Subproject commit dea6040996298e947d63fb172709e6abfec2ba93
diff --git a/client/3rd/QSimpleCrypto b/client/3rd/QSimpleCrypto
new file mode 160000
index 00000000..c99b33f0
--- /dev/null
+++ b/client/3rd/QSimpleCrypto
@@ -0,0 +1 @@
+Subproject commit c99b33f0e08b7206116ddff85c22d3b97ce1e79d
diff --git a/client/3rd/QSimpleCrypto/QSimpleCrypto.cmake b/client/3rd/QSimpleCrypto/QSimpleCrypto.cmake
deleted file mode 100644
index 7ec5498a..00000000
--- a/client/3rd/QSimpleCrypto/QSimpleCrypto.cmake
+++ /dev/null
@@ -1,20 +0,0 @@
-include_directories(${CMAKE_CURRENT_LIST_DIR})
-
-set(HEADERS ${HEADERS}
- ${CMAKE_CURRENT_LIST_DIR}/include/QAead.h
- ${CMAKE_CURRENT_LIST_DIR}/include/QBlockCipher.h
- ${CMAKE_CURRENT_LIST_DIR}/include/QCryptoError.h
- ${CMAKE_CURRENT_LIST_DIR}/include/QRsa.h
- ${CMAKE_CURRENT_LIST_DIR}/include/QSimpleCrypto_global.h
- ${CMAKE_CURRENT_LIST_DIR}/include/QX509.h
- ${CMAKE_CURRENT_LIST_DIR}/include/QX509Store.h
-)
-
-set(SOURCES ${SOURCES}
- ${CMAKE_CURRENT_LIST_DIR}/sources/QAead.cpp
- ${CMAKE_CURRENT_LIST_DIR}/sources/QBlockCipher.cpp
- ${CMAKE_CURRENT_LIST_DIR}/sources/QCryptoError.cpp
- ${CMAKE_CURRENT_LIST_DIR}/sources/QRsa.cpp
- ${CMAKE_CURRENT_LIST_DIR}/sources/QX509.cpp
- ${CMAKE_CURRENT_LIST_DIR}/sources/QX509Store.cpp
-)
diff --git a/client/3rd/QSimpleCrypto/QSimpleCrypto.pri b/client/3rd/QSimpleCrypto/QSimpleCrypto.pri
deleted file mode 100644
index 99a1c129..00000000
--- a/client/3rd/QSimpleCrypto/QSimpleCrypto.pri
+++ /dev/null
@@ -1,18 +0,0 @@
-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
diff --git a/client/3rd/QSimpleCrypto/include/QAead.h b/client/3rd/QSimpleCrypto/include/QAead.h
deleted file mode 100644
index 11f60b31..00000000
--- a/client/3rd/QSimpleCrypto/include/QAead.h
+++ /dev/null
@@ -1,87 +0,0 @@
-/**
- * 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
-
-#include
-
-#include
-#include
-#include
-#include
-
-#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
diff --git a/client/3rd/QSimpleCrypto/include/QBlockCipher.h b/client/3rd/QSimpleCrypto/include/QBlockCipher.h
deleted file mode 100644
index e7b83a88..00000000
--- a/client/3rd/QSimpleCrypto/include/QBlockCipher.h
+++ /dev/null
@@ -1,84 +0,0 @@
-/**
- * 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
-
-#include
-
-#include
-#include
-#include
-#include
-
-#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
diff --git a/client/3rd/QSimpleCrypto/include/QCryptoError.h b/client/3rd/QSimpleCrypto/include/QCryptoError.h
deleted file mode 100644
index fc059654..00000000
--- a/client/3rd/QSimpleCrypto/include/QCryptoError.h
+++ /dev/null
@@ -1,45 +0,0 @@
-#ifndef QCRYPTOERROR_H
-#define QCRYPTOERROR_H
-
-#include
-
-#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 lastError() const
- {
- return QPair(m_currentErrorCode, m_errorSummary);
- }
-
- private:
- quint8 m_currentErrorCode;
- QString m_errorSummary;
- };
-}
-
-#endif // QCRYPTOERROR_H
diff --git a/client/3rd/QSimpleCrypto/include/QRsa.h b/client/3rd/QSimpleCrypto/include/QRsa.h
deleted file mode 100644
index 45eb3169..00000000
--- a/client/3rd/QSimpleCrypto/include/QRsa.h
+++ /dev/null
@@ -1,104 +0,0 @@
-/**
- * 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
-#include
-
-#include
-
-#include
-#include
-#include
-
-#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
diff --git a/client/3rd/QSimpleCrypto/include/QSimpleCrypto_global.h b/client/3rd/QSimpleCrypto/include/QSimpleCrypto_global.h
deleted file mode 100644
index fdd6c020..00000000
--- a/client/3rd/QSimpleCrypto/include/QSimpleCrypto_global.h
+++ /dev/null
@@ -1,9 +0,0 @@
-#ifndef QSIMPLECRYPTO_GLOBAL_H
-#define QSIMPLECRYPTO_GLOBAL_H
-
-#include
-#include
-
-#define QSIMPLECRYPTO_EXPORT
-
-#endif // QSIMPLECRYPTO_GLOBAL_H
diff --git a/client/3rd/QSimpleCrypto/include/QX509.h b/client/3rd/QSimpleCrypto/include/QX509.h
deleted file mode 100644
index c31cb9e4..00000000
--- a/client/3rd/QSimpleCrypto/include/QX509.h
+++ /dev/null
@@ -1,87 +0,0 @@
-/**
- * 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
-#include
-
-#include
-
-#include
-#include
-#include
-#include
-#include
-
-#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(RSA* rsa, const QMap& 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
diff --git a/client/3rd/QSimpleCrypto/include/QX509Store.h b/client/3rd/QSimpleCrypto/include/QX509Store.h
deleted file mode 100644
index 8cd8ca82..00000000
--- a/client/3rd/QSimpleCrypto/include/QX509Store.h
+++ /dev/null
@@ -1,120 +0,0 @@
-/**
- * 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
-#include
-#include
-
-#include
-
-#include
-#include
-#include
-
-#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
diff --git a/client/3rd/QSimpleCrypto/sources/QAead.cpp b/client/3rd/QSimpleCrypto/sources/QAead.cpp
deleted file mode 100644
index 968c8841..00000000
--- a/client/3rd/QSimpleCrypto/sources/QAead.cpp
+++ /dev/null
@@ -1,364 +0,0 @@
-/**
- * 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 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 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(key.data()), reinterpret_cast(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(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(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(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(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 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 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(key.data()), reinterpret_cast(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(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(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(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(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 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 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(key.data()), reinterpret_cast(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(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(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(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(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 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 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(key.data()), reinterpret_cast(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(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(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(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(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();
-}
diff --git a/client/3rd/QSimpleCrypto/sources/QBlockCipher.cpp b/client/3rd/QSimpleCrypto/sources/QBlockCipher.cpp
deleted file mode 100644
index 8b86ab98..00000000
--- a/client/3rd/QSimpleCrypto/sources/QBlockCipher.cpp
+++ /dev/null
@@ -1,193 +0,0 @@
-/**
- * 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(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(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 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(key.data());
- unsigned char* m_iv = reinterpret_cast(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 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(salt.data()), reinterpret_cast(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(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(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 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(key.data());
- unsigned char* m_iv = reinterpret_cast(iv.data());
-
- /* Set data length */
- int plainTextLength(data.size());
- int finalLength = 0;
-
- /* Initialize plainText. Here decrypted data will be stored */
- std::unique_ptr 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(salt.data()), reinterpret_cast(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(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(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();
-}
diff --git a/client/3rd/QSimpleCrypto/sources/QCryptoError.cpp b/client/3rd/QSimpleCrypto/sources/QCryptoError.cpp
deleted file mode 100644
index 234f55d7..00000000
--- a/client/3rd/QSimpleCrypto/sources/QCryptoError.cpp
+++ /dev/null
@@ -1,6 +0,0 @@
-#include "include/QCryptoError.h"
-
-QSimpleCrypto::QCryptoError::QCryptoError(QObject* parent)
- : QObject(parent)
-{
-}
diff --git a/client/3rd/QSimpleCrypto/sources/QRsa.cpp b/client/3rd/QSimpleCrypto/sources/QRsa.cpp
deleted file mode 100644
index 544d6746..00000000
--- a/client/3rd/QSimpleCrypto/sources/QRsa.cpp
+++ /dev/null
@@ -1,274 +0,0 @@
-/**
- * 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 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 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 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(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 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 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 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(plainText.data()), cipherText.get(), rsa, padding);
- } else if (encryptType == PrivateDecrypt) {
- result = RSA_private_encrypt(plainText.size(), reinterpret_cast(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(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 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(cipherText.data()), plainText.get(), rsa, padding);
- } else if (decryptType == PrivateDecrypt) {
- result = RSA_private_decrypt(RSA_size(rsa), reinterpret_cast(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(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 "";
- }
-}
diff --git a/client/3rd/QSimpleCrypto/sources/QX509.cpp b/client/3rd/QSimpleCrypto/sources/QX509.cpp
deleted file mode 100644
index ac4fd270..00000000
--- a/client/3rd/QSimpleCrypto/sources/QX509.cpp
+++ /dev/null
@@ -1,234 +0,0 @@
-/**
- * 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 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 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 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(RSA* rsa, const QMap& 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 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 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(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 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;
- }
-}
diff --git a/client/3rd/QSimpleCrypto/sources/QX509Store.cpp b/client/3rd/QSimpleCrypto/sources/QX509Store.cpp
deleted file mode 100644
index bbbec1a8..00000000
--- a/client/3rd/QSimpleCrypto/sources/QX509Store.cpp
+++ /dev/null
@@ -1,176 +0,0 @@
-/**
- * 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;
-}
diff --git a/client/CMakeLists.txt b/client/CMakeLists.txt
index baad1b9a..0a155b18 100644
--- a/client/CMakeLists.txt
+++ b/client/CMakeLists.txt
@@ -24,6 +24,9 @@ execute_process(
add_definitions(-DGIT_COMMIT_HASH="${GIT_COMMIT_HASH}")
+add_definitions(-DPROD_AGW_PUBLIC_KEY="$ENV{PROD_AGW_PUBLIC_KEY}")
+add_definitions(-DPROD_PROXY_STORAGE_KEY="$ENV{PROD_PROXY_STORAGE_KEY}")
+
if(IOS)
set(PACKAGES ${PACKAGES} Multimedia)
endif()
@@ -34,7 +37,7 @@ endif()
find_package(Qt6 REQUIRED COMPONENTS ${PACKAGES})
-set(LIBS ${LIBS}
+set(LIBS ${LIBS}
Qt6::Core Qt6::Gui
Qt6::Network Qt6::Xml Qt6::RemoteObjects
Qt6::Quick Qt6::Svg Qt6::QuickControls2
@@ -136,6 +139,7 @@ set(HEADERS ${HEADERS}
${CMAKE_CURRENT_LIST_DIR}/core/networkUtilities.h
${CMAKE_CURRENT_LIST_DIR}/core/serialization/serialization.h
${CMAKE_CURRENT_LIST_DIR}/core/serialization/transfer.h
+ ${CMAKE_CURRENT_LIST_DIR}/core/enums/apiEnums.h
)
# Mozilla headres
@@ -252,7 +256,7 @@ set(SOURCES ${SOURCES}
if(WIN32)
configure_file(
- ${CMAKE_CURRENT_LIST_DIR}/platforms/windows/amneziavpn.rc.in
+ ${CMAKE_CURRENT_LIST_DIR}/platforms/windows/amneziavpn.rc.in
${CMAKE_CURRENT_BINARY_DIR}/amneziavpn.rc
)
diff --git a/client/amnezia_application.cpp b/client/amnezia_application.cpp
index 8fe97cd7..b8ce5b00 100644
--- a/client/amnezia_application.cpp
+++ b/client/amnezia_application.cpp
@@ -3,13 +3,13 @@
#include
#include
#include
+#include
#include
#include
#include
#include
#include
#include
-#include
#include "logger.h"
#include "ui/models/installedAppsModel.h"
@@ -116,7 +116,7 @@ void AmneziaApplication::init()
}
connect(AndroidController::instance(), &AndroidController::importConfigFromOutside, [this](QString data) {
- m_pageController->replaceStartPage();
+ m_pageController->goToPageHome();
m_importController->extractConfigFromData(data);
m_pageController->goToPageViewConfig();
});
@@ -127,13 +127,13 @@ void AmneziaApplication::init()
#ifdef Q_OS_IOS
IosController::Instance()->initialize();
connect(IosController::Instance(), &IosController::importConfigFromOutside, [this](QString data) {
- m_pageController->replaceStartPage();
+ m_pageController->goToPageHome();
m_importController->extractConfigFromData(data);
m_pageController->goToPageViewConfig();
});
connect(IosController::Instance(), &IosController::importBackupFromOutside, [this](QString filePath) {
- m_pageController->replaceStartPage();
+ m_pageController->goToPageHome();
m_pageController->goToPageSettingsBackup();
m_settingsController->importBackupFromOutside(filePath);
});
@@ -161,13 +161,15 @@ void AmneziaApplication::init()
m_engine->load(url);
m_systemController->setQmlRoot(m_engine->rootObjects().value(0));
+ bool enabled = m_settings->isSaveLogs();
#ifndef Q_OS_ANDROID
- if (m_settings->isSaveLogs()) {
+ if (enabled) {
if (!Logger::init()) {
qWarning() << "Initialization of debug subsystem failed";
}
}
#endif
+ Logger::setServiceLogsEnabled(enabled);
#ifdef Q_OS_WIN
if (m_parser.isSet("a"))
@@ -359,6 +361,18 @@ void AmneziaApplication::initModels()
m_engine->rootContext()->setContextProperty("ClientManagementModel", m_clientManagementModel.get());
connect(m_clientManagementModel.get(), &ClientManagementModel::adminConfigRevoked, m_serversModel.get(),
&ServersModel::clearCachedProfile);
+
+ m_apiServicesModel.reset(new ApiServicesModel(this));
+ m_engine->rootContext()->setContextProperty("ApiServicesModel", m_apiServicesModel.get());
+
+ m_apiCountryModel.reset(new ApiCountryModel(this));
+ m_engine->rootContext()->setContextProperty("ApiCountryModel", m_apiCountryModel.get());
+ connect(m_serversModel.get(), &ServersModel::updateApiLanguageModel, this, [this]() {
+ m_apiCountryModel->updateModel(m_serversModel->getProcessedServerData("apiAvailableCountries").toJsonArray(),
+ m_serversModel->getProcessedServerData("apiServerCountryCode").toString());
+ });
+ connect(m_serversModel.get(), &ServersModel::updateApiServicesModel, this,
+ [this]() { m_apiServicesModel->updateModel(m_serversModel->getProcessedServerData("apiConfig").toJsonObject()); });
}
void AmneziaApplication::initControllers()
@@ -367,25 +381,26 @@ void AmneziaApplication::initControllers()
new ConnectionController(m_serversModel, m_containersModel, m_clientManagementModel, m_vpnConnection, m_settings));
m_engine->rootContext()->setContextProperty("ConnectionController", m_connectionController.get());
- connect(m_connectionController.get(), qOverload(&ConnectionController::connectionErrorOccurred), this, [this](const QString &errorMessage) {
- emit m_pageController->showErrorMessage(errorMessage);
- emit m_vpnConnection->connectionStateChanged(Vpn::ConnectionState::Disconnected);
- });
+ connect(m_connectionController.get(), qOverload(&ConnectionController::connectionErrorOccurred), this,
+ [this](const QString &errorMessage) {
+ emit m_pageController->showErrorMessage(errorMessage);
+ emit m_vpnConnection->connectionStateChanged(Vpn::ConnectionState::Disconnected);
+ });
- connect(m_connectionController.get(), qOverload(&ConnectionController::connectionErrorOccurred), this, [this](ErrorCode errorCode) {
- emit m_pageController->showErrorMessage(errorCode);
- emit m_vpnConnection->connectionStateChanged(Vpn::ConnectionState::Disconnected);
- });
+ connect(m_connectionController.get(), qOverload(&ConnectionController::connectionErrorOccurred), this,
+ [this](ErrorCode errorCode) {
+ emit m_pageController->showErrorMessage(errorCode);
+ emit m_vpnConnection->connectionStateChanged(Vpn::ConnectionState::Disconnected);
+ });
connect(m_connectionController.get(), &ConnectionController::connectButtonClicked, m_connectionController.get(),
&ConnectionController::toggleConnection, Qt::QueuedConnection);
- connect(this, &AmneziaApplication::translationsUpdated, m_connectionController.get(), &ConnectionController::onTranslationsUpdated);
-
m_pageController.reset(new PageController(m_serversModel, m_settings));
m_engine->rootContext()->setContextProperty("PageController", m_pageController.get());
- m_installController.reset(new InstallController(m_serversModel, m_containersModel, m_protocolsModel, m_clientManagementModel, m_settings));
+ m_installController.reset(new InstallController(m_serversModel, m_containersModel, m_protocolsModel, m_clientManagementModel,
+ m_apiServicesModel, m_settings));
m_engine->rootContext()->setContextProperty("InstallController", m_installController.get());
connect(m_installController.get(), &InstallController::passphraseRequestStarted, m_pageController.get(),
&PageController::showPassphraseRequestDrawer);
@@ -394,6 +409,30 @@ void AmneziaApplication::initControllers()
connect(m_installController.get(), &InstallController::currentContainerUpdated, m_connectionController.get(),
&ConnectionController::onCurrentContainerUpdated);
+ connect(m_installController.get(), &InstallController::updateServerFromApiFinished, this, [this]() {
+ disconnect(m_reloadConfigErrorOccurredConnection);
+ emit m_connectionController->configFromApiUpdated();
+ });
+
+ connect(m_connectionController.get(), &ConnectionController::updateApiConfigFromGateway, this, [this]() {
+ m_reloadConfigErrorOccurredConnection = connect(
+ m_installController.get(), qOverload(&InstallController::installationErrorOccurred), this,
+ [this]() { emit m_vpnConnection->connectionStateChanged(Vpn::ConnectionState::Disconnected); },
+ static_cast(Qt::AutoConnection || Qt::SingleShotConnection));
+ m_installController->updateServiceFromApi(m_serversModel->getDefaultServerIndex(), "", "");
+ });
+
+ connect(m_connectionController.get(), &ConnectionController::updateApiConfigFromTelegram, this, [this]() {
+ m_reloadConfigErrorOccurredConnection = connect(
+ m_installController.get(), qOverload(&InstallController::installationErrorOccurred), this,
+ [this]() { emit m_vpnConnection->connectionStateChanged(Vpn::ConnectionState::Disconnected); },
+ static_cast(Qt::AutoConnection || Qt::SingleShotConnection));
+ m_serversModel->removeApiConfig(m_serversModel->getDefaultServerIndex());
+ m_installController->updateServiceFromTelegram(m_serversModel->getDefaultServerIndex());
+ });
+
+ connect(this, &AmneziaApplication::translationsUpdated, m_connectionController.get(), &ConnectionController::onTranslationsUpdated);
+
m_importController.reset(new ImportController(m_serversModel, m_containersModel, m_settings));
m_engine->rootContext()->setContextProperty("ImportController", m_importController.get());
diff --git a/client/amnezia_application.h b/client/amnezia_application.h
index b15d55d7..6fb61f44 100644
--- a/client/amnezia_application.h
+++ b/client/amnezia_application.h
@@ -45,6 +45,8 @@
#include "ui/models/sites_model.h"
#include "ui/models/clientManagementModel.h"
#include "ui/models/appSplitTunnelingModel.h"
+#include "ui/models/apiServicesModel.h"
+#include "ui/models/apiCountryModel.h"
#define amnApp (static_cast(QCoreApplication::instance()))
@@ -103,6 +105,8 @@ private:
QSharedPointer m_sitesModel;
QSharedPointer m_appSplitTunnelingModel;
QSharedPointer m_clientManagementModel;
+ QSharedPointer m_apiServicesModel;
+ QSharedPointer m_apiCountryModel;
QScopedPointer m_openVpnConfigModel;
QScopedPointer m_shadowSocksConfigModel;
@@ -134,6 +138,8 @@ private:
QScopedPointer m_appSplitTunnelingController;
QNetworkAccessManager *m_nam;
+
+ QMetaObject::Connection m_reloadConfigErrorOccurredConnection;
};
#endif // AMNEZIA_APPLICATION_H
diff --git a/client/android/AndroidManifest.xml b/client/android/AndroidManifest.xml
index f1d2682b..c1c40b52 100644
--- a/client/android/AndroidManifest.xml
+++ b/client/android/AndroidManifest.xml
@@ -11,6 +11,9 @@
+
+
+
@@ -31,9 +34,11 @@
android:label="-- %%INSERT_APP_NAME%% --"
android:icon="@mipmap/icon"
android:roundIcon="@mipmap/icon_round"
+ android:banner="@mipmap/ic_banner"
android:theme="@style/NoActionBar"
android:fullBackupContent="@xml/backup_content"
android:dataExtractionRules="@xml/data_extraction_rules"
+ android:hasFragileUserData="false"
tools:targetApi="s">
+
diff --git a/client/android/res/mipmap-anydpi-v26/ic_banner.xml b/client/android/res/mipmap-anydpi-v26/ic_banner.xml
new file mode 100644
index 00000000..cf3108b3
--- /dev/null
+++ b/client/android/res/mipmap-anydpi-v26/ic_banner.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/client/android/res/mipmap-xhdpi/ic_banner.png b/client/android/res/mipmap-xhdpi/ic_banner.png
new file mode 100644
index 00000000..f5029b23
Binary files /dev/null and b/client/android/res/mipmap-xhdpi/ic_banner.png differ
diff --git a/client/android/res/mipmap-xhdpi/ic_banner_foreground.png b/client/android/res/mipmap-xhdpi/ic_banner_foreground.png
new file mode 100644
index 00000000..1c21902e
Binary files /dev/null and b/client/android/res/mipmap-xhdpi/ic_banner_foreground.png differ
diff --git a/client/android/res/values/ic_banner_background.xml b/client/android/res/values/ic_banner_background.xml
new file mode 100644
index 00000000..fa6f91c7
--- /dev/null
+++ b/client/android/res/values/ic_banner_background.xml
@@ -0,0 +1,4 @@
+
+
+ #1E1E1F
+
\ No newline at end of file
diff --git a/client/android/src/org/amnezia/vpn/AmneziaActivity.kt b/client/android/src/org/amnezia/vpn/AmneziaActivity.kt
index e3ed6d39..8a78750b 100644
--- a/client/android/src/org/amnezia/vpn/AmneziaActivity.kt
+++ b/client/android/src/org/amnezia/vpn/AmneziaActivity.kt
@@ -1,6 +1,7 @@
package org.amnezia.vpn
import android.Manifest
+import android.annotation.SuppressLint
import android.app.AlertDialog
import android.app.NotificationManager
import android.content.BroadcastReceiver
@@ -230,7 +231,10 @@ class AmneziaActivity : QtActivity() {
override fun onStop() {
Log.d(TAG, "Stop Amnezia activity")
doUnbindService()
- QtAndroidController.onServiceDisconnected()
+ mainScope.launch {
+ qtInitialized.await()
+ QtAndroidController.onServiceDisconnected()
+ }
super.onStop()
}
@@ -542,7 +546,7 @@ class AmneziaActivity : QtActivity() {
}
}.also {
startActivityForResult(it, OPEN_FILE_ACTION_CODE, ActivityResultHandler(
- onSuccess = {
+ onAny = {
val uri = it?.data?.toString() ?: ""
Log.d(TAG, "Open file: $uri")
mainScope.launch {
@@ -556,8 +560,12 @@ class AmneziaActivity : QtActivity() {
}
@Suppress("unused")
+ @SuppressLint("UnsupportedChromeOsCameraSystemFeature")
fun isCameraPresent(): Boolean = applicationContext.packageManager.hasSystemFeature(PackageManager.FEATURE_CAMERA)
+ @Suppress("unused")
+ fun isOnTv(): Boolean = applicationContext.packageManager.hasSystemFeature(PackageManager.FEATURE_LEANBACK)
+
@Suppress("unused")
fun startQrCodeReader() {
Log.v(TAG, "Start camera")
diff --git a/client/android/utils/src/main/kotlin/net/NetworkState.kt b/client/android/utils/src/main/kotlin/net/NetworkState.kt
index 3cff8c04..26d23215 100644
--- a/client/android/utils/src/main/kotlin/net/NetworkState.kt
+++ b/client/android/utils/src/main/kotlin/net/NetworkState.kt
@@ -88,16 +88,24 @@ class NetworkState(
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
connectivityManager.registerBestMatchingNetworkCallback(networkRequest, networkCallback, handler)
} else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
- try {
- connectivityManager.requestNetwork(networkRequest, networkCallback, handler)
- } catch (e: SecurityException) {
- Log.e(TAG, "Failed to bind network listener: $e")
- // Android 11 bug: https://issuetracker.google.com/issues/175055271
- if (e.message?.startsWith("Package android does not belong to") == true) {
- delay(1000)
+ val numberAttempts = 3
+ var attemptCount = 0
+ while(true) {
+ try {
connectivityManager.requestNetwork(networkRequest, networkCallback, handler)
- } else {
- throw e
+ break
+ } catch (e: SecurityException) {
+ Log.e(TAG, "Failed to bind network listener: $e")
+ // Android 11 bug: https://issuetracker.google.com/issues/175055271
+ if (e.message?.startsWith("Package android does not belong to") == true) {
+ if (++attemptCount > numberAttempts) {
+ throw e
+ }
+ delay(1000)
+ continue
+ } else {
+ throw e
+ }
}
}
} else {
diff --git a/client/cmake/3rdparty.cmake b/client/cmake/3rdparty.cmake
index ec544764..087f4961 100644
--- a/client/cmake/3rdparty.cmake
+++ b/client/cmake/3rdparty.cmake
@@ -8,9 +8,9 @@ endif()
add_subdirectory(${CLIENT_ROOT_DIR}/3rd/SortFilterProxyModel)
set(LIBS ${LIBS} SortFilterProxyModel)
+include(${CLIENT_ROOT_DIR}/cmake/QSimpleCrypto.cmake)
include(${CLIENT_ROOT_DIR}/3rd/qrcodegen/qrcodegen.cmake)
-include(${CLIENT_ROOT_DIR}/3rd/QSimpleCrypto/QSimpleCrypto.cmake)
set(LIBSSH_ROOT_DIR "${CLIENT_ROOT_DIR}/3rd-prebuilt/3rd-prebuilt/libssh/")
set(OPENSSL_ROOT_DIR "${CLIENT_ROOT_DIR}/3rd-prebuilt/3rd-prebuilt/openssl/")
@@ -83,13 +83,12 @@ set(BUILD_WITH_QT6 ON)
add_subdirectory(${CLIENT_ROOT_DIR}/3rd/qtkeychain)
set(LIBS ${LIBS} qt6keychain)
-
include_directories(
${OPENSSL_INCLUDE_DIR}
${LIBSSH_INCLUDE_DIR}/include
${LIBSSH_ROOT_DIR}/include
${CLIENT_ROOT_DIR}/3rd/libssh/include
- ${CLIENT_ROOT_DIR}/3rd/QSimpleCrypto/include
+ ${CLIENT_ROOT_DIR}/3rd/QSimpleCrypto/src/include
${CLIENT_ROOT_DIR}/3rd/qtkeychain/qtkeychain
${CMAKE_CURRENT_BINARY_DIR}/3rd/qtkeychain
${CMAKE_CURRENT_BINARY_DIR}/3rd/libssh/include
diff --git a/client/cmake/QSimpleCrypto.cmake b/client/cmake/QSimpleCrypto.cmake
new file mode 100644
index 00000000..ec43cb83
--- /dev/null
+++ b/client/cmake/QSimpleCrypto.cmake
@@ -0,0 +1,21 @@
+set(CLIENT_ROOT_DIR ${CMAKE_CURRENT_LIST_DIR}/..)
+set(QSIMPLECRYPTO_DIR ${CLIENT_ROOT_DIR}/3rd/QSimpleCrypto/src)
+
+include_directories(${QSIMPLECRYPTO_DIR})
+
+set(HEADERS ${HEADERS}
+ ${QSIMPLECRYPTO_DIR}/include/QAead.h
+ ${QSIMPLECRYPTO_DIR}/include/QBlockCipher.h
+ ${QSIMPLECRYPTO_DIR}/include/QRsa.h
+ ${QSIMPLECRYPTO_DIR}/include/QSimpleCrypto_global.h
+ ${QSIMPLECRYPTO_DIR}/include/QX509.h
+ ${QSIMPLECRYPTO_DIR}/include/QX509Store.h
+)
+
+set(SOURCES ${SOURCES}
+ ${QSIMPLECRYPTO_DIR}/sources/QAead.cpp
+ ${QSIMPLECRYPTO_DIR}/sources/QBlockCipher.cpp
+ ${QSIMPLECRYPTO_DIR}/sources/QRsa.cpp
+ ${QSIMPLECRYPTO_DIR}/sources/QX509.cpp
+ ${QSIMPLECRYPTO_DIR}/sources/QX509Store.cpp
+)
diff --git a/client/configurators/openvpn_configurator.cpp b/client/configurators/openvpn_configurator.cpp
index c4bdf860..fafb7c2b 100644
--- a/client/configurators/openvpn_configurator.cpp
+++ b/client/configurators/openvpn_configurator.cpp
@@ -119,18 +119,21 @@ QString OpenVpnConfigurator::processConfigWithLocalSettings(const QPairisSitesSplitTunnelingEnabled()) {
config.append("\nredirect-gateway def1 ipv6 bypass-dhcp\n");
+
+#if !defined(Q_OS_ANDROID) && !defined(Q_OS_IOS)
// Prevent ipv6 leak
config.append("ifconfig-ipv6 fd15:53b6:dead::2/64 fd15:53b6:dead::1\n");
+#endif
config.append("block-ipv6\n");
} else if (m_settings->routeMode() == Settings::VpnOnlyForwardSites) {
// no redirect-gateway
} else if (m_settings->routeMode() == Settings::VpnAllExceptSites) {
-#ifndef Q_OS_ANDROID
+#if !defined(Q_OS_ANDROID) && !defined(Q_OS_IOS)
config.append("\nredirect-gateway ipv6 !ipv4 bypass-dhcp\n");
-#endif
// Prevent ipv6 leak
config.append("ifconfig-ipv6 fd15:53b6:dead::2/64 fd15:53b6:dead::1\n");
+#endif
config.append("block-ipv6\n");
}
}
diff --git a/client/containers/containers_defs.cpp b/client/containers/containers_defs.cpp
index cdf14db8..7647c166 100644
--- a/client/containers/containers_defs.cpp
+++ b/client/containers/containers_defs.cpp
@@ -96,7 +96,7 @@ QMap ContainerProps::containerHumanNames()
{ DockerContainer::Awg, "AmneziaWG" },
{ DockerContainer::Xray, "XRay" },
{ DockerContainer::Ipsec, QObject::tr("IPsec") },
- { DockerContainer::SSXray, "ShadowSocks"},
+ { DockerContainer::SSXray, "Shadowsocks"},
{ DockerContainer::TorWebSite, QObject::tr("Website in Tor network") },
{ DockerContainer::Dns, QObject::tr("AmneziaDNS") },
diff --git a/client/core/controllers/apiController.cpp b/client/core/controllers/apiController.cpp
index 35b459be..8e5f8ed5 100644
--- a/client/core/controllers/apiController.cpp
+++ b/client/core/controllers/apiController.cpp
@@ -5,7 +5,11 @@
#include
#include
+#include "QBlockCipher.h"
+#include "QRsa.h"
+
#include "amnezia_application.h"
+#include "core/enums/apiEnums.h"
#include "configurators/wireguard_configurator.h"
#include "version.h"
@@ -25,25 +29,74 @@ namespace
constexpr char uuid[] = "installation_uuid";
constexpr char osVersion[] = "os_version";
constexpr char appVersion[] = "app_version";
+
+ constexpr char userCountryCode[] = "user_country_code";
+ constexpr char serverCountryCode[] = "server_country_code";
+ constexpr char serviceType[] = "service_type";
+
+ constexpr char aesKey[] = "aes_key";
+ constexpr char aesIv[] = "aes_iv";
+ constexpr char aesSalt[] = "aes_salt";
+
+ constexpr char apiPayload[] = "api_payload";
+ constexpr char keyPayload[] = "key_payload";
+ }
+
+ const QStringList proxyStorageUrl = {""};
+
+ ErrorCode checkErrors(const QList &sslErrors, QNetworkReply *reply)
+ {
+ if (!sslErrors.empty()) {
+ qDebug().noquote() << sslErrors;
+ return ErrorCode::ApiConfigSslError;
+ } else if (reply->error() == QNetworkReply::NoError) {
+ return ErrorCode::NoError;
+ } else if (reply->error() == QNetworkReply::NetworkError::OperationCanceledError
+ || reply->error() == QNetworkReply::NetworkError::TimeoutError) {
+ return ErrorCode::ApiConfigTimeoutError;
+ } else {
+ QString err = reply->errorString();
+ qDebug() << QString::fromUtf8(reply->readAll());
+ qDebug() << reply->error();
+ qDebug() << err;
+ qDebug() << reply->attribute(QNetworkRequest::HttpStatusCodeAttribute);
+ return ErrorCode::ApiConfigDownloadError;
+ }
}
}
-ApiController::ApiController(QObject *parent) : QObject(parent)
+ApiController::ApiController(const QString &gatewayEndpoint, QObject *parent) : QObject(parent), m_gatewayEndpoint(gatewayEndpoint)
{
}
-void ApiController::processApiConfig(const QString &protocol, const ApiController::ApiPayloadData &apiPayloadData, QString &config)
+void ApiController::fillServerConfig(const QString &protocol, const ApiController::ApiPayloadData &apiPayloadData,
+ const QByteArray &apiResponseBody, QJsonObject &serverConfig)
{
- if (protocol == configKey::cloak) {
- config.replace("", "\n");
- config.replace("$OPENVPN_PRIV_KEY", apiPayloadData.certRequest.privKey);
+ QString data = QJsonDocument::fromJson(apiResponseBody).object().value(config_key::config).toString();
+
+ data.replace("vpn://", "");
+ QByteArray ba = QByteArray::fromBase64(data.toUtf8(), QByteArray::Base64UrlEncoding | QByteArray::OmitTrailingEquals);
+
+ if (ba.isEmpty()) {
+ emit errorOccurred(ErrorCode::ApiConfigEmptyError);
return;
+ }
+
+ QByteArray ba_uncompressed = qUncompress(ba);
+ if (!ba_uncompressed.isEmpty()) {
+ ba = ba_uncompressed;
+ }
+
+ QString configStr = ba;
+ if (protocol == configKey::cloak) {
+ configStr.replace("", "\n");
+ configStr.replace("$OPENVPN_PRIV_KEY", apiPayloadData.certRequest.privKey);
} else if (protocol == configKey::awg) {
- config.replace("$WIREGUARD_CLIENT_PRIVATE_KEY", apiPayloadData.wireGuardClientPrivKey);
- auto serverConfig = QJsonDocument::fromJson(config.toUtf8()).object();
+ configStr.replace("$WIREGUARD_CLIENT_PRIVATE_KEY", apiPayloadData.wireGuardClientPrivKey);
+ auto serverConfig = QJsonDocument::fromJson(configStr.toUtf8()).object();
auto containers = serverConfig.value(config_key::containers).toArray();
if (containers.isEmpty()) {
- return;
+ return; // todo process error
}
auto container = containers.at(0).toObject();
QString containerName = ContainerProps::containerTypeToString(DockerContainer::Awg);
@@ -61,11 +114,75 @@ void ApiController::processApiConfig(const QString &protocol, const ApiControlle
container[containerName] = containerConfig;
containers.replace(0, container);
serverConfig[config_key::containers] = containers;
- config = QString(QJsonDocument(serverConfig).toJson());
+ configStr = QString(QJsonDocument(serverConfig).toJson());
}
+
+ QJsonObject apiConfig = QJsonDocument::fromJson(configStr.toUtf8()).object();
+ serverConfig[config_key::dns1] = apiConfig.value(config_key::dns1);
+ serverConfig[config_key::dns2] = apiConfig.value(config_key::dns2);
+ serverConfig[config_key::containers] = apiConfig.value(config_key::containers);
+ serverConfig[config_key::hostName] = apiConfig.value(config_key::hostName);
+
+ if (apiConfig.value(config_key::configVersion).toInt() == ApiConfigSources::AmneziaGateway) {
+ serverConfig[config_key::configVersion] = apiConfig.value(config_key::configVersion);
+ serverConfig[config_key::description] = apiConfig.value(config_key::description);
+ serverConfig[config_key::name] = apiConfig.value(config_key::name);
+ }
+
+ auto defaultContainer = apiConfig.value(config_key::defaultContainer).toString();
+ serverConfig[config_key::defaultContainer] = defaultContainer;
+
return;
}
+QStringList ApiController::getProxyUrls()
+{
+ QNetworkRequest request;
+ request.setTransferTimeout(7000);
+ request.setHeader(QNetworkRequest::ContentTypeHeader, "application/json");
+
+ QEventLoop wait;
+ QList sslErrors;
+ QNetworkReply* reply;
+
+ for (const auto &proxyStorageUrl : proxyStorageUrl) {
+ request.setUrl(proxyStorageUrl);
+ reply = amnApp->manager()->get(request);
+
+ connect(reply, &QNetworkReply::finished, &wait, &QEventLoop::quit);
+ connect(reply, &QNetworkReply::sslErrors, [this, &sslErrors](const QList &errors) { sslErrors = errors; });
+ wait.exec();
+
+ if (reply->error() == QNetworkReply::NetworkError::NoError) {
+ break;
+ }
+ reply->deleteLater();
+ }
+
+ auto encryptedResponseBody = reply->readAll();
+ reply->deleteLater();
+
+ EVP_PKEY *privateKey = nullptr;
+ QByteArray responseBody;
+ try {
+ QByteArray key = PROD_PROXY_STORAGE_KEY;
+ QSimpleCrypto::QRsa rsa;
+ privateKey = rsa.getPrivateKeyFromByteArray(key, "");
+ responseBody = rsa.decrypt(encryptedResponseBody, privateKey, RSA_PKCS1_PADDING);
+ } catch (...) {
+ qCritical() << "error loading private key from environment variables or decrypting payload";
+ return {};
+ }
+
+ auto endpointsArray = QJsonDocument::fromJson(responseBody).array();
+
+ QStringList endpoints;
+ for (const auto &endpoint : endpointsArray) {
+ endpoints.push_back(endpoint.toString());
+ }
+ return endpoints;
+}
+
ApiController::ApiPayloadData ApiController::generateApiPayloadData(const QString &protocol)
{
ApiController::ApiPayloadData apiPayload;
@@ -101,8 +218,6 @@ void ApiController::updateServerConfigFromApi(const QString &installationUuid, c
QThread::msleep(10);
#endif
- auto containerConfig = serverConfig.value(config_key::containers).toArray();
-
if (serverConfig.value(config_key::configVersion).toInt()) {
QNetworkRequest request;
request.setTransferTimeout(7000);
@@ -120,39 +235,13 @@ void ApiController::updateServerConfigFromApi(const QString &installationUuid, c
QByteArray requestBody = QJsonDocument(apiPayload).toJson();
- QNetworkReply *reply = amnApp->manager()->post(request, requestBody); // ??
+ QNetworkReply *reply = amnApp->manager()->post(request, requestBody);
QObject::connect(reply, &QNetworkReply::finished, [this, reply, protocol, apiPayloadData, serverIndex, serverConfig]() mutable {
if (reply->error() == QNetworkReply::NoError) {
- QString contents = QString::fromUtf8(reply->readAll());
- QString data = QJsonDocument::fromJson(contents.toUtf8()).object().value(config_key::config).toString();
-
- data.replace("vpn://", "");
- QByteArray ba = QByteArray::fromBase64(data.toUtf8(), QByteArray::Base64UrlEncoding | QByteArray::OmitTrailingEquals);
-
- if (ba.isEmpty()) {
- emit errorOccurred(ErrorCode::ApiConfigEmptyError);
- return;
- }
-
- QByteArray ba_uncompressed = qUncompress(ba);
- if (!ba_uncompressed.isEmpty()) {
- ba = ba_uncompressed;
- }
-
- QString configStr = ba;
- processApiConfig(protocol, apiPayloadData, configStr);
-
- QJsonObject apiConfig = QJsonDocument::fromJson(configStr.toUtf8()).object();
- serverConfig[config_key::dns1] = apiConfig.value(config_key::dns1);
- serverConfig[config_key::dns2] = apiConfig.value(config_key::dns2);
- serverConfig[config_key::containers] = apiConfig.value(config_key::containers);
- serverConfig[config_key::hostName] = apiConfig.value(config_key::hostName);
-
- auto defaultContainer = apiConfig.value(config_key::defaultContainer).toString();
- serverConfig[config_key::defaultContainer] = defaultContainer;
-
- emit configUpdated(true, serverConfig, serverIndex);
+ auto apiResponseBody = reply->readAll();
+ fillServerConfig(protocol, apiPayloadData, apiResponseBody, serverConfig);
+ emit finished(serverConfig, serverIndex);
} else {
if (reply->error() == QNetworkReply::NetworkError::OperationCanceledError
|| reply->error() == QNetworkReply::NetworkError::TimeoutError) {
@@ -178,3 +267,154 @@ void ApiController::updateServerConfigFromApi(const QString &installationUuid, c
});
}
}
+
+ErrorCode ApiController::getServicesList(QByteArray &responseBody)
+{
+#ifdef Q_OS_IOS
+ IosController::Instance()->requestInetAccess();
+ QThread::msleep(10);
+#endif
+
+ QNetworkRequest request;
+ request.setTransferTimeout(7000);
+ request.setHeader(QNetworkRequest::ContentTypeHeader, "application/json");
+
+ request.setUrl(QString("%1v1/services").arg(m_gatewayEndpoint));
+
+ QNetworkReply* reply;
+ reply = amnApp->manager()->get(request);
+
+ QEventLoop wait;
+ QObject::connect(reply, &QNetworkReply::finished, &wait, &QEventLoop::quit);
+
+ QList sslErrors;
+ connect(reply, &QNetworkReply::sslErrors, [this, &sslErrors](const QList &errors) { sslErrors = errors; });
+ wait.exec();
+
+ if (reply->error() == QNetworkReply::NetworkError::TimeoutError || reply->error() == QNetworkReply::NetworkError::OperationCanceledError) {
+ m_proxyUrls = getProxyUrls();
+ for (const QString &proxyUrl : m_proxyUrls) {
+ request.setUrl(QString("%1v1/services").arg(proxyUrl));
+ reply = amnApp->manager()->get(request);
+
+ QObject::connect(reply, &QNetworkReply::finished, &wait, &QEventLoop::quit);
+ connect(reply, &QNetworkReply::sslErrors, [this, &sslErrors](const QList &errors) { sslErrors = errors; });
+ wait.exec();
+ if (reply->error() != QNetworkReply::NetworkError::TimeoutError && reply->error() != QNetworkReply::NetworkError::OperationCanceledError) {
+ break;
+ }
+ reply->deleteLater();
+ }
+ }
+
+ responseBody = reply->readAll();
+ auto errorCode = checkErrors(sslErrors, reply);
+ reply->deleteLater();
+ return errorCode;
+}
+
+ErrorCode ApiController::getConfigForService(const QString &installationUuid, const QString &userCountryCode, const QString &serviceType,
+ const QString &protocol, const QString &serverCountryCode, QJsonObject &serverConfig)
+{
+#ifdef Q_OS_IOS
+ IosController::Instance()->requestInetAccess();
+ QThread::msleep(10);
+#endif
+
+ QNetworkAccessManager manager;
+ QNetworkRequest request;
+ request.setTransferTimeout(7000);
+ request.setHeader(QNetworkRequest::ContentTypeHeader, "application/json");
+
+ request.setUrl(QString("%1v1/config").arg(m_gatewayEndpoint));
+
+ ApiPayloadData apiPayloadData = generateApiPayloadData(protocol);
+
+ QJsonObject apiPayload = fillApiPayload(protocol, apiPayloadData);
+ apiPayload[configKey::userCountryCode] = userCountryCode;
+ if (!serverCountryCode.isEmpty()) {
+ apiPayload[configKey::serverCountryCode] = serverCountryCode;
+ }
+ apiPayload[configKey::serviceType] = serviceType;
+ apiPayload[configKey::uuid] = installationUuid;
+
+ QSimpleCrypto::QBlockCipher blockCipher;
+ QByteArray key = blockCipher.generatePrivateSalt(32);
+ QByteArray iv = blockCipher.generatePrivateSalt(32);
+ QByteArray salt = blockCipher.generatePrivateSalt(8);
+
+ QJsonObject keyPayload;
+ keyPayload[configKey::aesKey] = QString(key.toBase64());
+ keyPayload[configKey::aesIv] = QString(iv.toBase64());
+ keyPayload[configKey::aesSalt] = QString(salt.toBase64());
+
+ QByteArray encryptedKeyPayload;
+ QByteArray encryptedApiPayload;
+ try {
+ QSimpleCrypto::QRsa rsa;
+
+ EVP_PKEY *publicKey = nullptr;
+ try {
+ QByteArray key = PROD_AGW_PUBLIC_KEY;
+ QSimpleCrypto::QRsa rsa;
+ publicKey = rsa.getPublicKeyFromByteArray(key);
+ } catch (...) {
+ qCritical() << "error loading public key from environment variables";
+ return ErrorCode::ApiMissingAgwPublicKey;
+ }
+
+ encryptedKeyPayload = rsa.encrypt(QJsonDocument(keyPayload).toJson(), publicKey, RSA_PKCS1_PADDING);
+ EVP_PKEY_free(publicKey);
+
+ encryptedApiPayload = blockCipher.encryptAesBlockCipher(QJsonDocument(apiPayload).toJson(), key, iv, "", salt);
+ } catch (...) { // todo change error handling in QSimpleCrypto?
+ qCritical() << "error when encrypting the request body";
+ }
+
+ QJsonObject requestBody;
+ requestBody[configKey::keyPayload] = QString(encryptedKeyPayload.toBase64());
+ requestBody[configKey::apiPayload] = QString(encryptedApiPayload.toBase64());
+
+ QNetworkReply* reply = manager.post(request, QJsonDocument(requestBody).toJson());
+
+ QEventLoop wait;
+ connect(reply, &QNetworkReply::finished, &wait, &QEventLoop::quit);
+
+ QList sslErrors;
+ connect(reply, &QNetworkReply::sslErrors, [this, &sslErrors](const QList &errors) { sslErrors = errors; });
+ wait.exec();
+
+ if (reply->error() == QNetworkReply::NetworkError::TimeoutError || reply->error() == QNetworkReply::NetworkError::OperationCanceledError) {
+ if (m_proxyUrls.isEmpty()) {
+ m_proxyUrls = getProxyUrls();
+ }
+ for (const QString &proxyUrl : m_proxyUrls) {
+ request.setUrl(QString("%1v1/config").arg(proxyUrl));
+ reply = manager.post(request, QJsonDocument(requestBody).toJson());
+
+ QObject::connect(reply, &QNetworkReply::finished, &wait, &QEventLoop::quit);
+ connect(reply, &QNetworkReply::sslErrors, [this, &sslErrors](const QList &errors) { sslErrors = errors; });
+ wait.exec();
+ if (reply->error() != QNetworkReply::NetworkError::TimeoutError && reply->error() != QNetworkReply::NetworkError::OperationCanceledError) {
+ break;
+ }
+ reply->deleteLater();
+ }
+ }
+
+ auto errorCode = checkErrors(sslErrors, reply);
+ if (errorCode) {
+ return errorCode;
+ }
+
+ auto encryptedResponseBody = reply->readAll();
+ reply->deleteLater();
+ try {
+ auto responseBody = blockCipher.decryptAesBlockCipher(encryptedResponseBody, key, iv, "", salt);
+ fillServerConfig(protocol, apiPayloadData, responseBody, serverConfig);
+ } catch (...) { // todo change error handling in QSimpleCrypto?
+ qCritical() << "error when decrypting the request body";
+ }
+
+ return errorCode;
+}
diff --git a/client/core/controllers/apiController.h b/client/core/controllers/apiController.h
index cc5d9f31..6cfde983 100644
--- a/client/core/controllers/apiController.h
+++ b/client/core/controllers/apiController.h
@@ -14,14 +14,18 @@ class ApiController : public QObject
Q_OBJECT
public:
- explicit ApiController(QObject *parent = nullptr);
+ explicit ApiController(const QString &gatewayEndpoint, QObject *parent = nullptr);
public slots:
void updateServerConfigFromApi(const QString &installationUuid, const int serverIndex, QJsonObject serverConfig);
+ ErrorCode getServicesList(QByteArray &responseBody);
+ ErrorCode getConfigForService(const QString &installationUuid, const QString &userCountryCode, const QString &serviceType,
+ const QString &protocol, const QString &serverCountryCode, QJsonObject &serverConfig);
+
signals:
void errorOccurred(ErrorCode errorCode);
- void configUpdated(const bool updateConfig, const QJsonObject &config, const int serverIndex);
+ void finished(const QJsonObject &config, const int serverIndex);
private:
struct ApiPayloadData
@@ -34,7 +38,12 @@ private:
ApiPayloadData generateApiPayloadData(const QString &protocol);
QJsonObject fillApiPayload(const QString &protocol, const ApiController::ApiPayloadData &apiPayloadData);
- void processApiConfig(const QString &protocol, const ApiController::ApiPayloadData &apiPayloadData, QString &config);
+ void fillServerConfig(const QString &protocol, const ApiController::ApiPayloadData &apiPayloadData, const QByteArray &apiResponseBody,
+ QJsonObject &serverConfig);
+ QStringList getProxyUrls();
+
+ QString m_gatewayEndpoint;
+ QStringList m_proxyUrls;
};
#endif // APICONTROLLER_H
diff --git a/client/core/controllers/serverController.cpp b/client/core/controllers/serverController.cpp
index 11efb57a..233d66d4 100644
--- a/client/core/controllers/serverController.cpp
+++ b/client/core/controllers/serverController.cpp
@@ -569,6 +569,7 @@ ServerController::Vars ServerController::genVarsForScript(const ServerCredential
// Xray vars
vars.append({ { "$XRAY_SITE_NAME", xrayConfig.value(config_key::site).toString(protocols::xray::defaultSite) } });
+ vars.append({ { "$XRAY_SERVER_PORT", xrayConfig.value(config_key::port).toString(protocols::xray::defaultPort) } });
// Wireguard vars
vars.append({ { "$WIREGUARD_SUBNET_IP",
diff --git a/client/core/defs.h b/client/core/defs.h
index a441ee1c..ebc07f4b 100644
--- a/client/core/defs.h
+++ b/client/core/defs.h
@@ -106,6 +106,7 @@ namespace amnezia
ApiConfigEmptyError = 1102,
ApiConfigTimeoutError = 1103,
ApiConfigSslError = 1104,
+ ApiMissingAgwPublicKey = 1105,
// QFile errors
OpenError = 1200,
diff --git a/client/core/enums/apiEnums.h b/client/core/enums/apiEnums.h
new file mode 100644
index 00000000..1f050007
--- /dev/null
+++ b/client/core/enums/apiEnums.h
@@ -0,0 +1,9 @@
+#ifndef APIENUMS_H
+#define APIENUMS_H
+
+enum ApiConfigSources {
+ Telegram = 1,
+ AmneziaGateway
+};
+
+#endif // APIENUMS_H
diff --git a/client/core/errorstrings.cpp b/client/core/errorstrings.cpp
index 645ec6c5..8c16d786 100644
--- a/client/core/errorstrings.cpp
+++ b/client/core/errorstrings.cpp
@@ -60,6 +60,7 @@ QString errorString(ErrorCode code) {
case (ErrorCode::ApiConfigEmptyError): errorMessage = QObject::tr("In the response from the server, an empty config was received"); break;
case (ErrorCode::ApiConfigSslError): errorMessage = QObject::tr("SSL error occurred"); break;
case (ErrorCode::ApiConfigTimeoutError): errorMessage = QObject::tr("Server response timeout on api request"); break;
+ case (ErrorCode::ApiMissingAgwPublicKey): errorMessage = QObject::tr("Missing AGW public key"); break;
// QFile errors
case(ErrorCode::OpenError): errorMessage = QObject::tr("QFile error: The file could not be opened"); break;
diff --git a/client/images/amneziaBigLogo.svg b/client/images/amneziaBigLogo.svg
deleted file mode 100644
index c50c7743..00000000
--- a/client/images/amneziaBigLogo.svg
+++ /dev/null
@@ -1 +0,0 @@
-
\ No newline at end of file
diff --git a/client/images/animation.gif b/client/images/animation.gif
deleted file mode 100644
index 6f7f38e8..00000000
Binary files a/client/images/animation.gif and /dev/null differ
diff --git a/client/images/arrow_left.png b/client/images/arrow_left.png
deleted file mode 100644
index 3a4d149d..00000000
Binary files a/client/images/arrow_left.png and /dev/null differ
diff --git a/client/images/background_connected.png b/client/images/background_connected.png
deleted file mode 100644
index 62480d5f..00000000
Binary files a/client/images/background_connected.png and /dev/null differ
diff --git a/client/images/background_connected@2x.png b/client/images/background_connected@2x.png
deleted file mode 100644
index 4f76b956..00000000
Binary files a/client/images/background_connected@2x.png and /dev/null differ
diff --git a/client/images/check.png b/client/images/check.png
deleted file mode 100644
index 43039eb1..00000000
Binary files a/client/images/check.png and /dev/null differ
diff --git a/client/images/close.png b/client/images/close.png
deleted file mode 100644
index 072232c1..00000000
Binary files a/client/images/close.png and /dev/null differ
diff --git a/client/images/connected.png b/client/images/connected.png
deleted file mode 100644
index b3c907c8..00000000
Binary files a/client/images/connected.png and /dev/null differ
diff --git a/client/images/connectionOff.svg b/client/images/connectionOff.svg
deleted file mode 100644
index 27905ff9..00000000
--- a/client/images/connectionOff.svg
+++ /dev/null
@@ -1,18 +0,0 @@
-
diff --git a/client/images/connectionOn.svg b/client/images/connectionOn.svg
deleted file mode 100644
index ef317622..00000000
--- a/client/images/connectionOn.svg
+++ /dev/null
@@ -1,17 +0,0 @@
-
diff --git a/client/images/connectionProgress.svg b/client/images/connectionProgress.svg
deleted file mode 100644
index 8c4024c9..00000000
--- a/client/images/connectionProgress.svg
+++ /dev/null
@@ -1,30 +0,0 @@
-
diff --git a/client/images/controls/archive-restore.svg b/client/images/controls/archive-restore.svg
new file mode 100644
index 00000000..d3ad8c9e
--- /dev/null
+++ b/client/images/controls/archive-restore.svg
@@ -0,0 +1,7 @@
+
diff --git a/client/images/controls/bug.svg b/client/images/controls/bug.svg
new file mode 100644
index 00000000..80fd2277
--- /dev/null
+++ b/client/images/controls/bug.svg
@@ -0,0 +1,11 @@
+
diff --git a/client/images/controls/folder-search-2.svg b/client/images/controls/folder-search-2.svg
new file mode 100644
index 00000000..f77ce57d
--- /dev/null
+++ b/client/images/controls/folder-search-2.svg
@@ -0,0 +1,5 @@
+
diff --git a/client/images/controls/gauge.svg b/client/images/controls/gauge.svg
new file mode 100644
index 00000000..4b9c1444
--- /dev/null
+++ b/client/images/controls/gauge.svg
@@ -0,0 +1,4 @@
+
diff --git a/client/images/controls/help-circle.svg b/client/images/controls/help-circle.svg
new file mode 100644
index 00000000..7bcd4450
--- /dev/null
+++ b/client/images/controls/help-circle.svg
@@ -0,0 +1,5 @@
+
diff --git a/client/images/controls/history.svg b/client/images/controls/history.svg
new file mode 100644
index 00000000..73beb8b3
--- /dev/null
+++ b/client/images/controls/history.svg
@@ -0,0 +1,5 @@
+
diff --git a/client/images/controls/info.svg b/client/images/controls/info.svg
new file mode 100644
index 00000000..43a40245
--- /dev/null
+++ b/client/images/controls/info.svg
@@ -0,0 +1,5 @@
+
diff --git a/client/images/controls/map-pin.svg b/client/images/controls/map-pin.svg
new file mode 100644
index 00000000..64b75b48
--- /dev/null
+++ b/client/images/controls/map-pin.svg
@@ -0,0 +1,4 @@
+
diff --git a/client/images/controls/refresh-cw.svg b/client/images/controls/refresh-cw.svg
new file mode 100644
index 00000000..9572e3e2
--- /dev/null
+++ b/client/images/controls/refresh-cw.svg
@@ -0,0 +1,6 @@
+
diff --git a/client/images/controls/scan-line.svg b/client/images/controls/scan-line.svg
new file mode 100644
index 00000000..be4acc2a
--- /dev/null
+++ b/client/images/controls/scan-line.svg
@@ -0,0 +1,7 @@
+
diff --git a/client/images/controls/tag.svg b/client/images/controls/tag.svg
new file mode 100644
index 00000000..88a9db8d
--- /dev/null
+++ b/client/images/controls/tag.svg
@@ -0,0 +1,4 @@
+
diff --git a/client/images/delete.png b/client/images/delete.png
deleted file mode 100644
index 59687bd2..00000000
Binary files a/client/images/delete.png and /dev/null differ
diff --git a/client/images/disconnected.png b/client/images/disconnected.png
deleted file mode 100644
index 199f71dc..00000000
Binary files a/client/images/disconnected.png and /dev/null differ
diff --git a/client/images/download.png b/client/images/download.png
deleted file mode 100644
index 0e949133..00000000
Binary files a/client/images/download.png and /dev/null differ
diff --git a/client/images/favorites_disabled.png b/client/images/favorites_disabled.png
deleted file mode 100644
index 12a821ac..00000000
Binary files a/client/images/favorites_disabled.png and /dev/null differ
diff --git a/client/images/favorites_enabled.png b/client/images/favorites_enabled.png
deleted file mode 100644
index 61e28f42..00000000
Binary files a/client/images/favorites_enabled.png and /dev/null differ
diff --git a/client/images/favorites_hover.png b/client/images/favorites_hover.png
deleted file mode 100644
index 71e7a1b2..00000000
Binary files a/client/images/favorites_hover.png and /dev/null differ
diff --git a/client/images/flagKit/AD.svg b/client/images/flagKit/AD.svg
new file mode 100644
index 00000000..4855f9fb
--- /dev/null
+++ b/client/images/flagKit/AD.svg
@@ -0,0 +1,35 @@
+
+
\ No newline at end of file
diff --git a/client/images/flagKit/AE.svg b/client/images/flagKit/AE.svg
new file mode 100644
index 00000000..3095fe31
--- /dev/null
+++ b/client/images/flagKit/AE.svg
@@ -0,0 +1,33 @@
+
+
\ No newline at end of file
diff --git a/client/images/flagKit/AF.svg b/client/images/flagKit/AF.svg
new file mode 100644
index 00000000..75216b74
--- /dev/null
+++ b/client/images/flagKit/AF.svg
@@ -0,0 +1,34 @@
+
+
\ No newline at end of file
diff --git a/client/images/flagKit/AG.svg b/client/images/flagKit/AG.svg
new file mode 100644
index 00000000..ac56b808
--- /dev/null
+++ b/client/images/flagKit/AG.svg
@@ -0,0 +1,44 @@
+
+
\ No newline at end of file
diff --git a/client/images/flagKit/AI.svg b/client/images/flagKit/AI.svg
new file mode 100644
index 00000000..7f53e464
--- /dev/null
+++ b/client/images/flagKit/AI.svg
@@ -0,0 +1,50 @@
+
+
\ No newline at end of file
diff --git a/client/images/flagKit/AL.svg b/client/images/flagKit/AL.svg
new file mode 100644
index 00000000..43ff1a3b
--- /dev/null
+++ b/client/images/flagKit/AL.svg
@@ -0,0 +1,27 @@
+
+
\ No newline at end of file
diff --git a/client/images/flagKit/AM.svg b/client/images/flagKit/AM.svg
new file mode 100644
index 00000000..5224d30f
--- /dev/null
+++ b/client/images/flagKit/AM.svg
@@ -0,0 +1,32 @@
+
+
\ No newline at end of file
diff --git a/client/images/flagKit/AO.svg b/client/images/flagKit/AO.svg
new file mode 100644
index 00000000..86044f3b
--- /dev/null
+++ b/client/images/flagKit/AO.svg
@@ -0,0 +1,37 @@
+
+
\ No newline at end of file
diff --git a/client/images/flagKit/AR.svg b/client/images/flagKit/AR.svg
new file mode 100644
index 00000000..4dbc96f1
--- /dev/null
+++ b/client/images/flagKit/AR.svg
@@ -0,0 +1,26 @@
+
+
\ No newline at end of file
diff --git a/client/images/flagKit/AS.svg b/client/images/flagKit/AS.svg
new file mode 100644
index 00000000..afb37540
--- /dev/null
+++ b/client/images/flagKit/AS.svg
@@ -0,0 +1,36 @@
+
+
\ No newline at end of file
diff --git a/client/images/flagKit/AT.svg b/client/images/flagKit/AT.svg
new file mode 100644
index 00000000..627245e3
--- /dev/null
+++ b/client/images/flagKit/AT.svg
@@ -0,0 +1,24 @@
+
+
\ No newline at end of file
diff --git a/client/images/flagKit/AU.svg b/client/images/flagKit/AU.svg
new file mode 100644
index 00000000..aad6b1e6
--- /dev/null
+++ b/client/images/flagKit/AU.svg
@@ -0,0 +1,36 @@
+
+
\ No newline at end of file
diff --git a/client/images/flagKit/AW.svg b/client/images/flagKit/AW.svg
new file mode 100644
index 00000000..892d8aa0
--- /dev/null
+++ b/client/images/flagKit/AW.svg
@@ -0,0 +1,30 @@
+
+
\ No newline at end of file
diff --git a/client/images/flagKit/AX.svg b/client/images/flagKit/AX.svg
new file mode 100644
index 00000000..577cd268
--- /dev/null
+++ b/client/images/flagKit/AX.svg
@@ -0,0 +1,32 @@
+
+
\ No newline at end of file
diff --git a/client/images/flagKit/AZ.svg b/client/images/flagKit/AZ.svg
new file mode 100644
index 00000000..3f082f33
--- /dev/null
+++ b/client/images/flagKit/AZ.svg
@@ -0,0 +1,33 @@
+
+
\ No newline at end of file
diff --git a/client/images/flagKit/BA.svg b/client/images/flagKit/BA.svg
new file mode 100644
index 00000000..a16324e1
--- /dev/null
+++ b/client/images/flagKit/BA.svg
@@ -0,0 +1,32 @@
+
+
\ No newline at end of file
diff --git a/client/images/flagKit/BB.svg b/client/images/flagKit/BB.svg
new file mode 100644
index 00000000..5c89e132
--- /dev/null
+++ b/client/images/flagKit/BB.svg
@@ -0,0 +1,38 @@
+
+
\ No newline at end of file
diff --git a/client/images/flagKit/BD.svg b/client/images/flagKit/BD.svg
new file mode 100644
index 00000000..e1a3cd31
--- /dev/null
+++ b/client/images/flagKit/BD.svg
@@ -0,0 +1,27 @@
+
+
\ No newline at end of file
diff --git a/client/images/flagKit/BE.svg b/client/images/flagKit/BE.svg
new file mode 100644
index 00000000..ac00173d
--- /dev/null
+++ b/client/images/flagKit/BE.svg
@@ -0,0 +1,32 @@
+
+
\ No newline at end of file
diff --git a/client/images/flagKit/BF.svg b/client/images/flagKit/BF.svg
new file mode 100644
index 00000000..5b4286bb
--- /dev/null
+++ b/client/images/flagKit/BF.svg
@@ -0,0 +1,28 @@
+
+
\ No newline at end of file
diff --git a/client/images/flagKit/BG.svg b/client/images/flagKit/BG.svg
new file mode 100644
index 00000000..e8256f47
--- /dev/null
+++ b/client/images/flagKit/BG.svg
@@ -0,0 +1,28 @@
+
+
\ No newline at end of file
diff --git a/client/images/flagKit/BH.svg b/client/images/flagKit/BH.svg
new file mode 100644
index 00000000..e1c11093
--- /dev/null
+++ b/client/images/flagKit/BH.svg
@@ -0,0 +1,23 @@
+
+
\ No newline at end of file
diff --git a/client/images/flagKit/BI.svg b/client/images/flagKit/BI.svg
new file mode 100644
index 00000000..2f208253
--- /dev/null
+++ b/client/images/flagKit/BI.svg
@@ -0,0 +1,36 @@
+
+
\ No newline at end of file
diff --git a/client/images/flagKit/BJ.svg b/client/images/flagKit/BJ.svg
new file mode 100644
index 00000000..b21c46e0
--- /dev/null
+++ b/client/images/flagKit/BJ.svg
@@ -0,0 +1,32 @@
+
+
\ No newline at end of file
diff --git a/client/images/flagKit/BL.svg b/client/images/flagKit/BL.svg
new file mode 100644
index 00000000..b99bc2c7
--- /dev/null
+++ b/client/images/flagKit/BL.svg
@@ -0,0 +1,42 @@
+
+
\ No newline at end of file
diff --git a/client/images/flagKit/BM.svg b/client/images/flagKit/BM.svg
new file mode 100644
index 00000000..798dd8b9
--- /dev/null
+++ b/client/images/flagKit/BM.svg
@@ -0,0 +1,49 @@
+
+
\ No newline at end of file
diff --git a/client/images/flagKit/BN.svg b/client/images/flagKit/BN.svg
new file mode 100644
index 00000000..1fe9afc4
--- /dev/null
+++ b/client/images/flagKit/BN.svg
@@ -0,0 +1,28 @@
+
+
\ No newline at end of file
diff --git a/client/images/flagKit/BO.svg b/client/images/flagKit/BO.svg
new file mode 100644
index 00000000..7ee247bd
--- /dev/null
+++ b/client/images/flagKit/BO.svg
@@ -0,0 +1,32 @@
+
+
\ No newline at end of file
diff --git a/client/images/flagKit/BR.svg b/client/images/flagKit/BR.svg
new file mode 100644
index 00000000..17edb103
--- /dev/null
+++ b/client/images/flagKit/BR.svg
@@ -0,0 +1,35 @@
+
+
\ No newline at end of file
diff --git a/client/images/flagKit/BS.svg b/client/images/flagKit/BS.svg
new file mode 100644
index 00000000..767423af
--- /dev/null
+++ b/client/images/flagKit/BS.svg
@@ -0,0 +1,33 @@
+
+
\ No newline at end of file
diff --git a/client/images/flagKit/BT.svg b/client/images/flagKit/BT.svg
new file mode 100644
index 00000000..d2f749bd
--- /dev/null
+++ b/client/images/flagKit/BT.svg
@@ -0,0 +1,27 @@
+
+
\ No newline at end of file
diff --git a/client/images/flagKit/BV.svg b/client/images/flagKit/BV.svg
new file mode 100644
index 00000000..00a47ee5
--- /dev/null
+++ b/client/images/flagKit/BV.svg
@@ -0,0 +1,28 @@
+
+
\ No newline at end of file
diff --git a/client/images/flagKit/BW.svg b/client/images/flagKit/BW.svg
new file mode 100644
index 00000000..ccac652b
--- /dev/null
+++ b/client/images/flagKit/BW.svg
@@ -0,0 +1,29 @@
+
+
\ No newline at end of file
diff --git a/client/images/flagKit/BY.svg b/client/images/flagKit/BY.svg
new file mode 100644
index 00000000..d584988d
--- /dev/null
+++ b/client/images/flagKit/BY.svg
@@ -0,0 +1,30 @@
+
+
\ No newline at end of file
diff --git a/client/images/flagKit/BZ.svg b/client/images/flagKit/BZ.svg
new file mode 100644
index 00000000..8758df23
--- /dev/null
+++ b/client/images/flagKit/BZ.svg
@@ -0,0 +1,30 @@
+
+
\ No newline at end of file
diff --git a/client/images/flagKit/CA.svg b/client/images/flagKit/CA.svg
new file mode 100644
index 00000000..786b609b
--- /dev/null
+++ b/client/images/flagKit/CA.svg
@@ -0,0 +1,25 @@
+
+
\ No newline at end of file
diff --git a/client/images/flagKit/CC.svg b/client/images/flagKit/CC.svg
new file mode 100644
index 00000000..b96f3016
--- /dev/null
+++ b/client/images/flagKit/CC.svg
@@ -0,0 +1,33 @@
+
+
\ No newline at end of file
diff --git a/client/images/flagKit/CD.svg b/client/images/flagKit/CD.svg
new file mode 100644
index 00000000..0d351c30
--- /dev/null
+++ b/client/images/flagKit/CD.svg
@@ -0,0 +1,31 @@
+
+
\ No newline at end of file
diff --git a/client/images/flagKit/CF.svg b/client/images/flagKit/CF.svg
new file mode 100644
index 00000000..68566a2e
--- /dev/null
+++ b/client/images/flagKit/CF.svg
@@ -0,0 +1,43 @@
+
+
\ No newline at end of file
diff --git a/client/images/flagKit/CG.svg b/client/images/flagKit/CG.svg
new file mode 100644
index 00000000..bc4eb95b
--- /dev/null
+++ b/client/images/flagKit/CG.svg
@@ -0,0 +1,34 @@
+
+
\ No newline at end of file
diff --git a/client/images/flagKit/CH.svg b/client/images/flagKit/CH.svg
new file mode 100644
index 00000000..772f4fa3
--- /dev/null
+++ b/client/images/flagKit/CH.svg
@@ -0,0 +1,23 @@
+
+
\ No newline at end of file
diff --git a/client/images/flagKit/CI.svg b/client/images/flagKit/CI.svg
new file mode 100644
index 00000000..096d98ab
--- /dev/null
+++ b/client/images/flagKit/CI.svg
@@ -0,0 +1,28 @@
+
+
\ No newline at end of file
diff --git a/client/images/flagKit/CK.svg b/client/images/flagKit/CK.svg
new file mode 100644
index 00000000..c1ea3734
--- /dev/null
+++ b/client/images/flagKit/CK.svg
@@ -0,0 +1,31 @@
+
+
\ No newline at end of file
diff --git a/client/images/flagKit/CL.svg b/client/images/flagKit/CL.svg
new file mode 100644
index 00000000..d456d951
--- /dev/null
+++ b/client/images/flagKit/CL.svg
@@ -0,0 +1,29 @@
+
+
\ No newline at end of file
diff --git a/client/images/flagKit/CM.svg b/client/images/flagKit/CM.svg
new file mode 100644
index 00000000..482f4a97
--- /dev/null
+++ b/client/images/flagKit/CM.svg
@@ -0,0 +1,38 @@
+
+
\ No newline at end of file
diff --git a/client/images/flagKit/CN.svg b/client/images/flagKit/CN.svg
new file mode 100644
index 00000000..883ba157
--- /dev/null
+++ b/client/images/flagKit/CN.svg
@@ -0,0 +1,32 @@
+
+
\ No newline at end of file
diff --git a/client/images/flagKit/CO.svg b/client/images/flagKit/CO.svg
new file mode 100644
index 00000000..be492e3d
--- /dev/null
+++ b/client/images/flagKit/CO.svg
@@ -0,0 +1,32 @@
+
+
\ No newline at end of file
diff --git a/client/images/flagKit/CR.svg b/client/images/flagKit/CR.svg
new file mode 100644
index 00000000..271204eb
--- /dev/null
+++ b/client/images/flagKit/CR.svg
@@ -0,0 +1,29 @@
+
+
\ No newline at end of file
diff --git a/client/images/flagKit/CU.svg b/client/images/flagKit/CU.svg
new file mode 100644
index 00000000..23750cd9
--- /dev/null
+++ b/client/images/flagKit/CU.svg
@@ -0,0 +1,32 @@
+
+
\ No newline at end of file
diff --git a/client/images/flagKit/CV.svg b/client/images/flagKit/CV.svg
new file mode 100644
index 00000000..4b6152fb
--- /dev/null
+++ b/client/images/flagKit/CV.svg
@@ -0,0 +1,30 @@
+
+
\ No newline at end of file
diff --git a/client/images/flagKit/CW.svg b/client/images/flagKit/CW.svg
new file mode 100644
index 00000000..14acd27f
--- /dev/null
+++ b/client/images/flagKit/CW.svg
@@ -0,0 +1,29 @@
+
+
\ No newline at end of file
diff --git a/client/images/flagKit/CX.svg b/client/images/flagKit/CX.svg
new file mode 100644
index 00000000..b3fe73d9
--- /dev/null
+++ b/client/images/flagKit/CX.svg
@@ -0,0 +1,38 @@
+
+
\ No newline at end of file
diff --git a/client/images/flagKit/CY.svg b/client/images/flagKit/CY.svg
new file mode 100644
index 00000000..b7860aa9
--- /dev/null
+++ b/client/images/flagKit/CY.svg
@@ -0,0 +1,24 @@
+
+
\ No newline at end of file
diff --git a/client/images/flagKit/CZ.svg b/client/images/flagKit/CZ.svg
new file mode 100644
index 00000000..d56c61b8
--- /dev/null
+++ b/client/images/flagKit/CZ.svg
@@ -0,0 +1,28 @@
+
+
\ No newline at end of file
diff --git a/client/images/flagKit/DE.svg b/client/images/flagKit/DE.svg
new file mode 100644
index 00000000..4ff1ebd5
--- /dev/null
+++ b/client/images/flagKit/DE.svg
@@ -0,0 +1,32 @@
+
+
\ No newline at end of file
diff --git a/client/images/flagKit/DJ.svg b/client/images/flagKit/DJ.svg
new file mode 100644
index 00000000..c0a019f9
--- /dev/null
+++ b/client/images/flagKit/DJ.svg
@@ -0,0 +1,33 @@
+
+
\ No newline at end of file
diff --git a/client/images/flagKit/DK.svg b/client/images/flagKit/DK.svg
new file mode 100644
index 00000000..27900e15
--- /dev/null
+++ b/client/images/flagKit/DK.svg
@@ -0,0 +1,23 @@
+
+
\ No newline at end of file
diff --git a/client/images/flagKit/DM.svg b/client/images/flagKit/DM.svg
new file mode 100644
index 00000000..d5c401eb
--- /dev/null
+++ b/client/images/flagKit/DM.svg
@@ -0,0 +1,41 @@
+
+
\ No newline at end of file
diff --git a/client/images/flagKit/DO.svg b/client/images/flagKit/DO.svg
new file mode 100644
index 00000000..9188e0be
--- /dev/null
+++ b/client/images/flagKit/DO.svg
@@ -0,0 +1,33 @@
+
+
\ No newline at end of file
diff --git a/client/images/flagKit/DZ.svg b/client/images/flagKit/DZ.svg
new file mode 100644
index 00000000..0920d712
--- /dev/null
+++ b/client/images/flagKit/DZ.svg
@@ -0,0 +1,29 @@
+
+
\ No newline at end of file
diff --git a/client/images/flagKit/EC.svg b/client/images/flagKit/EC.svg
new file mode 100644
index 00000000..0fbd3ea6
--- /dev/null
+++ b/client/images/flagKit/EC.svg
@@ -0,0 +1,39 @@
+
+
\ No newline at end of file
diff --git a/client/images/flagKit/EE.svg b/client/images/flagKit/EE.svg
new file mode 100644
index 00000000..63605223
--- /dev/null
+++ b/client/images/flagKit/EE.svg
@@ -0,0 +1,28 @@
+
+
\ No newline at end of file
diff --git a/client/images/flagKit/EG.svg b/client/images/flagKit/EG.svg
new file mode 100644
index 00000000..32d4447e
--- /dev/null
+++ b/client/images/flagKit/EG.svg
@@ -0,0 +1,30 @@
+
+
\ No newline at end of file
diff --git a/client/images/flagKit/ER.svg b/client/images/flagKit/ER.svg
new file mode 100644
index 00000000..bb70368b
--- /dev/null
+++ b/client/images/flagKit/ER.svg
@@ -0,0 +1,40 @@
+
+
\ No newline at end of file
diff --git a/client/images/flagKit/ES.svg b/client/images/flagKit/ES.svg
new file mode 100644
index 00000000..883554f8
--- /dev/null
+++ b/client/images/flagKit/ES.svg
@@ -0,0 +1,34 @@
+
+
\ No newline at end of file
diff --git a/client/images/flagKit/ET.svg b/client/images/flagKit/ET.svg
new file mode 100644
index 00000000..c4387b9f
--- /dev/null
+++ b/client/images/flagKit/ET.svg
@@ -0,0 +1,42 @@
+
+
\ No newline at end of file
diff --git a/client/images/flagKit/EU.svg b/client/images/flagKit/EU.svg
new file mode 100644
index 00000000..db74ffaf
--- /dev/null
+++ b/client/images/flagKit/EU.svg
@@ -0,0 +1,27 @@
+
+
\ No newline at end of file
diff --git a/client/images/flagKit/FI.svg b/client/images/flagKit/FI.svg
new file mode 100644
index 00000000..9d243ed5
--- /dev/null
+++ b/client/images/flagKit/FI.svg
@@ -0,0 +1,22 @@
+
+
\ No newline at end of file
diff --git a/client/images/flagKit/FJ.svg b/client/images/flagKit/FJ.svg
new file mode 100644
index 00000000..e3ebc9bb
--- /dev/null
+++ b/client/images/flagKit/FJ.svg
@@ -0,0 +1,51 @@
+
+
\ No newline at end of file
diff --git a/client/images/flagKit/FK.svg b/client/images/flagKit/FK.svg
new file mode 100644
index 00000000..01b0f2a8
--- /dev/null
+++ b/client/images/flagKit/FK.svg
@@ -0,0 +1,58 @@
+
+
\ No newline at end of file
diff --git a/client/images/flagKit/FM.svg b/client/images/flagKit/FM.svg
new file mode 100644
index 00000000..befd157c
--- /dev/null
+++ b/client/images/flagKit/FM.svg
@@ -0,0 +1,23 @@
+
+
\ No newline at end of file
diff --git a/client/images/flagKit/FO.svg b/client/images/flagKit/FO.svg
new file mode 100644
index 00000000..77618c05
--- /dev/null
+++ b/client/images/flagKit/FO.svg
@@ -0,0 +1,27 @@
+
+
\ No newline at end of file
diff --git a/client/images/flagKit/FR.svg b/client/images/flagKit/FR.svg
new file mode 100644
index 00000000..940de616
--- /dev/null
+++ b/client/images/flagKit/FR.svg
@@ -0,0 +1,28 @@
+
+
\ No newline at end of file
diff --git a/client/images/flagKit/GA.svg b/client/images/flagKit/GA.svg
new file mode 100644
index 00000000..45c68087
--- /dev/null
+++ b/client/images/flagKit/GA.svg
@@ -0,0 +1,32 @@
+
+
\ No newline at end of file
diff --git a/client/images/flagKit/GB.svg b/client/images/flagKit/GB.svg
new file mode 100644
index 00000000..679d27c7
--- /dev/null
+++ b/client/images/flagKit/GB.svg
@@ -0,0 +1,32 @@
+
+
\ No newline at end of file
diff --git a/client/images/flagKit/GD.svg b/client/images/flagKit/GD.svg
new file mode 100644
index 00000000..210dc3fd
--- /dev/null
+++ b/client/images/flagKit/GD.svg
@@ -0,0 +1,49 @@
+
+
\ No newline at end of file
diff --git a/client/images/flagKit/GE.svg b/client/images/flagKit/GE.svg
new file mode 100644
index 00000000..818f3f5b
--- /dev/null
+++ b/client/images/flagKit/GE.svg
@@ -0,0 +1,26 @@
+
+
\ No newline at end of file
diff --git a/client/images/flagKit/GF.svg b/client/images/flagKit/GF.svg
new file mode 100644
index 00000000..bae1448d
--- /dev/null
+++ b/client/images/flagKit/GF.svg
@@ -0,0 +1,32 @@
+
+
\ No newline at end of file
diff --git a/client/images/flagKit/GG.svg b/client/images/flagKit/GG.svg
new file mode 100644
index 00000000..fa428535
--- /dev/null
+++ b/client/images/flagKit/GG.svg
@@ -0,0 +1,27 @@
+
+
\ No newline at end of file
diff --git a/client/images/flagKit/GH.svg b/client/images/flagKit/GH.svg
new file mode 100644
index 00000000..528473ff
--- /dev/null
+++ b/client/images/flagKit/GH.svg
@@ -0,0 +1,37 @@
+
+
\ No newline at end of file
diff --git a/client/images/flagKit/GI.svg b/client/images/flagKit/GI.svg
new file mode 100644
index 00000000..ecd8530a
--- /dev/null
+++ b/client/images/flagKit/GI.svg
@@ -0,0 +1,38 @@
+
+
\ No newline at end of file
diff --git a/client/images/flagKit/GL.svg b/client/images/flagKit/GL.svg
new file mode 100644
index 00000000..33b22333
--- /dev/null
+++ b/client/images/flagKit/GL.svg
@@ -0,0 +1,33 @@
+
+
\ No newline at end of file
diff --git a/client/images/flagKit/GM.svg b/client/images/flagKit/GM.svg
new file mode 100644
index 00000000..b6330f52
--- /dev/null
+++ b/client/images/flagKit/GM.svg
@@ -0,0 +1,33 @@
+
+
\ No newline at end of file
diff --git a/client/images/flagKit/GN.svg b/client/images/flagKit/GN.svg
new file mode 100644
index 00000000..2d20595e
--- /dev/null
+++ b/client/images/flagKit/GN.svg
@@ -0,0 +1,32 @@
+
+
\ No newline at end of file
diff --git a/client/images/flagKit/GP.svg b/client/images/flagKit/GP.svg
new file mode 100644
index 00000000..3dbdcc13
--- /dev/null
+++ b/client/images/flagKit/GP.svg
@@ -0,0 +1,40 @@
+
+
\ No newline at end of file
diff --git a/client/images/flagKit/GQ.svg b/client/images/flagKit/GQ.svg
new file mode 100644
index 00000000..e2d5c67d
--- /dev/null
+++ b/client/images/flagKit/GQ.svg
@@ -0,0 +1,34 @@
+
+
\ No newline at end of file
diff --git a/client/images/flagKit/GR.svg b/client/images/flagKit/GR.svg
new file mode 100644
index 00000000..a9b12c00
--- /dev/null
+++ b/client/images/flagKit/GR.svg
@@ -0,0 +1,22 @@
+
+
\ No newline at end of file
diff --git a/client/images/flagKit/GS.svg b/client/images/flagKit/GS.svg
new file mode 100644
index 00000000..03984521
--- /dev/null
+++ b/client/images/flagKit/GS.svg
@@ -0,0 +1,112 @@
+
+
\ No newline at end of file
diff --git a/client/images/flagKit/GT.svg b/client/images/flagKit/GT.svg
new file mode 100644
index 00000000..be45ee89
--- /dev/null
+++ b/client/images/flagKit/GT.svg
@@ -0,0 +1,26 @@
+
+
\ No newline at end of file
diff --git a/client/images/flagKit/GU.svg b/client/images/flagKit/GU.svg
new file mode 100644
index 00000000..6233a0bb
--- /dev/null
+++ b/client/images/flagKit/GU.svg
@@ -0,0 +1,65 @@
+
+
\ No newline at end of file
diff --git a/client/images/flagKit/GW.svg b/client/images/flagKit/GW.svg
new file mode 100644
index 00000000..b09530d4
--- /dev/null
+++ b/client/images/flagKit/GW.svg
@@ -0,0 +1,37 @@
+
+
\ No newline at end of file
diff --git a/client/images/flagKit/GY.svg b/client/images/flagKit/GY.svg
new file mode 100644
index 00000000..e5937c24
--- /dev/null
+++ b/client/images/flagKit/GY.svg
@@ -0,0 +1,42 @@
+
+
\ No newline at end of file
diff --git a/client/images/flagKit/HK.svg b/client/images/flagKit/HK.svg
new file mode 100644
index 00000000..f99b8882
--- /dev/null
+++ b/client/images/flagKit/HK.svg
@@ -0,0 +1,23 @@
+
+
\ No newline at end of file
diff --git a/client/images/flagKit/HM.svg b/client/images/flagKit/HM.svg
new file mode 100644
index 00000000..8ef4f346
--- /dev/null
+++ b/client/images/flagKit/HM.svg
@@ -0,0 +1,36 @@
+
+
\ No newline at end of file
diff --git a/client/images/flagKit/HN.svg b/client/images/flagKit/HN.svg
new file mode 100644
index 00000000..50a48cd9
--- /dev/null
+++ b/client/images/flagKit/HN.svg
@@ -0,0 +1,33 @@
+
+
\ No newline at end of file
diff --git a/client/images/flagKit/HR.svg b/client/images/flagKit/HR.svg
new file mode 100644
index 00000000..a6cf5daa
--- /dev/null
+++ b/client/images/flagKit/HR.svg
@@ -0,0 +1,35 @@
+
+
\ No newline at end of file
diff --git a/client/images/flagKit/HT.svg b/client/images/flagKit/HT.svg
new file mode 100644
index 00000000..0cd82be1
--- /dev/null
+++ b/client/images/flagKit/HT.svg
@@ -0,0 +1,46 @@
+
+
\ No newline at end of file
diff --git a/client/images/flagKit/HU.svg b/client/images/flagKit/HU.svg
new file mode 100644
index 00000000..795319ea
--- /dev/null
+++ b/client/images/flagKit/HU.svg
@@ -0,0 +1,28 @@
+
+
\ No newline at end of file
diff --git a/client/images/flagKit/ID.svg b/client/images/flagKit/ID.svg
new file mode 100644
index 00000000..8101da05
--- /dev/null
+++ b/client/images/flagKit/ID.svg
@@ -0,0 +1,23 @@
+
+
\ No newline at end of file
diff --git a/client/images/flagKit/IE.svg b/client/images/flagKit/IE.svg
new file mode 100644
index 00000000..60d9af87
--- /dev/null
+++ b/client/images/flagKit/IE.svg
@@ -0,0 +1,28 @@
+
+
\ No newline at end of file
diff --git a/client/images/flagKit/IL.svg b/client/images/flagKit/IL.svg
new file mode 100644
index 00000000..7646f91e
--- /dev/null
+++ b/client/images/flagKit/IL.svg
@@ -0,0 +1,26 @@
+
+
\ No newline at end of file
diff --git a/client/images/flagKit/IM.svg b/client/images/flagKit/IM.svg
new file mode 100644
index 00000000..ecc7c12e
--- /dev/null
+++ b/client/images/flagKit/IM.svg
@@ -0,0 +1,30 @@
+
+
\ No newline at end of file
diff --git a/client/images/flagKit/IN.svg b/client/images/flagKit/IN.svg
new file mode 100644
index 00000000..3726ceb7
--- /dev/null
+++ b/client/images/flagKit/IN.svg
@@ -0,0 +1,31 @@
+
+
\ No newline at end of file
diff --git a/client/images/flagKit/IO.svg b/client/images/flagKit/IO.svg
new file mode 100644
index 00000000..4d8b5229
--- /dev/null
+++ b/client/images/flagKit/IO.svg
@@ -0,0 +1,33 @@
+
+
\ No newline at end of file
diff --git a/client/images/flagKit/IQ.svg b/client/images/flagKit/IQ.svg
new file mode 100644
index 00000000..16c4cf18
--- /dev/null
+++ b/client/images/flagKit/IQ.svg
@@ -0,0 +1,33 @@
+
+
\ No newline at end of file
diff --git a/client/images/flagKit/IR.svg b/client/images/flagKit/IR.svg
new file mode 100644
index 00000000..af325017
--- /dev/null
+++ b/client/images/flagKit/IR.svg
@@ -0,0 +1,31 @@
+
+
\ No newline at end of file
diff --git a/client/images/flagKit/IS.svg b/client/images/flagKit/IS.svg
new file mode 100644
index 00000000..385a2bf9
--- /dev/null
+++ b/client/images/flagKit/IS.svg
@@ -0,0 +1,28 @@
+
+
\ No newline at end of file
diff --git a/client/images/flagKit/IT.svg b/client/images/flagKit/IT.svg
new file mode 100644
index 00000000..9e76f24c
--- /dev/null
+++ b/client/images/flagKit/IT.svg
@@ -0,0 +1,28 @@
+
+
\ No newline at end of file
diff --git a/client/images/flagKit/JE.svg b/client/images/flagKit/JE.svg
new file mode 100644
index 00000000..6663c504
--- /dev/null
+++ b/client/images/flagKit/JE.svg
@@ -0,0 +1,32 @@
+
+
\ No newline at end of file
diff --git a/client/images/flagKit/JM.svg b/client/images/flagKit/JM.svg
new file mode 100644
index 00000000..54779e77
--- /dev/null
+++ b/client/images/flagKit/JM.svg
@@ -0,0 +1,33 @@
+
+
\ No newline at end of file
diff --git a/client/images/flagKit/JO.svg b/client/images/flagKit/JO.svg
new file mode 100644
index 00000000..b0788e76
--- /dev/null
+++ b/client/images/flagKit/JO.svg
@@ -0,0 +1,34 @@
+
+
\ No newline at end of file
diff --git a/client/images/flagKit/JP.svg b/client/images/flagKit/JP.svg
new file mode 100644
index 00000000..0a655c04
--- /dev/null
+++ b/client/images/flagKit/JP.svg
@@ -0,0 +1,22 @@
+
+
\ No newline at end of file
diff --git a/client/images/flagKit/KE.svg b/client/images/flagKit/KE.svg
new file mode 100644
index 00000000..6c6a6cf6
--- /dev/null
+++ b/client/images/flagKit/KE.svg
@@ -0,0 +1,43 @@
+
+
\ No newline at end of file
diff --git a/client/images/flagKit/KG.svg b/client/images/flagKit/KG.svg
new file mode 100644
index 00000000..12e6a244
--- /dev/null
+++ b/client/images/flagKit/KG.svg
@@ -0,0 +1,28 @@
+
+
\ No newline at end of file
diff --git a/client/images/flagKit/KH.svg b/client/images/flagKit/KH.svg
new file mode 100644
index 00000000..9ea454bb
--- /dev/null
+++ b/client/images/flagKit/KH.svg
@@ -0,0 +1,29 @@
+
+
\ No newline at end of file
diff --git a/client/images/flagKit/KI.svg b/client/images/flagKit/KI.svg
new file mode 100644
index 00000000..e00e2352
--- /dev/null
+++ b/client/images/flagKit/KI.svg
@@ -0,0 +1,35 @@
+
+
\ No newline at end of file
diff --git a/client/images/flagKit/KM.svg b/client/images/flagKit/KM.svg
new file mode 100644
index 00000000..2da152d5
--- /dev/null
+++ b/client/images/flagKit/KM.svg
@@ -0,0 +1,39 @@
+
+
\ No newline at end of file
diff --git a/client/images/flagKit/KN.svg b/client/images/flagKit/KN.svg
new file mode 100644
index 00000000..e65b7b61
--- /dev/null
+++ b/client/images/flagKit/KN.svg
@@ -0,0 +1,39 @@
+
+
\ No newline at end of file
diff --git a/client/images/flagKit/KP.svg b/client/images/flagKit/KP.svg
new file mode 100644
index 00000000..649feb27
--- /dev/null
+++ b/client/images/flagKit/KP.svg
@@ -0,0 +1,30 @@
+
+
\ No newline at end of file
diff --git a/client/images/flagKit/KR.svg b/client/images/flagKit/KR.svg
new file mode 100644
index 00000000..078665a5
--- /dev/null
+++ b/client/images/flagKit/KR.svg
@@ -0,0 +1,38 @@
+
+
\ No newline at end of file
diff --git a/client/images/flagKit/KW.svg b/client/images/flagKit/KW.svg
new file mode 100644
index 00000000..a73b0113
--- /dev/null
+++ b/client/images/flagKit/KW.svg
@@ -0,0 +1,33 @@
+
+
\ No newline at end of file
diff --git a/client/images/flagKit/KY.svg b/client/images/flagKit/KY.svg
new file mode 100644
index 00000000..2240dbc6
--- /dev/null
+++ b/client/images/flagKit/KY.svg
@@ -0,0 +1,44 @@
+
+
\ No newline at end of file
diff --git a/client/images/flagKit/KZ.svg b/client/images/flagKit/KZ.svg
new file mode 100644
index 00000000..6076ac54
--- /dev/null
+++ b/client/images/flagKit/KZ.svg
@@ -0,0 +1,29 @@
+
+
\ No newline at end of file
diff --git a/client/images/flagKit/LA.svg b/client/images/flagKit/LA.svg
new file mode 100644
index 00000000..5b740da7
--- /dev/null
+++ b/client/images/flagKit/LA.svg
@@ -0,0 +1,29 @@
+
+
\ No newline at end of file
diff --git a/client/images/flagKit/LB.svg b/client/images/flagKit/LB.svg
new file mode 100644
index 00000000..401a235d
--- /dev/null
+++ b/client/images/flagKit/LB.svg
@@ -0,0 +1,29 @@
+
+
\ No newline at end of file
diff --git a/client/images/flagKit/LC.svg b/client/images/flagKit/LC.svg
new file mode 100644
index 00000000..8d809d3e
--- /dev/null
+++ b/client/images/flagKit/LC.svg
@@ -0,0 +1,33 @@
+
+
\ No newline at end of file
diff --git a/client/images/flagKit/LI.svg b/client/images/flagKit/LI.svg
new file mode 100644
index 00000000..1160975a
--- /dev/null
+++ b/client/images/flagKit/LI.svg
@@ -0,0 +1,27 @@
+
+
\ No newline at end of file
diff --git a/client/images/flagKit/LICENSE b/client/images/flagKit/LICENSE
new file mode 100644
index 00000000..59f47bf1
--- /dev/null
+++ b/client/images/flagKit/LICENSE
@@ -0,0 +1,22 @@
+The MIT License (MIT)
+
+Copyright (c) 2016 Bowtie AB
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
+
diff --git a/client/images/flagKit/LK.svg b/client/images/flagKit/LK.svg
new file mode 100644
index 00000000..55386d5c
--- /dev/null
+++ b/client/images/flagKit/LK.svg
@@ -0,0 +1,43 @@
+
+
\ No newline at end of file
diff --git a/client/images/flagKit/LR.svg b/client/images/flagKit/LR.svg
new file mode 100644
index 00000000..3d6cef1e
--- /dev/null
+++ b/client/images/flagKit/LR.svg
@@ -0,0 +1,36 @@
+
+
\ No newline at end of file
diff --git a/client/images/flagKit/LS.svg b/client/images/flagKit/LS.svg
new file mode 100644
index 00000000..3ec5277d
--- /dev/null
+++ b/client/images/flagKit/LS.svg
@@ -0,0 +1,34 @@
+
+
\ No newline at end of file
diff --git a/client/images/flagKit/LT.svg b/client/images/flagKit/LT.svg
new file mode 100644
index 00000000..8e592267
--- /dev/null
+++ b/client/images/flagKit/LT.svg
@@ -0,0 +1,32 @@
+
+
\ No newline at end of file
diff --git a/client/images/flagKit/LU.svg b/client/images/flagKit/LU.svg
new file mode 100644
index 00000000..860e730b
--- /dev/null
+++ b/client/images/flagKit/LU.svg
@@ -0,0 +1,28 @@
+
+
\ No newline at end of file
diff --git a/client/images/flagKit/LV.svg b/client/images/flagKit/LV.svg
new file mode 100644
index 00000000..5d0255e6
--- /dev/null
+++ b/client/images/flagKit/LV.svg
@@ -0,0 +1,24 @@
+
+
\ No newline at end of file
diff --git a/client/images/flagKit/LY.svg b/client/images/flagKit/LY.svg
new file mode 100644
index 00000000..4b9f2a0e
--- /dev/null
+++ b/client/images/flagKit/LY.svg
@@ -0,0 +1,33 @@
+
+
\ No newline at end of file
diff --git a/client/images/flagKit/MA.svg b/client/images/flagKit/MA.svg
new file mode 100644
index 00000000..cb22ba95
--- /dev/null
+++ b/client/images/flagKit/MA.svg
@@ -0,0 +1,23 @@
+
+
\ No newline at end of file
diff --git a/client/images/flagKit/MC.svg b/client/images/flagKit/MC.svg
new file mode 100644
index 00000000..207590a7
--- /dev/null
+++ b/client/images/flagKit/MC.svg
@@ -0,0 +1,23 @@
+
+
\ No newline at end of file
diff --git a/client/images/flagKit/MD.svg b/client/images/flagKit/MD.svg
new file mode 100644
index 00000000..301e93ee
--- /dev/null
+++ b/client/images/flagKit/MD.svg
@@ -0,0 +1,42 @@
+
+
\ No newline at end of file
diff --git a/client/images/flagKit/ME.svg b/client/images/flagKit/ME.svg
new file mode 100644
index 00000000..9b0838e9
--- /dev/null
+++ b/client/images/flagKit/ME.svg
@@ -0,0 +1,29 @@
+
+
\ No newline at end of file
diff --git a/client/images/flagKit/MF.svg b/client/images/flagKit/MF.svg
new file mode 100644
index 00000000..c45b62a0
--- /dev/null
+++ b/client/images/flagKit/MF.svg
@@ -0,0 +1,28 @@
+
+
\ No newline at end of file
diff --git a/client/images/flagKit/MG.svg b/client/images/flagKit/MG.svg
new file mode 100644
index 00000000..c173fdd5
--- /dev/null
+++ b/client/images/flagKit/MG.svg
@@ -0,0 +1,28 @@
+
+
\ No newline at end of file
diff --git a/client/images/flagKit/MH.svg b/client/images/flagKit/MH.svg
new file mode 100644
index 00000000..e6b66091
--- /dev/null
+++ b/client/images/flagKit/MH.svg
@@ -0,0 +1,29 @@
+
+
\ No newline at end of file
diff --git a/client/images/flagKit/MK.svg b/client/images/flagKit/MK.svg
new file mode 100644
index 00000000..35b92297
--- /dev/null
+++ b/client/images/flagKit/MK.svg
@@ -0,0 +1,29 @@
+
+
\ No newline at end of file
diff --git a/client/images/flagKit/ML.svg b/client/images/flagKit/ML.svg
new file mode 100644
index 00000000..babc6e59
--- /dev/null
+++ b/client/images/flagKit/ML.svg
@@ -0,0 +1,32 @@
+
+
\ No newline at end of file
diff --git a/client/images/flagKit/MM.svg b/client/images/flagKit/MM.svg
new file mode 100644
index 00000000..eb3c18a3
--- /dev/null
+++ b/client/images/flagKit/MM.svg
@@ -0,0 +1,33 @@
+
+
\ No newline at end of file
diff --git a/client/images/flagKit/MN.svg b/client/images/flagKit/MN.svg
new file mode 100644
index 00000000..8af15a51
--- /dev/null
+++ b/client/images/flagKit/MN.svg
@@ -0,0 +1,33 @@
+
+
\ No newline at end of file
diff --git a/client/images/flagKit/MO.svg b/client/images/flagKit/MO.svg
new file mode 100644
index 00000000..be4bc875
--- /dev/null
+++ b/client/images/flagKit/MO.svg
@@ -0,0 +1,26 @@
+
+
\ No newline at end of file
diff --git a/client/images/flagKit/MP.svg b/client/images/flagKit/MP.svg
new file mode 100644
index 00000000..33151489
--- /dev/null
+++ b/client/images/flagKit/MP.svg
@@ -0,0 +1,29 @@
+
+
\ No newline at end of file
diff --git a/client/images/flagKit/MQ.svg b/client/images/flagKit/MQ.svg
new file mode 100644
index 00000000..adc82074
--- /dev/null
+++ b/client/images/flagKit/MQ.svg
@@ -0,0 +1,27 @@
+
+
\ No newline at end of file
diff --git a/client/images/flagKit/MR.svg b/client/images/flagKit/MR.svg
new file mode 100644
index 00000000..da5adee6
--- /dev/null
+++ b/client/images/flagKit/MR.svg
@@ -0,0 +1,27 @@
+
+
\ No newline at end of file
diff --git a/client/images/flagKit/MS.svg b/client/images/flagKit/MS.svg
new file mode 100644
index 00000000..184c9178
--- /dev/null
+++ b/client/images/flagKit/MS.svg
@@ -0,0 +1,47 @@
+
+
\ No newline at end of file
diff --git a/client/images/flagKit/MT.svg b/client/images/flagKit/MT.svg
new file mode 100644
index 00000000..5ce0b3fe
--- /dev/null
+++ b/client/images/flagKit/MT.svg
@@ -0,0 +1,29 @@
+
+
\ No newline at end of file
diff --git a/client/images/flagKit/MU.svg b/client/images/flagKit/MU.svg
new file mode 100644
index 00000000..f2c6f3f8
--- /dev/null
+++ b/client/images/flagKit/MU.svg
@@ -0,0 +1,37 @@
+
+
\ No newline at end of file
diff --git a/client/images/flagKit/MV.svg b/client/images/flagKit/MV.svg
new file mode 100644
index 00000000..f10e07d5
--- /dev/null
+++ b/client/images/flagKit/MV.svg
@@ -0,0 +1,28 @@
+
+
\ No newline at end of file
diff --git a/client/images/flagKit/MW.svg b/client/images/flagKit/MW.svg
new file mode 100644
index 00000000..5b0cc5c6
--- /dev/null
+++ b/client/images/flagKit/MW.svg
@@ -0,0 +1,33 @@
+
+
\ No newline at end of file
diff --git a/client/images/flagKit/MX.svg b/client/images/flagKit/MX.svg
new file mode 100644
index 00000000..7ed245bc
--- /dev/null
+++ b/client/images/flagKit/MX.svg
@@ -0,0 +1,30 @@
+
+
\ No newline at end of file
diff --git a/client/images/flagKit/MY.svg b/client/images/flagKit/MY.svg
new file mode 100644
index 00000000..e7ff885f
--- /dev/null
+++ b/client/images/flagKit/MY.svg
@@ -0,0 +1,32 @@
+
+
\ No newline at end of file
diff --git a/client/images/flagKit/MZ.svg b/client/images/flagKit/MZ.svg
new file mode 100644
index 00000000..7f553b00
--- /dev/null
+++ b/client/images/flagKit/MZ.svg
@@ -0,0 +1,43 @@
+
+
\ No newline at end of file
diff --git a/client/images/flagKit/NA.svg b/client/images/flagKit/NA.svg
new file mode 100644
index 00000000..cb0ba69f
--- /dev/null
+++ b/client/images/flagKit/NA.svg
@@ -0,0 +1,75 @@
+
+
\ No newline at end of file
diff --git a/client/images/flagKit/NC.svg b/client/images/flagKit/NC.svg
new file mode 100644
index 00000000..bae580e8
--- /dev/null
+++ b/client/images/flagKit/NC.svg
@@ -0,0 +1,42 @@
+
+
\ No newline at end of file
diff --git a/client/images/flagKit/NE.svg b/client/images/flagKit/NE.svg
new file mode 100644
index 00000000..12bcf8a0
--- /dev/null
+++ b/client/images/flagKit/NE.svg
@@ -0,0 +1,33 @@
+
+
\ No newline at end of file
diff --git a/client/images/flagKit/NF.svg b/client/images/flagKit/NF.svg
new file mode 100644
index 00000000..b707e52d
--- /dev/null
+++ b/client/images/flagKit/NF.svg
@@ -0,0 +1,29 @@
+
+
\ No newline at end of file
diff --git a/client/images/flagKit/NG.svg b/client/images/flagKit/NG.svg
new file mode 100644
index 00000000..4063ff84
--- /dev/null
+++ b/client/images/flagKit/NG.svg
@@ -0,0 +1,24 @@
+
+
\ No newline at end of file
diff --git a/client/images/flagKit/NI.svg b/client/images/flagKit/NI.svg
new file mode 100644
index 00000000..7adb4ba4
--- /dev/null
+++ b/client/images/flagKit/NI.svg
@@ -0,0 +1,26 @@
+
+
\ No newline at end of file
diff --git a/client/images/flagKit/NL.svg b/client/images/flagKit/NL.svg
new file mode 100644
index 00000000..c62f42ad
--- /dev/null
+++ b/client/images/flagKit/NL.svg
@@ -0,0 +1,28 @@
+
+
\ No newline at end of file
diff --git a/client/images/flagKit/NO.svg b/client/images/flagKit/NO.svg
new file mode 100644
index 00000000..cdc23f49
--- /dev/null
+++ b/client/images/flagKit/NO.svg
@@ -0,0 +1,28 @@
+
+
\ No newline at end of file
diff --git a/client/images/flagKit/NP.svg b/client/images/flagKit/NP.svg
new file mode 100644
index 00000000..c879fa80
--- /dev/null
+++ b/client/images/flagKit/NP.svg
@@ -0,0 +1,35 @@
+
+
\ No newline at end of file
diff --git a/client/images/flagKit/NR.svg b/client/images/flagKit/NR.svg
new file mode 100644
index 00000000..1a6c3a21
--- /dev/null
+++ b/client/images/flagKit/NR.svg
@@ -0,0 +1,28 @@
+
+
\ No newline at end of file
diff --git a/client/images/flagKit/NU.svg b/client/images/flagKit/NU.svg
new file mode 100644
index 00000000..3d9bc80c
--- /dev/null
+++ b/client/images/flagKit/NU.svg
@@ -0,0 +1,41 @@
+
+
\ No newline at end of file
diff --git a/client/images/flagKit/NZ.svg b/client/images/flagKit/NZ.svg
new file mode 100644
index 00000000..c1f624df
--- /dev/null
+++ b/client/images/flagKit/NZ.svg
@@ -0,0 +1,34 @@
+
+
\ No newline at end of file
diff --git a/client/images/flagKit/OM.svg b/client/images/flagKit/OM.svg
new file mode 100644
index 00000000..cb08ac82
--- /dev/null
+++ b/client/images/flagKit/OM.svg
@@ -0,0 +1,29 @@
+
+
\ No newline at end of file
diff --git a/client/images/flagKit/PA.svg b/client/images/flagKit/PA.svg
new file mode 100644
index 00000000..d8516682
--- /dev/null
+++ b/client/images/flagKit/PA.svg
@@ -0,0 +1,30 @@
+
+
\ No newline at end of file
diff --git a/client/images/flagKit/PE.svg b/client/images/flagKit/PE.svg
new file mode 100644
index 00000000..98a26cf2
--- /dev/null
+++ b/client/images/flagKit/PE.svg
@@ -0,0 +1,24 @@
+
+
\ No newline at end of file
diff --git a/client/images/flagKit/PF.svg b/client/images/flagKit/PF.svg
new file mode 100644
index 00000000..b29385f4
--- /dev/null
+++ b/client/images/flagKit/PF.svg
@@ -0,0 +1,52 @@
+
+
\ No newline at end of file
diff --git a/client/images/flagKit/PG.svg b/client/images/flagKit/PG.svg
new file mode 100644
index 00000000..0630fab6
--- /dev/null
+++ b/client/images/flagKit/PG.svg
@@ -0,0 +1,36 @@
+
+
\ No newline at end of file
diff --git a/client/images/flagKit/PH.svg b/client/images/flagKit/PH.svg
new file mode 100644
index 00000000..4c1087b8
--- /dev/null
+++ b/client/images/flagKit/PH.svg
@@ -0,0 +1,33 @@
+
+
\ No newline at end of file
diff --git a/client/images/flagKit/PK.svg b/client/images/flagKit/PK.svg
new file mode 100644
index 00000000..7ecb09cf
--- /dev/null
+++ b/client/images/flagKit/PK.svg
@@ -0,0 +1,32 @@
+
+
\ No newline at end of file
diff --git a/client/images/flagKit/PL.svg b/client/images/flagKit/PL.svg
new file mode 100644
index 00000000..fadbd2d6
--- /dev/null
+++ b/client/images/flagKit/PL.svg
@@ -0,0 +1,23 @@
+
+
\ No newline at end of file
diff --git a/client/images/flagKit/PM.svg b/client/images/flagKit/PM.svg
new file mode 100644
index 00000000..1f39fd0a
--- /dev/null
+++ b/client/images/flagKit/PM.svg
@@ -0,0 +1,66 @@
+
+
\ No newline at end of file
diff --git a/client/images/flagKit/PN.svg b/client/images/flagKit/PN.svg
new file mode 100644
index 00000000..f2b2cc4f
--- /dev/null
+++ b/client/images/flagKit/PN.svg
@@ -0,0 +1,51 @@
+
+
\ No newline at end of file
diff --git a/client/images/flagKit/PR.svg b/client/images/flagKit/PR.svg
new file mode 100644
index 00000000..7d120445
--- /dev/null
+++ b/client/images/flagKit/PR.svg
@@ -0,0 +1,30 @@
+
+
\ No newline at end of file
diff --git a/client/images/flagKit/PS.svg b/client/images/flagKit/PS.svg
new file mode 100644
index 00000000..e68583ba
--- /dev/null
+++ b/client/images/flagKit/PS.svg
@@ -0,0 +1,33 @@
+
+
\ No newline at end of file
diff --git a/client/images/flagKit/PT.svg b/client/images/flagKit/PT.svg
new file mode 100644
index 00000000..49b59be2
--- /dev/null
+++ b/client/images/flagKit/PT.svg
@@ -0,0 +1,38 @@
+
+
\ No newline at end of file
diff --git a/client/images/flagKit/PW.svg b/client/images/flagKit/PW.svg
new file mode 100644
index 00000000..4ab7f166
--- /dev/null
+++ b/client/images/flagKit/PW.svg
@@ -0,0 +1,27 @@
+
+
\ No newline at end of file
diff --git a/client/images/flagKit/PY.svg b/client/images/flagKit/PY.svg
new file mode 100644
index 00000000..2ae00546
--- /dev/null
+++ b/client/images/flagKit/PY.svg
@@ -0,0 +1,30 @@
+
+
\ No newline at end of file
diff --git a/client/images/flagKit/QA.svg b/client/images/flagKit/QA.svg
new file mode 100644
index 00000000..985171d1
--- /dev/null
+++ b/client/images/flagKit/QA.svg
@@ -0,0 +1,23 @@
+
+
\ No newline at end of file
diff --git a/client/images/flagKit/RE.svg b/client/images/flagKit/RE.svg
new file mode 100644
index 00000000..7e130938
--- /dev/null
+++ b/client/images/flagKit/RE.svg
@@ -0,0 +1,28 @@
+
+
\ No newline at end of file
diff --git a/client/images/flagKit/RO.svg b/client/images/flagKit/RO.svg
new file mode 100644
index 00000000..dd82b266
--- /dev/null
+++ b/client/images/flagKit/RO.svg
@@ -0,0 +1,32 @@
+
+
\ No newline at end of file
diff --git a/client/images/flagKit/RS.svg b/client/images/flagKit/RS.svg
new file mode 100644
index 00000000..892dd5e4
--- /dev/null
+++ b/client/images/flagKit/RS.svg
@@ -0,0 +1,39 @@
+
+
\ No newline at end of file
diff --git a/client/images/flagKit/RU.svg b/client/images/flagKit/RU.svg
new file mode 100644
index 00000000..a9ba65b5
--- /dev/null
+++ b/client/images/flagKit/RU.svg
@@ -0,0 +1,28 @@
+
+
\ No newline at end of file
diff --git a/client/images/flagKit/RW.svg b/client/images/flagKit/RW.svg
new file mode 100644
index 00000000..43b26156
--- /dev/null
+++ b/client/images/flagKit/RW.svg
@@ -0,0 +1,37 @@
+
+
\ No newline at end of file
diff --git a/client/images/flagKit/SA.svg b/client/images/flagKit/SA.svg
new file mode 100644
index 00000000..735b986f
--- /dev/null
+++ b/client/images/flagKit/SA.svg
@@ -0,0 +1,26 @@
+
+
\ No newline at end of file
diff --git a/client/images/flagKit/SB.svg b/client/images/flagKit/SB.svg
new file mode 100644
index 00000000..768c45c0
--- /dev/null
+++ b/client/images/flagKit/SB.svg
@@ -0,0 +1,39 @@
+
+
\ No newline at end of file
diff --git a/client/images/flagKit/SC.svg b/client/images/flagKit/SC.svg
new file mode 100644
index 00000000..62b380b8
--- /dev/null
+++ b/client/images/flagKit/SC.svg
@@ -0,0 +1,43 @@
+
+
\ No newline at end of file
diff --git a/client/images/flagKit/SD.svg b/client/images/flagKit/SD.svg
new file mode 100644
index 00000000..c68d6b1b
--- /dev/null
+++ b/client/images/flagKit/SD.svg
@@ -0,0 +1,33 @@
+
+
\ No newline at end of file
diff --git a/client/images/flagKit/SE.svg b/client/images/flagKit/SE.svg
new file mode 100644
index 00000000..bb4f4e11
--- /dev/null
+++ b/client/images/flagKit/SE.svg
@@ -0,0 +1,27 @@
+
+
\ No newline at end of file
diff --git a/client/images/flagKit/SG.svg b/client/images/flagKit/SG.svg
new file mode 100644
index 00000000..27011483
--- /dev/null
+++ b/client/images/flagKit/SG.svg
@@ -0,0 +1,24 @@
+
+
\ No newline at end of file
diff --git a/client/images/flagKit/SH.svg b/client/images/flagKit/SH.svg
new file mode 100644
index 00000000..e0dde764
--- /dev/null
+++ b/client/images/flagKit/SH.svg
@@ -0,0 +1,53 @@
+
+
\ No newline at end of file
diff --git a/client/images/flagKit/SI.svg b/client/images/flagKit/SI.svg
new file mode 100644
index 00000000..497f8705
--- /dev/null
+++ b/client/images/flagKit/SI.svg
@@ -0,0 +1,28 @@
+
+
\ No newline at end of file
diff --git a/client/images/flagKit/SJ.svg b/client/images/flagKit/SJ.svg
new file mode 100644
index 00000000..bef7e505
--- /dev/null
+++ b/client/images/flagKit/SJ.svg
@@ -0,0 +1,28 @@
+
+
\ No newline at end of file
diff --git a/client/images/flagKit/SK.svg b/client/images/flagKit/SK.svg
new file mode 100644
index 00000000..2b8ba801
--- /dev/null
+++ b/client/images/flagKit/SK.svg
@@ -0,0 +1,46 @@
+
+
\ No newline at end of file
diff --git a/client/images/flagKit/SL.svg b/client/images/flagKit/SL.svg
new file mode 100644
index 00000000..817419ef
--- /dev/null
+++ b/client/images/flagKit/SL.svg
@@ -0,0 +1,28 @@
+
+
\ No newline at end of file
diff --git a/client/images/flagKit/SM.svg b/client/images/flagKit/SM.svg
new file mode 100644
index 00000000..abf62171
--- /dev/null
+++ b/client/images/flagKit/SM.svg
@@ -0,0 +1,25 @@
+
+
\ No newline at end of file
diff --git a/client/images/flagKit/SN.svg b/client/images/flagKit/SN.svg
new file mode 100644
index 00000000..09484160
--- /dev/null
+++ b/client/images/flagKit/SN.svg
@@ -0,0 +1,33 @@
+
+
\ No newline at end of file
diff --git a/client/images/flagKit/SO.svg b/client/images/flagKit/SO.svg
new file mode 100644
index 00000000..6372e377
--- /dev/null
+++ b/client/images/flagKit/SO.svg
@@ -0,0 +1,23 @@
+
+
\ No newline at end of file
diff --git a/client/images/flagKit/SR.svg b/client/images/flagKit/SR.svg
new file mode 100644
index 00000000..97963b0c
--- /dev/null
+++ b/client/images/flagKit/SR.svg
@@ -0,0 +1,34 @@
+
+
\ No newline at end of file
diff --git a/client/images/flagKit/SS.svg b/client/images/flagKit/SS.svg
new file mode 100644
index 00000000..e8d68dd0
--- /dev/null
+++ b/client/images/flagKit/SS.svg
@@ -0,0 +1,44 @@
+
+
\ No newline at end of file
diff --git a/client/images/flagKit/ST.svg b/client/images/flagKit/ST.svg
new file mode 100644
index 00000000..4b355d71
--- /dev/null
+++ b/client/images/flagKit/ST.svg
@@ -0,0 +1,39 @@
+
+
\ No newline at end of file
diff --git a/client/images/flagKit/SV.svg b/client/images/flagKit/SV.svg
new file mode 100644
index 00000000..9bfdd5ce
--- /dev/null
+++ b/client/images/flagKit/SV.svg
@@ -0,0 +1,30 @@
+
+
\ No newline at end of file
diff --git a/client/images/flagKit/SX.svg b/client/images/flagKit/SX.svg
new file mode 100644
index 00000000..ccefe037
--- /dev/null
+++ b/client/images/flagKit/SX.svg
@@ -0,0 +1,45 @@
+
+
\ No newline at end of file
diff --git a/client/images/flagKit/SY.svg b/client/images/flagKit/SY.svg
new file mode 100644
index 00000000..040530b6
--- /dev/null
+++ b/client/images/flagKit/SY.svg
@@ -0,0 +1,34 @@
+
+
\ No newline at end of file
diff --git a/client/images/flagKit/SZ.svg b/client/images/flagKit/SZ.svg
new file mode 100644
index 00000000..fc4120de
--- /dev/null
+++ b/client/images/flagKit/SZ.svg
@@ -0,0 +1,47 @@
+
+
\ No newline at end of file
diff --git a/client/images/flagKit/TC.svg b/client/images/flagKit/TC.svg
new file mode 100644
index 00000000..c3ea149a
--- /dev/null
+++ b/client/images/flagKit/TC.svg
@@ -0,0 +1,40 @@
+
+
\ No newline at end of file
diff --git a/client/images/flagKit/TD.svg b/client/images/flagKit/TD.svg
new file mode 100644
index 00000000..74756faf
--- /dev/null
+++ b/client/images/flagKit/TD.svg
@@ -0,0 +1,32 @@
+
+
\ No newline at end of file
diff --git a/client/images/flagKit/TF.svg b/client/images/flagKit/TF.svg
new file mode 100644
index 00000000..d1ea6918
--- /dev/null
+++ b/client/images/flagKit/TF.svg
@@ -0,0 +1,35 @@
+
+
\ No newline at end of file
diff --git a/client/images/flagKit/TG.svg b/client/images/flagKit/TG.svg
new file mode 100644
index 00000000..e9f6360f
--- /dev/null
+++ b/client/images/flagKit/TG.svg
@@ -0,0 +1,33 @@
+
+
\ No newline at end of file
diff --git a/client/images/flagKit/TH.svg b/client/images/flagKit/TH.svg
new file mode 100644
index 00000000..1bf403a2
--- /dev/null
+++ b/client/images/flagKit/TH.svg
@@ -0,0 +1,29 @@
+
+
\ No newline at end of file
diff --git a/client/images/flagKit/TJ.svg b/client/images/flagKit/TJ.svg
new file mode 100644
index 00000000..77d6728b
--- /dev/null
+++ b/client/images/flagKit/TJ.svg
@@ -0,0 +1,29 @@
+
+
\ No newline at end of file
diff --git a/client/images/flagKit/TK.svg b/client/images/flagKit/TK.svg
new file mode 100644
index 00000000..3cde9608
--- /dev/null
+++ b/client/images/flagKit/TK.svg
@@ -0,0 +1,31 @@
+
+
\ No newline at end of file
diff --git a/client/images/flagKit/TL.svg b/client/images/flagKit/TL.svg
new file mode 100644
index 00000000..41b89521
--- /dev/null
+++ b/client/images/flagKit/TL.svg
@@ -0,0 +1,33 @@
+
+
\ No newline at end of file
diff --git a/client/images/flagKit/TM.svg b/client/images/flagKit/TM.svg
new file mode 100644
index 00000000..dac62a13
--- /dev/null
+++ b/client/images/flagKit/TM.svg
@@ -0,0 +1,74 @@
+
+
\ No newline at end of file
diff --git a/client/images/flagKit/TN.svg b/client/images/flagKit/TN.svg
new file mode 100644
index 00000000..3ff74a9e
--- /dev/null
+++ b/client/images/flagKit/TN.svg
@@ -0,0 +1,23 @@
+
+
\ No newline at end of file
diff --git a/client/images/flagKit/TO.svg b/client/images/flagKit/TO.svg
new file mode 100644
index 00000000..e0e42ee2
--- /dev/null
+++ b/client/images/flagKit/TO.svg
@@ -0,0 +1,28 @@
+
+
\ No newline at end of file
diff --git a/client/images/flagKit/TR.svg b/client/images/flagKit/TR.svg
new file mode 100644
index 00000000..e5c0924d
--- /dev/null
+++ b/client/images/flagKit/TR.svg
@@ -0,0 +1,23 @@
+
+
\ No newline at end of file
diff --git a/client/images/flagKit/TT.svg b/client/images/flagKit/TT.svg
new file mode 100644
index 00000000..69bdb9a9
--- /dev/null
+++ b/client/images/flagKit/TT.svg
@@ -0,0 +1,28 @@
+
+
\ No newline at end of file
diff --git a/client/images/flagKit/TV.svg b/client/images/flagKit/TV.svg
new file mode 100644
index 00000000..839c97f1
--- /dev/null
+++ b/client/images/flagKit/TV.svg
@@ -0,0 +1,36 @@
+
+
\ No newline at end of file
diff --git a/client/images/flagKit/TW.svg b/client/images/flagKit/TW.svg
new file mode 100644
index 00000000..488d1120
--- /dev/null
+++ b/client/images/flagKit/TW.svg
@@ -0,0 +1,28 @@
+
+
\ No newline at end of file
diff --git a/client/images/flagKit/TZ.svg b/client/images/flagKit/TZ.svg
new file mode 100644
index 00000000..d652e211
--- /dev/null
+++ b/client/images/flagKit/TZ.svg
@@ -0,0 +1,37 @@
+
+
\ No newline at end of file
diff --git a/client/images/flagKit/UA.svg b/client/images/flagKit/UA.svg
new file mode 100644
index 00000000..8dac8366
--- /dev/null
+++ b/client/images/flagKit/UA.svg
@@ -0,0 +1,27 @@
+
+
\ No newline at end of file
diff --git a/client/images/flagKit/UG.svg b/client/images/flagKit/UG.svg
new file mode 100644
index 00000000..7fabd77c
--- /dev/null
+++ b/client/images/flagKit/UG.svg
@@ -0,0 +1,37 @@
+
+
\ No newline at end of file
diff --git a/client/images/flagKit/UM.svg b/client/images/flagKit/UM.svg
new file mode 100644
index 00000000..1a8fc6a7
--- /dev/null
+++ b/client/images/flagKit/UM.svg
@@ -0,0 +1,28 @@
+
+
\ No newline at end of file
diff --git a/client/images/flagKit/US.svg b/client/images/flagKit/US.svg
new file mode 100644
index 00000000..846ec9d2
--- /dev/null
+++ b/client/images/flagKit/US.svg
@@ -0,0 +1,28 @@
+
+
\ No newline at end of file
diff --git a/client/images/flagKit/UY.svg b/client/images/flagKit/UY.svg
new file mode 100644
index 00000000..81c28154
--- /dev/null
+++ b/client/images/flagKit/UY.svg
@@ -0,0 +1,29 @@
+
+
\ No newline at end of file
diff --git a/client/images/flagKit/UZ.svg b/client/images/flagKit/UZ.svg
new file mode 100644
index 00000000..f6cf2140
--- /dev/null
+++ b/client/images/flagKit/UZ.svg
@@ -0,0 +1,29 @@
+
+
\ No newline at end of file
diff --git a/client/images/flagKit/VA.svg b/client/images/flagKit/VA.svg
new file mode 100644
index 00000000..14c78aaa
--- /dev/null
+++ b/client/images/flagKit/VA.svg
@@ -0,0 +1,39 @@
+
+
\ No newline at end of file
diff --git a/client/images/flagKit/VC.svg b/client/images/flagKit/VC.svg
new file mode 100644
index 00000000..22cc1d53
--- /dev/null
+++ b/client/images/flagKit/VC.svg
@@ -0,0 +1,37 @@
+
+
\ No newline at end of file
diff --git a/client/images/flagKit/VE.svg b/client/images/flagKit/VE.svg
new file mode 100644
index 00000000..1a14634f
--- /dev/null
+++ b/client/images/flagKit/VE.svg
@@ -0,0 +1,33 @@
+
+
\ No newline at end of file
diff --git a/client/images/flagKit/VG.svg b/client/images/flagKit/VG.svg
new file mode 100644
index 00000000..c3c31ed1
--- /dev/null
+++ b/client/images/flagKit/VG.svg
@@ -0,0 +1,42 @@
+
+
\ No newline at end of file
diff --git a/client/images/flagKit/VI.svg b/client/images/flagKit/VI.svg
new file mode 100644
index 00000000..071cf62c
--- /dev/null
+++ b/client/images/flagKit/VI.svg
@@ -0,0 +1,49 @@
+
+
\ No newline at end of file
diff --git a/client/images/flagKit/VN.svg b/client/images/flagKit/VN.svg
new file mode 100644
index 00000000..2bb79564
--- /dev/null
+++ b/client/images/flagKit/VN.svg
@@ -0,0 +1,27 @@
+
+
\ No newline at end of file
diff --git a/client/images/flagKit/VU.svg b/client/images/flagKit/VU.svg
new file mode 100644
index 00000000..26e02981
--- /dev/null
+++ b/client/images/flagKit/VU.svg
@@ -0,0 +1,38 @@
+
+
\ No newline at end of file
diff --git a/client/images/flagKit/WF.svg b/client/images/flagKit/WF.svg
new file mode 100644
index 00000000..26a5e414
--- /dev/null
+++ b/client/images/flagKit/WF.svg
@@ -0,0 +1,28 @@
+
+
\ No newline at end of file
diff --git a/client/images/flagKit/WS.svg b/client/images/flagKit/WS.svg
new file mode 100644
index 00000000..756c78f5
--- /dev/null
+++ b/client/images/flagKit/WS.svg
@@ -0,0 +1,28 @@
+
+
\ No newline at end of file
diff --git a/client/images/flagKit/XK.svg b/client/images/flagKit/XK.svg
new file mode 100644
index 00000000..a9c245fd
--- /dev/null
+++ b/client/images/flagKit/XK.svg
@@ -0,0 +1,28 @@
+
+
\ No newline at end of file
diff --git a/client/images/flagKit/YE.svg b/client/images/flagKit/YE.svg
new file mode 100644
index 00000000..535406f9
--- /dev/null
+++ b/client/images/flagKit/YE.svg
@@ -0,0 +1,28 @@
+
+
\ No newline at end of file
diff --git a/client/images/flagKit/YT.svg b/client/images/flagKit/YT.svg
new file mode 100644
index 00000000..be67985d
--- /dev/null
+++ b/client/images/flagKit/YT.svg
@@ -0,0 +1,77 @@
+
+
\ No newline at end of file
diff --git a/client/images/flagKit/ZA.svg b/client/images/flagKit/ZA.svg
new file mode 100644
index 00000000..f3ad3726
--- /dev/null
+++ b/client/images/flagKit/ZA.svg
@@ -0,0 +1,44 @@
+
+
\ No newline at end of file
diff --git a/client/images/flagKit/ZM.svg b/client/images/flagKit/ZM.svg
new file mode 100644
index 00000000..3e6f42a8
--- /dev/null
+++ b/client/images/flagKit/ZM.svg
@@ -0,0 +1,42 @@
+
+
\ No newline at end of file
diff --git a/client/images/flagKit/ZW.svg b/client/images/flagKit/ZW.svg
new file mode 100644
index 00000000..dfaf1f3f
--- /dev/null
+++ b/client/images/flagKit/ZW.svg
@@ -0,0 +1,43 @@
+
+
\ No newline at end of file
diff --git a/client/images/folder.png b/client/images/folder.png
deleted file mode 100644
index 07407596..00000000
Binary files a/client/images/folder.png and /dev/null differ
diff --git a/client/images/icon_src.png b/client/images/icon_src.png
deleted file mode 100644
index 1201a89a..00000000
Binary files a/client/images/icon_src.png and /dev/null differ
diff --git a/client/images/icon_src.svg b/client/images/icon_src.svg
deleted file mode 100644
index b27d1360..00000000
--- a/client/images/icon_src.svg
+++ /dev/null
@@ -1,67 +0,0 @@
-
-
-
diff --git a/client/images/settings.png b/client/images/settings.png
deleted file mode 100644
index a64c6116..00000000
Binary files a/client/images/settings.png and /dev/null differ
diff --git a/client/images/settings_grey.png b/client/images/settings_grey.png
deleted file mode 100644
index 60127b5c..00000000
Binary files a/client/images/settings_grey.png and /dev/null differ
diff --git a/client/images/share.png b/client/images/share.png
deleted file mode 100644
index e1451e06..00000000
Binary files a/client/images/share.png and /dev/null differ
diff --git a/client/images/svg/close_black_24dp.svg b/client/images/svg/close_black_24dp.svg
deleted file mode 100644
index 5f1267d7..00000000
--- a/client/images/svg/close_black_24dp.svg
+++ /dev/null
@@ -1 +0,0 @@
-
\ No newline at end of file
diff --git a/client/images/svg/control_point_black_24dp.svg b/client/images/svg/control_point_black_24dp.svg
deleted file mode 100644
index 75b25e67..00000000
--- a/client/images/svg/control_point_black_24dp.svg
+++ /dev/null
@@ -1 +0,0 @@
-
\ No newline at end of file
diff --git a/client/images/svg/delete_black_24dp.svg b/client/images/svg/delete_black_24dp.svg
deleted file mode 100644
index 69a68354..00000000
--- a/client/images/svg/delete_black_24dp.svg
+++ /dev/null
@@ -1 +0,0 @@
-
\ No newline at end of file
diff --git a/client/images/svg/density_small_black_24dp.svg b/client/images/svg/density_small_black_24dp.svg
deleted file mode 100644
index f79483de..00000000
--- a/client/images/svg/density_small_black_24dp.svg
+++ /dev/null
@@ -1 +0,0 @@
-
\ No newline at end of file
diff --git a/client/images/svg/done_black_24dp.svg b/client/images/svg/done_black_24dp.svg
deleted file mode 100644
index b7e19d35..00000000
--- a/client/images/svg/done_black_24dp.svg
+++ /dev/null
@@ -1 +0,0 @@
-
\ No newline at end of file
diff --git a/client/images/svg/format_list_bulleted_black_24dp.svg b/client/images/svg/format_list_bulleted_black_24dp.svg
deleted file mode 100644
index 21821a14..00000000
--- a/client/images/svg/format_list_bulleted_black_24dp.svg
+++ /dev/null
@@ -1 +0,0 @@
-
\ No newline at end of file
diff --git a/client/images/svg/gpp_good_black_24dp.svg b/client/images/svg/gpp_good_black_24dp.svg
deleted file mode 100644
index 45d4a819..00000000
--- a/client/images/svg/gpp_good_black_24dp.svg
+++ /dev/null
@@ -1 +0,0 @@
-
\ No newline at end of file
diff --git a/client/images/svg/gpp_maybe_black_24dp.svg b/client/images/svg/gpp_maybe_black_24dp.svg
deleted file mode 100644
index dceeac79..00000000
--- a/client/images/svg/gpp_maybe_black_24dp.svg
+++ /dev/null
@@ -1 +0,0 @@
-
\ No newline at end of file
diff --git a/client/images/svg/logout_black_24dp.svg b/client/images/svg/logout_black_24dp.svg
deleted file mode 100644
index 1b785f84..00000000
--- a/client/images/svg/logout_black_24dp.svg
+++ /dev/null
@@ -1 +0,0 @@
-
\ No newline at end of file
diff --git a/client/images/svg/miscellaneous_services_black_24dp.svg b/client/images/svg/miscellaneous_services_black_24dp.svg
deleted file mode 100644
index 425990e5..00000000
--- a/client/images/svg/miscellaneous_services_black_24dp.svg
+++ /dev/null
@@ -1 +0,0 @@
-
\ No newline at end of file
diff --git a/client/images/svg/refresh_black_24dp.svg b/client/images/svg/refresh_black_24dp.svg
deleted file mode 100644
index f31411f5..00000000
--- a/client/images/svg/refresh_black_24dp.svg
+++ /dev/null
@@ -1 +0,0 @@
-
\ No newline at end of file
diff --git a/client/images/svg/settings_black_24dp.svg b/client/images/svg/settings_black_24dp.svg
deleted file mode 100644
index 4165162b..00000000
--- a/client/images/svg/settings_black_24dp.svg
+++ /dev/null
@@ -1 +0,0 @@
-
\ No newline at end of file
diff --git a/client/images/svg/settings_suggest_black_24dp.svg b/client/images/svg/settings_suggest_black_24dp.svg
deleted file mode 100644
index 80053d0e..00000000
--- a/client/images/svg/settings_suggest_black_24dp.svg
+++ /dev/null
@@ -1 +0,0 @@
-
\ No newline at end of file
diff --git a/client/images/svg/share_black_24dp.svg b/client/images/svg/share_black_24dp.svg
deleted file mode 100644
index 4c5fa323..00000000
--- a/client/images/svg/share_black_24dp.svg
+++ /dev/null
@@ -1 +0,0 @@
-
\ No newline at end of file
diff --git a/client/images/svg/vpn_key_black_24dp.svg b/client/images/svg/vpn_key_black_24dp.svg
deleted file mode 100644
index 2c18df46..00000000
--- a/client/images/svg/vpn_key_black_24dp.svg
+++ /dev/null
@@ -1 +0,0 @@
-
\ No newline at end of file
diff --git a/client/images/uncheck.png b/client/images/uncheck.png
deleted file mode 100644
index b6723a44..00000000
Binary files a/client/images/uncheck.png and /dev/null differ
diff --git a/client/images/upload.png b/client/images/upload.png
deleted file mode 100644
index 185e7a7b..00000000
Binary files a/client/images/upload.png and /dev/null differ
diff --git a/client/logger.cpp b/client/logger.cpp
index 0dc836c6..c76bc698 100644
--- a/client/logger.cpp
+++ b/client/logger.cpp
@@ -99,6 +99,29 @@ void Logger::deInit()
m_file.close();
}
+bool Logger::setServiceLogsEnabled(bool enabled) {
+#ifdef AMNEZIA_DESKTOP
+ IpcClient *m_IpcClient = new IpcClient;
+
+ if (!m_IpcClient->isSocketConnected()) {
+ if (!IpcClient::init(m_IpcClient)) {
+ qWarning() << "Error occurred when init IPC client";
+ return false;
+ }
+ }
+
+ if (m_IpcClient->Interface()) {
+ m_IpcClient->Interface()->setLogsEnabled(enabled);
+ }
+ else {
+ qWarning() << "Error occurred setting up service logs";
+ return false;
+ }
+#endif
+
+ return true;
+}
+
QString Logger::userLogsDir()
{
return QStandardPaths::writableLocation(QStandardPaths::AppDataLocation) + "/log";
@@ -141,7 +164,9 @@ bool Logger::openLogsFolder()
bool Logger::openServiceLogsFolder()
{
QString path = Utils::systemLogPath();
+#ifdef Q_OS_WIN
path = "file:///" + path;
+#endif
QDesktopServices::openUrl(QUrl::fromLocalFile(path));
return true;
}
@@ -184,8 +209,7 @@ void Logger::clearServiceLogs()
}
if (m_IpcClient->Interface()) {
- m_IpcClient->Interface()->setLogsEnabled(false);
- m_IpcClient->Interface()->cleanUp();
+ m_IpcClient->Interface()->clearLogs();
}
else {
qWarning() << "Error occurred cleaning up service logs";
diff --git a/client/logger.h b/client/logger.h
index f8bfc225..0dcbd35c 100644
--- a/client/logger.h
+++ b/client/logger.h
@@ -26,6 +26,7 @@ public:
static bool init();
static void deInit();
+ static bool setServiceLogsEnabled(bool enabled);
static bool openLogsFolder();
static bool openServiceLogsFolder();
static QString appLogFileNamePath();
diff --git a/client/platforms/android/android_controller.cpp b/client/platforms/android/android_controller.cpp
index be404a15..c9ee3cfd 100644
--- a/client/platforms/android/android_controller.cpp
+++ b/client/platforms/android/android_controller.cpp
@@ -179,6 +179,11 @@ bool AndroidController::isCameraPresent()
return callActivityMethod("isCameraPresent", "()Z");
}
+bool AndroidController::isOnTv()
+{
+ return callActivityMethod("isOnTv", "()Z");
+}
+
void AndroidController::startQrReaderActivity()
{
callActivityMethod("startQrCodeReader", "()V");
diff --git a/client/platforms/android/android_controller.h b/client/platforms/android/android_controller.h
index d015dbe3..1041c31f 100644
--- a/client/platforms/android/android_controller.h
+++ b/client/platforms/android/android_controller.h
@@ -35,6 +35,7 @@ public:
void saveFile(const QString &fileName, const QString &data);
QString openFile(const QString &filter);
bool isCameraPresent();
+ bool isOnTv();
void startQrReaderActivity();
void setSaveLogs(bool enabled);
void exportLogsFile(const QString &fileName);
diff --git a/client/platforms/windows/windowsservicemanager.h b/client/platforms/windows/windowsservicemanager.h
index e0709309..7638588f 100644
--- a/client/platforms/windows/windowsservicemanager.h
+++ b/client/platforms/windows/windowsservicemanager.h
@@ -12,7 +12,7 @@
#include "Winsvc.h"
/**
- * @brief The WindowsServiceManager provides controll over the MozillaVPNBroker
+ * @brief The WindowsServiceManager provides control over the MozillaVPNBroker
* service via SCM
*/
class WindowsServiceManager : public QObject {
diff --git a/client/protocols/ikev2_vpn_protocol_windows.cpp b/client/protocols/ikev2_vpn_protocol_windows.cpp
index ed6fb174..2c753c8a 100644
--- a/client/protocols/ikev2_vpn_protocol_windows.cpp
+++ b/client/protocols/ikev2_vpn_protocol_windows.cpp
@@ -206,8 +206,8 @@ ErrorCode Ikev2Protocol::start()
certInstallProcess->setProgram(PermittedProcess::CertUtil);
QStringList arguments({"-f", "-importpfx", "-p", m_config[config_key::password].toString(),
- QDir::toNativeSeparators(m_filename), "NoExport"
- });
+ QDir::toNativeSeparators(m_filename), "NoExport"
+ });
certInstallProcess->setArguments(arguments);
certInstallProcess->start();
@@ -223,40 +223,40 @@ ErrorCode Ikev2Protocol::start()
}
{
- {
- if ( !create_new_vpn(tunnelName(), m_config[config_key::hostName].toString())){
- qDebug() <<"Can't create the VPN connect";
- }
- }
- }
+ {
+ if ( !create_new_vpn(tunnelName(), m_config[config_key::hostName].toString())){
+ qDebug() <<"Can't create the VPN connect";
+}
+}
+}
- {
- QProcess adapterConfigProcess;
- adapterConfigProcess.setProgram("powershell");
- QString arguments = QString("-command \"Set-VpnConnectionIPsecConfiguration\" "
- "-ConnectionName '%1' "
- "-AuthenticationTransformConstants GCMAES128 "
- "-CipherTransformConstants GCMAES128 "
- "-EncryptionMethod AES256 "
- "-IntegrityCheckMethod SHA256 "
- "-PfsGroup None "
- "-DHGroup Group14 "
- "-PassThru -Force\"")
- .arg(tunnelName());
+{
+ QProcess adapterConfigProcess;
+ adapterConfigProcess.setProgram("powershell");
+ QString arguments = QString("-command \"Set-VpnConnectionIPsecConfiguration\" "
+ "-ConnectionName '%1' "
+ "-AuthenticationTransformConstants GCMAES128 "
+ "-CipherTransformConstants GCMAES128 "
+ "-EncryptionMethod AES256 "
+ "-IntegrityCheckMethod SHA256 "
+ "-PfsGroup None "
+ "-DHGroup Group14 "
+ "-PassThru -Force\"")
+ .arg(tunnelName());
- adapterConfigProcess.setNativeArguments(arguments);
+ adapterConfigProcess.setNativeArguments(arguments);
- adapterConfigProcess.start();
- adapterConfigProcess.waitForFinished(5000);
+ adapterConfigProcess.start();
+ adapterConfigProcess.waitForFinished(5000);
+}
+//*/
+{
+ if (!connect_to_vpn(tunnelName())) {
+ qDebug()<<"We can't connect to VPN";
}
- //*/
- {
- if (!connect_to_vpn(tunnelName())) {
- qDebug()<<"We can't connect to VPN";
- }
- }
- //setConnectionState(Connecting);
- return ErrorCode::NoError;
+}
+//setConnectionState(Connecting);
+return ErrorCode::NoError;
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
bool Ikev2Protocol::create_new_vpn(const QString & vpn_name,
diff --git a/client/protocols/protocols_defs.cpp b/client/protocols/protocols_defs.cpp
index 9be5a75f..ac5bb1ad 100644
--- a/client/protocols/protocols_defs.cpp
+++ b/client/protocols/protocols_defs.cpp
@@ -65,14 +65,14 @@ QString ProtocolProps::transportProtoToString(TransportProto proto, Proto p)
QMap ProtocolProps::protocolHumanNames()
{
return { { Proto::OpenVpn, "OpenVPN" },
- { Proto::ShadowSocks, "ShadowSocks" },
+ { Proto::ShadowSocks, "Shadowsocks" },
{ Proto::Cloak, "Cloak" },
{ Proto::WireGuard, "WireGuard" },
{ Proto::Awg, "AmneziaWG" },
{ Proto::Ikev2, "IKEv2" },
{ Proto::L2tp, "L2TP" },
{ Proto::Xray, "XRay" },
- { Proto::SSXray, "ShadowSocks"},
+ { Proto::SSXray, "Shadowsocks"},
{ Proto::TorWebSite, "Website in Tor network" },
@@ -154,6 +154,7 @@ bool ProtocolProps::defaultPortChangeable(Proto p)
case Proto::Awg: return true;
case Proto::Ikev2: return false;
case Proto::L2tp: return false;
+ case Proto::Xray: return true;
case Proto::TorWebSite: return false;
case Proto::Dns: return false;
diff --git a/client/resources.qrc b/client/resources.qrc
index a12b0805..5001f2cb 100644
--- a/client/resources.qrc
+++ b/client/resources.qrc
@@ -1,18 +1,9 @@
- images/close.png
- images/settings.png
- images/favorites_disabled.png
- images/favorites_enabled.png
- images/favorites_hover.png
- images/download.png
- images/upload.pngimages/tray/active.pngimages/tray/default.pngimages/tray/error.png
- images/arrow_left.pngimages/AmneziaVPN.png
- images/share.pngserver_scripts/remove_container.shserver_scripts/setup_host_firewall.shserver_scripts/openvpn_cloak/Dockerfile
@@ -22,9 +13,6 @@
server_scripts/install_docker.shserver_scripts/build_container.shserver_scripts/prepare_host.sh
- images/check.png
- images/uncheck.png
- images/settings_grey.pngserver_scripts/check_connection.shserver_scripts/remove_all_containers.shserver_scripts/openvpn_cloak/run_container.sh
@@ -38,7 +26,6 @@
server_scripts/openvpn_shadowsocks/run_container.shserver_scripts/openvpn_shadowsocks/start.shserver_scripts/openvpn_shadowsocks/template.ovpn
- images/folder.pngserver_scripts/wireguard/configure_container.shserver_scripts/wireguard/Dockerfileserver_scripts/wireguard/run_container.sh
@@ -61,26 +48,6 @@
server_scripts/ipsec/start.shserver_scripts/ipsec/mobileconfig.plistserver_scripts/ipsec/strongswan.profile
- images/background_connected.png
- images/background_connected@2x.png
- images/delete.png
- images/animation.gif
- images/connected.png
- images/disconnected.png
- images/svg/gpp_good_black_24dp.svg
- images/svg/gpp_maybe_black_24dp.svg
- images/svg/close_black_24dp.svg
- images/svg/delete_black_24dp.svg
- images/svg/done_black_24dp.svg
- images/svg/format_list_bulleted_black_24dp.svg
- images/svg/logout_black_24dp.svg
- images/svg/miscellaneous_services_black_24dp.svg
- images/svg/refresh_black_24dp.svg
- images/svg/settings_black_24dp.svg
- images/svg/share_black_24dp.svg
- images/svg/vpn_key_black_24dp.svg
- images/svg/control_point_black_24dp.svg
- images/svg/settings_suggest_black_24dp.svgserver_scripts/website_tor/Dockerfileserver_scripts/check_user_in_sudo.shui/qml/Controls2/BasicButtonType.qml
@@ -96,7 +63,6 @@
ui/qml/Pages2/PageSetupWizardStart.qmlui/qml/main2.qmlimages/amneziaBigLogo.png
- images/amneziaBigLogo.svgui/qml/Controls2/FlickableType.qmlui/qml/Pages2/PageSetupWizardCredentials.qmlui/qml/Controls2/HeaderType.qml
@@ -132,9 +98,6 @@
ui/qml/Controls2/Header2Type.qmlimages/controls/plus.svgui/qml/Components/ConnectButton.qml
- images/connectionProgress.svg
- images/connectionOff.svg
- images/connectionOn.svgimages/controls/download.svgui/qml/Controls2/ProgressBarType.qmlui/qml/Components/ConnectionTypeSelectionDrawer.qml
@@ -237,5 +200,274 @@
server_scripts/socks5_proxy/configure_container.shserver_scripts/socks5_proxy/start.shserver_scripts/ipsec/template.conf
+ ui/qml/Pages2/PageSetupWizardApiServicesList.qml
+ ui/qml/Pages2/PageSetupWizardApiServiceInfo.qml
+ ui/qml/Controls2/CardWithIconsType.qml
+ images/controls/tag.svg
+ images/controls/history.svg
+ images/controls/gauge.svg
+ images/controls/map-pin.svg
+ ui/qml/Controls2/LabelWithImageType.qml
+ images/controls/info.svg
+ ui/qml/Controls2/TextAreaWithFooterType.qml
+ images/controls/scan-line.svg
+ images/controls/folder-search-2.svg
+ ui/qml/Pages2/PageSettingsApiServerInfo.qml
+ images/controls/bug.svg
+ ui/qml/Pages2/PageDevMenu.qml
+ images/controls/refresh-cw.svg
+ ui/qml/Pages2/PageSettingsApiLanguageList.qml
+ images/controls/archive-restore.svg
+ images/controls/help-circle.svg
+
+
+ images/flagKit/ZW.svg
+ images/flagKit/ZM.svg
+ images/flagKit/ZA.svg
+ images/flagKit/YT.svg
+ images/flagKit/YE.svg
+ images/flagKit/XK.svg
+ images/flagKit/WS.svg
+ images/flagKit/WF.svg
+ images/flagKit/VU.svg
+ images/flagKit/VN.svg
+ images/flagKit/VI.svg
+ images/flagKit/VG.svg
+ images/flagKit/VE.svg
+ images/flagKit/VC.svg
+ images/flagKit/VA.svg
+ images/flagKit/UZ.svg
+ images/flagKit/UY.svg
+ images/flagKit/US.svg
+ images/flagKit/UM.svg
+ images/flagKit/UG.svg
+ images/flagKit/UA.svg
+ images/flagKit/TZ.svg
+ images/flagKit/TW.svg
+ images/flagKit/TV.svg
+ images/flagKit/TT.svg
+ images/flagKit/TR.svg
+ images/flagKit/TO.svg
+ images/flagKit/TN.svg
+ images/flagKit/TM.svg
+ images/flagKit/TL.svg
+ images/flagKit/TK.svg
+ images/flagKit/TJ.svg
+ images/flagKit/TH.svg
+ images/flagKit/TG.svg
+ images/flagKit/TF.svg
+ images/flagKit/TD.svg
+ images/flagKit/TC.svg
+ images/flagKit/SZ.svg
+ images/flagKit/SY.svg
+ images/flagKit/SX.svg
+ images/flagKit/SV.svg
+ images/flagKit/ST.svg
+ images/flagKit/SS.svg
+ images/flagKit/SR.svg
+ images/flagKit/SO.svg
+ images/flagKit/SN.svg
+ images/flagKit/SM.svg
+ images/flagKit/SL.svg
+ images/flagKit/SK.svg
+ images/flagKit/SJ.svg
+ images/flagKit/SI.svg
+ images/flagKit/SH.svg
+ images/flagKit/SG.svg
+ images/flagKit/SE.svg
+ images/flagKit/SD.svg
+ images/flagKit/SC.svg
+ images/flagKit/SB.svg
+ images/flagKit/SA.svg
+ images/flagKit/RW.svg
+ images/flagKit/RU.svg
+ images/flagKit/RS.svg
+ images/flagKit/RO.svg
+ images/flagKit/RE.svg
+ images/flagKit/QA.svg
+ images/flagKit/PY.svg
+ images/flagKit/PW.svg
+ images/flagKit/PT.svg
+ images/flagKit/PS.svg
+ images/flagKit/PR.svg
+ images/flagKit/PN.svg
+ images/flagKit/PM.svg
+ images/flagKit/PL.svg
+ images/flagKit/PK.svg
+ images/flagKit/PH.svg
+ images/flagKit/PG.svg
+ images/flagKit/PF.svg
+ images/flagKit/PE.svg
+ images/flagKit/PA.svg
+ images/flagKit/OM.svg
+ images/flagKit/NZ.svg
+ images/flagKit/NU.svg
+ images/flagKit/NR.svg
+ images/flagKit/NP.svg
+ images/flagKit/NO.svg
+ images/flagKit/NL.svg
+ images/flagKit/NI.svg
+ images/flagKit/NG.svg
+ images/flagKit/NF.svg
+ images/flagKit/NE.svg
+ images/flagKit/NC.svg
+ images/flagKit/NA.svg
+ images/flagKit/MZ.svg
+ images/flagKit/MY.svg
+ images/flagKit/MX.svg
+ images/flagKit/MW.svg
+ images/flagKit/MV.svg
+ images/flagKit/MU.svg
+ images/flagKit/MT.svg
+ images/flagKit/MS.svg
+ images/flagKit/MR.svg
+ images/flagKit/MQ.svg
+ images/flagKit/MP.svg
+ images/flagKit/MO.svg
+ images/flagKit/MN.svg
+ images/flagKit/MM.svg
+ images/flagKit/ML.svg
+ images/flagKit/MK.svg
+ images/flagKit/MH.svg
+ images/flagKit/MG.svg
+ images/flagKit/MF.svg
+ images/flagKit/ME.svg
+ images/flagKit/MD.svg
+ images/flagKit/MC.svg
+ images/flagKit/MA.svg
+ images/flagKit/LY.svg
+ images/flagKit/LV.svg
+ images/flagKit/LU.svg
+ images/flagKit/LT.svg
+ images/flagKit/LS.svg
+ images/flagKit/LR.svg
+ images/flagKit/LK.svg
+ images/flagKit/LI.svg
+ images/flagKit/LC.svg
+ images/flagKit/LB.svg
+ images/flagKit/LA.svg
+ images/flagKit/KZ.svg
+ images/flagKit/KY.svg
+ images/flagKit/KW.svg
+ images/flagKit/KR.svg
+ images/flagKit/KP.svg
+ images/flagKit/KN.svg
+ images/flagKit/KM.svg
+ images/flagKit/KI.svg
+ images/flagKit/KH.svg
+ images/flagKit/KG.svg
+ images/flagKit/KE.svg
+ images/flagKit/JP.svg
+ images/flagKit/JO.svg
+ images/flagKit/JM.svg
+ images/flagKit/JE.svg
+ images/flagKit/IT.svg
+ images/flagKit/IS.svg
+ images/flagKit/IR.svg
+ images/flagKit/IQ.svg
+ images/flagKit/IO.svg
+ images/flagKit/IN.svg
+ images/flagKit/IM.svg
+ images/flagKit/IL.svg
+ images/flagKit/IE.svg
+ images/flagKit/ID.svg
+ images/flagKit/HU.svg
+ images/flagKit/HT.svg
+ images/flagKit/HR.svg
+ images/flagKit/HN.svg
+ images/flagKit/HM.svg
+ images/flagKit/HK.svg
+ images/flagKit/GY.svg
+ images/flagKit/GW.svg
+ images/flagKit/GU.svg
+ images/flagKit/GT.svg
+ images/flagKit/GS.svg
+ images/flagKit/GR.svg
+ images/flagKit/GQ.svg
+ images/flagKit/GP.svg
+ images/flagKit/GN.svg
+ images/flagKit/GM.svg
+ images/flagKit/GL.svg
+ images/flagKit/GI.svg
+ images/flagKit/GH.svg
+ images/flagKit/GG.svg
+ images/flagKit/GF.svg
+ images/flagKit/GE.svg
+ images/flagKit/GD.svg
+ images/flagKit/GB.svg
+ images/flagKit/GA.svg
+ images/flagKit/FR.svg
+ images/flagKit/FO.svg
+ images/flagKit/FM.svg
+ images/flagKit/FK.svg
+ images/flagKit/FJ.svg
+ images/flagKit/FI.svg
+ images/flagKit/EU.svg
+ images/flagKit/ET.svg
+ images/flagKit/ES.svg
+ images/flagKit/ER.svg
+ images/flagKit/EG.svg
+ images/flagKit/EE.svg
+ images/flagKit/EC.svg
+ images/flagKit/DZ.svg
+ images/flagKit/DO.svg
+ images/flagKit/DM.svg
+ images/flagKit/DK.svg
+ images/flagKit/DJ.svg
+ images/flagKit/DE.svg
+ images/flagKit/CZ.svg
+ images/flagKit/CY.svg
+ images/flagKit/CX.svg
+ images/flagKit/CW.svg
+ images/flagKit/CV.svg
+ images/flagKit/CU.svg
+ images/flagKit/CR.svg
+ images/flagKit/CO.svg
+ images/flagKit/CN.svg
+ images/flagKit/CM.svg
+ images/flagKit/CL.svg
+ images/flagKit/CK.svg
+ images/flagKit/CI.svg
+ images/flagKit/CH.svg
+ images/flagKit/CG.svg
+ images/flagKit/CF.svg
+ images/flagKit/CD.svg
+ images/flagKit/CC.svg
+ images/flagKit/CA.svg
+ images/flagKit/BZ.svg
+ images/flagKit/BY.svg
+ images/flagKit/BW.svg
+ images/flagKit/BV.svg
+ images/flagKit/BT.svg
+ images/flagKit/BS.svg
+ images/flagKit/BR.svg
+ images/flagKit/BO.svg
+ images/flagKit/BN.svg
+ images/flagKit/BM.svg
+ images/flagKit/BL.svg
+ images/flagKit/BJ.svg
+ images/flagKit/BI.svg
+ images/flagKit/BH.svg
+ images/flagKit/BG.svg
+ images/flagKit/BF.svg
+ images/flagKit/BE.svg
+ images/flagKit/BD.svg
+ images/flagKit/BB.svg
+ images/flagKit/BA.svg
+ images/flagKit/AZ.svg
+ images/flagKit/AX.svg
+ images/flagKit/AW.svg
+ images/flagKit/AU.svg
+ images/flagKit/AT.svg
+ images/flagKit/AS.svg
+ images/flagKit/AR.svg
+ images/flagKit/AO.svg
+ images/flagKit/AM.svg
+ images/flagKit/AL.svg
+ images/flagKit/AI.svg
+ images/flagKit/AG.svg
+ images/flagKit/AF.svg
+ images/flagKit/AE.svg
+ images/flagKit/AD.svg
diff --git a/client/secure_qsettings.cpp b/client/secure_qsettings.cpp
index 592f77d4..1e2a2273 100644
--- a/client/secure_qsettings.cpp
+++ b/client/secure_qsettings.cpp
@@ -185,7 +185,7 @@ QByteArray SecureQSettings::decryptText(const QByteArray &ba) const
bool SecureQSettings::encryptionRequired() const
{
-#ifdef Q_OS_LINUX
+#if defined(Q_OS_LINUX) && !defined(Q_OS_ANDROID)
// QtKeyChain failing on Linux
return false;
#endif
@@ -200,7 +200,7 @@ QByteArray SecureQSettings::getEncKey() const
if (m_key.isEmpty()) {
// Create new key
QSimpleCrypto::QBlockCipher cipher;
- QByteArray key = cipher.generateSecureRandomBytes(32);
+ QByteArray key = cipher.generatePrivateSalt(32);
if (key.isEmpty()) {
qCritical() << "SecureQSettings::getEncKey Unable to generate new enc key";
}
@@ -226,7 +226,7 @@ QByteArray SecureQSettings::getEncIv() const
if (m_iv.isEmpty()) {
// Create new IV
QSimpleCrypto::QBlockCipher cipher;
- QByteArray iv = cipher.generateSecureRandomBytes(32);
+ QByteArray iv = cipher.generatePrivateSalt(32);
if (iv.isEmpty()) {
qCritical() << "SecureQSettings::getEncIv Unable to generate new enc IV";
}
diff --git a/client/server_scripts/xray/configure_container.sh b/client/server_scripts/xray/configure_container.sh
index 541e155b..a84751c7 100644
--- a/client/server_scripts/xray/configure_container.sh
+++ b/client/server_scripts/xray/configure_container.sh
@@ -29,7 +29,7 @@ cat > /opt/amnezia/xray/server.json < Settings::containers(int serverIndex) const
QMap containersMap;
for (const QJsonValue &val : containers) {
- containersMap.insert(ContainerProps::containerFromString(val.toObject().value(config_key::container).toString()),
- val.toObject());
+ containersMap.insert(ContainerProps::containerFromString(val.toObject().value(config_key::container).toString()), val.toObject());
}
return containersMap;
@@ -226,6 +232,8 @@ void Settings::setSaveLogs(bool enabled)
}
}
#endif
+ Logger::setServiceLogsEnabled(enabled);
+
if (enabled) {
setLogEnableDate(QDateTime::currentDateTime());
}
@@ -440,6 +448,17 @@ QString Settings::getInstallationUuid(const bool needCreate)
auto uuid = value("Conf/installationUuid", "").toString();
if (needCreate && uuid.isEmpty()) {
uuid = QUuid::createUuid().toString();
+
+ //remove {} from uuid
+ uuid.remove(0, 1);
+ uuid.chop(1);
+
+ setInstallationUuid(uuid);
+ } else if (uuid.contains("{") && uuid.contains("}")) {
+ //remove {} from old uuid
+ uuid.remove(0, 1);
+ uuid.chop(1);
+
setInstallationUuid(uuid);
}
return uuid;
@@ -474,11 +493,8 @@ QVariant Settings::value(const QString &key, const QVariant &defaultValue) const
if (QThread::currentThread() == QCoreApplication::instance()->thread()) {
returnValue = m_settings.value(key, defaultValue);
} else {
- QMetaObject::invokeMethod(&m_settings, "value",
- Qt::BlockingQueuedConnection,
- Q_RETURN_ARG(QVariant, returnValue),
- Q_ARG(const QString&, key),
- Q_ARG(const QVariant&, defaultValue));
+ QMetaObject::invokeMethod(&m_settings, "value", Qt::BlockingQueuedConnection, Q_RETURN_ARG(QVariant, returnValue),
+ Q_ARG(const QString &, key), Q_ARG(const QVariant &, defaultValue));
}
return returnValue;
}
@@ -488,9 +504,22 @@ void Settings::setValue(const QString &key, const QVariant &value)
if (QThread::currentThread() == QCoreApplication::instance()->thread()) {
m_settings.setValue(key, value);
} else {
- QMetaObject::invokeMethod(&m_settings, "setValue",
- Qt::BlockingQueuedConnection,
- Q_ARG(const QString&, key),
- Q_ARG(const QVariant&, value));
+ QMetaObject::invokeMethod(&m_settings, "setValue", Qt::BlockingQueuedConnection, Q_ARG(const QString &, key),
+ Q_ARG(const QVariant &, value));
}
}
+
+void Settings::resetGatewayEndpoint()
+{
+ m_gatewayEndpoint = gatewayEndpoint;
+}
+
+void Settings::setGatewayEndpoint(const QString &endpoint)
+{
+ m_gatewayEndpoint = endpoint;
+}
+
+QString Settings::getGatewayEndpoint()
+{
+ return m_gatewayEndpoint;
+}
diff --git a/client/settings.h b/client/settings.h
index 74d1b4b9..ee10c3b8 100644
--- a/client/settings.h
+++ b/client/settings.h
@@ -160,9 +160,6 @@ public:
setValue("Conf/secondaryDns", secondaryDns);
}
- static const char cloudFlareNs1[];
- static const char cloudFlareNs2[];
-
// static constexpr char openNicNs5[] = "94.103.153.176";
// static constexpr char openNicNs13[] = "144.76.103.143";
@@ -218,6 +215,10 @@ public:
void setKillSwitchEnabled(bool enabled);
QString getInstallationUuid(const bool needCreate);
+ void resetGatewayEndpoint();
+ void setGatewayEndpoint(const QString &endpoint);
+ QString getGatewayEndpoint();
+
signals:
void saveLogsChanged(bool enabled);
void screenshotsEnabledChanged(bool enabled);
@@ -231,6 +232,8 @@ private:
void setInstallationUuid(const QString &uuid);
mutable SecureQSettings m_settings;
+
+ QString m_gatewayEndpoint;
};
#endif // SETTINGS_H
diff --git a/client/translations/amneziavpn_ar_EG.ts b/client/translations/amneziavpn_ar_EG.ts
index 9e101c2d..42ea2720 100644
--- a/client/translations/amneziavpn_ar_EG.ts
+++ b/client/translations/amneziavpn_ar_EG.ts
@@ -1,97 +1,145 @@
+
+ ApiServicesModel
+
+
+ Classic VPN for comfortable work, downloading large files and watching videos. Works for any sites. Speed up to %1 MBit/s
+
+
+
+
+ VPN to access blocked sites in regions with high levels of Internet censorship.
+
+
+
+
+ Amnezia Premium - A classic VPN for comfortable work, downloading large files, and watching videos in high resolution. It works for all websites, even in countries with the highest level of internet censorship.
+
+
+
+
+ Amnezia Free is a free VPN to bypass blocking in countries with high levels of internet censorship
+
+
+
+
+ %1 MBit/s
+
+
+
+
+ %1 days
+
+
+
+
+ VPN will open only popular sites blocked in your region, such as Instagram, Facebook, Twitter and others. Other sites will be opened from your real IP address, <a href="%1/free" style="color: #FBB26A;">more details on the website.</a>
+
+
+
+
+ Free
+
+
+
+
+ %1 $/month
+
+
+AppSplitTunnelingControllerApplication added: %1
-
+ تمت إضافة التطبيق: %1The application has already been added
-
+ التطبيق مٌضاف بالفعلThe selected applications have been added
-
+ تمت إضافة التطبيقات المٌختارةApplication removed: %1
-
+ تم حذف التطبيق: %1ConnectButton
-
+ Unable to disconnect during configuration preparation
-
+ غير قادر علي قطع الاتصال اثناء إعداد التكوينConnectionController
-
-
-
+
+
+ Connectاتصل
-
+ VPN Protocols is not installed.
Please install VPN container at firstلم يتم تثبيت بروتوكولات VPN, من فضلك قم بتنزيل حاوية VPN اولاً
-
+ Connecting...اتصال...
-
+ Connectedتم الاتصال
-
+ Reconnecting...إعادة الاتصال...
-
+ Disconnecting...إنهاء الاتصال...
-
+ Preparing...
-
+ جاري التحضير...
-
+ Settings updated successfully, reconnnection...تم تحديث الاعدادات بنجاح, جاري إعادة الاتصال...
-
+ Settings updated successfullyتم تحديث الاعدادات بنجاح
-
+ The selected protocol is not supported on the current platform
- البروتوكول المحدد غير مدعوم علي المنصة الحالية
+ البروتوكول المحدد غير مدعوم علي المنصة الحالية
-
+ unable to create configuration
-
+ غير قادر علي إنشاء تكوين
@@ -130,7 +178,7 @@
&لصق
-
+ &SelectAll&تحديد الكل
@@ -148,11 +196,7 @@
Unable change protocol while there is an active connection
- قم بتغيير البروتوكول عند تواجد اتصال
-
-
- The selected protocol is not supported on the current platform
- البروتوكول المحدد غير مدعوم علي المنصة الحالية
+ غير قادر علي تغيير البروتوكول اثناء تواجد اتصال
@@ -207,13 +251,13 @@ Can't be disabled for current server
Unable to open file
-
+ غير قادر علي فتح الملفInvalid configuration file
-
+ ملف تكوين غير صحيح
@@ -223,38 +267,30 @@ Can't be disabled for current server
In the imported configuration, potentially dangerous lines were found:
-
+ في التكوين المستورد، تم العثور على سطور يحتمل أن تكون خطرة:InstallController
- installed successfully.
- تم التثبيت بنجاح
-
-
- is already installed on the server.
- بالفعل مٌثبت علي الخادم
-
-
-
+ %1 installed successfully. %1 تم التثبيت بنجاح.
-
+ %1 is already installed on the server. %1 بالفعل مٌثبت علي الخادم.
-
+
Added containers that were already installed on the server
تمت إضافة الحاويات التي كانت مٌثبتة بالفعل علي الخادم
-
+
Already installed containers were found on the server. All installed containers have been added to the application
@@ -262,78 +298,82 @@ Already installed containers were found on the server. All installed containers
تمت إضافة جميع الحاويات المٌثبتة إلي التطبيق
-
+ Settings updated successfullyتم تحديث الاعدادات بنجاح
-
+ Server '%1' was rebootedتمت إعادة تشغيل الخادم%1
-
+ Server '%1' was removedتمت إزالة الخادم '%1'
-
+ All containers from server '%1' have been removedقد تم حذفها '%1' جميع الحاويات من الخادم
-
+ %1 has been removed from the server '%2'%1 تم حدف '%2' اسم الخادم
-
- %1 cached profile cleared
+
+ Api config removed
- 1% has been removed from the server '%2'
- %1 من الخادم '%2' تم مسحة
+
+ %1 cached profile cleared
+ تم مسح ملف تعريف %1 المخزن مؤقتًا
- Server '
- خادم
-
-
- ' was removed
- تم حذفة
-
-
- has been removed from the server '
- قد تمت إزالتة من الخادم
-
-
-
+ Please login as the userمن فضلك قم بتسجيل الدخول كمستخدم
-
+ Server added successfullyتمت إضافة الخادم بنجاح
+
+
+ %1 installed successfully.
+
+
+
+
+ API config reloaded
+
+
+
+
+ Successfully changed the country of connection to %1
+
+ InstalledAppsDrawer
-
+ Choose application
-
+ اختر تطبيق
-
+ application name
-
+ اسم التطبيق
-
+ Add selected
-
+ اضف اختيارك
@@ -386,45 +426,53 @@ Already installed containers were found on the server. All installed containers
PageDeinstalling
-
+ Removing services from %1من %1 مسح الخدمة
-
+ Usually it takes no more than 5 minutesفي العادة تستغرق اقل من 5 دقائق
- PageHome
+ PageDevMenu
-
- Logging enabled
+
+ Gateway endpoint
+
+
+ PageHome
-
+
+ Logging enabled
+ تم تمكين التسجيل
+
+
+ Split tunneling enabledتقسيم الانفاق مٌفعل
-
+ Split tunneling disabledتقسيم الانفاق مٌعطل
-
+ VPN protocolبروتوكول VPN
-
+ Serversالخوادم
-
+ Unable change server while there is an active connectionلا يمكن تغير الخادم بينما هناك اتصال مفعل
@@ -432,354 +480,355 @@ Already installed containers were found on the server. All installed containers
PageProtocolAwgSettings
-
+ AmneziaWG settingsاعدادات AmneziaWG
-
+ Portمنفذ
-
+ MTU
-
+
- Remove AmneziaWG
- قم بحذف AmneziaWG
-
-
- Remove AmneziaWG from server?
- قم بحذف AmneziaWG من الخادم؟
-
-
-
+ All users with whom you shared a connection with will no longer be able to connect to it.جميع المستخدمين الذين شاركت معهم اتصال لن يكونو قادرين علي الاتصال مرة اخري.
-
+ Saveاحفظ
-
+
+ Jc - Junk packet count
+
+
+
+
+ Jmin - Junk packet minimum size
+
+
+
+
+ Jmax - Junk packet maximum size
+
+
+
+
+ S1 - Init packet junk size
+
+
+
+
+ S2 - Response packet junk size
+
+
+
+
+ H1 - Init packet magic header
+
+
+
+
+ H2 - Response packet magic header
+
+
+
+
+ H4 - Transport packet magic header
+
+
+
+
+ H3 - Underload packet magic header
+
+
+
+ The values of the H1-H4 fields must be unique
-
+ يجب أن تكون قيم الحقول H1-H4 فريدة
-
+ The value of the field S1 + message initiation size (148) must not equal S2 + message response size (92)
-
+ يجب ألا تساوي قيمة الحقل S1 + حجم بدء الرسالة (148) S2 + حجم استجابة الرسالة (92)
-
+ Save settings?احفظ الإعدادات؟
-
+ Continueواصل
-
+ Cancelإلغاء
-
+ Unable change settings while there is an active connection
-
+ لا يمكن تغيير الإعدادات أثناء وجود اتصال نشطPageProtocolCloakSettings
-
+ Cloak settingsCloak إعدادات
-
+ Disguised as traffic fromمتنكراً في حركة مرور من
-
+ Portمنفذ
-
+ Cipherالشفرة
-
+ Saveاحفظ
-
+ Unable change settings while there is an active connection
-
+ لا يمكن تغيير الإعدادات أثناء وجود اتصال نشطPageProtocolOpenVpnSettings
-
+ OpenVPN settingsOpenVPN اعدادات
-
+ VPN address subnetالشبكة الفرعية لعنوان VPN
-
+ Network protocolبروتوكول الشبكة
-
+ Portمنفذ
-
+ Auto-negotiate encryptionالتفاوض التلقائي علي الشبكة
-
+ Hash
-
+ SHA512
-
+ SHA384
-
+ SHA256
-
+ SHA3-512
-
+ SHA3-384
-
+ SHA3-256
-
+ whirlpool
-
+ BLAKE2b512
-
+ BLAKE2s256
-
+ SHA1
-
+ Cipherشفرة
-
+ AES-256-GCM
-
+ AES-192-GCM
-
+ AES-128-GCM
-
+ AES-256-CBC
-
+ AES-192-CBC
-
+ AES-128-CBC
-
+ ChaCha20-Poly1305
-
+ ARIA-256-CBC
-
+ CAMELLIA-256-CBC
-
+ noneلا شئ
-
+ TLS authTLS مصادقة
-
+ Block DNS requests outside of VPNاحظر طلبات DNS خارج ال VPN
-
+ Additional client configuration commandsاوامر تكوين العميل الاضافية
-
-
+
+ Commands:الاوامر:
-
+ Additional server configuration commandsاوامر تكوين الخادم الاضافية
-
+ Unable change settings while there is an active connection
-
+ لا يمكن تغيير الإعدادات أثناء وجود اتصال نشط
- Remove OpenVPN
- احذف OpenVPN
-
-
- Remove OpenVPN from server?
- احذف OpenVPN من الخادم?
-
-
- All users with whom you shared a connection with will no longer be able to connect to it.
- جميع المستخدمين الذين شاركت معهم اتصال لن يكونو قادرين علي الاتصال مرة اخري.
-
-
-
+ Saveاحفظ
-
- All users with whom you shared a connection will no longer be able to connect to it
- جميع المستخدمين الذين شاركت اتصال معهم لن يستطيعو الاتصال بعد الان
-
-
- Continue
- واصل
-
-
- Cancel
- إلغاء
- PageProtocolRaw
-
+ settings إعدادات
-
+ Show connection optionsاظهر اختيارات الاتصال
- Connection options
- اختيارات الاتصال
-
-
-
+ Connection options %1%1 اختيارات الاتصال
-
+ Remove احذف
-
+ Remove %1 from server?احذف %1 من الخادم ?
-
+ All users with whom you shared a connection with will no longer be able to connect to it.جميع المستخدمين الذين شاركت معهم اتصال لن يكونو قادرين علي الاتصال مرة اخري.
- from server?
- من الخادم
-
-
- All users with whom you shared a connection will no longer be able to connect to it
- جميع المستخدمين الذين شاركت اتصال معهم لن يستطيعو الاتصال بعد الان
-
-
-
+ Continueواصل
-
+ Cancelإلغاء
@@ -787,68 +836,56 @@ Already installed containers were found on the server. All installed containers
PageProtocolShadowSocksSettings
-
+ Shadowsocks settingsShadowsocks إعدادات
-
+ Portمنفذ
-
+ Cipherتشفير
-
+ Saveاحفظ
-
+ Unable change settings while there is an active connection
-
+ لا يمكن تغيير الإعدادات أثناء وجود اتصال نشطPageProtocolWireGuardSettings
-
+ WG settings
-
+ إعدادات WG
-
+ Port
- منفذ
+ منفذ
-
+ MTU
-
+
-
+ Unable change settings while there is an active connection
-
+ لا يمكن تغيير الإعدادات أثناء وجود اتصال نشط
- All users with whom you shared a connection will no longer be able to connect to it.
- جميع المستخدمين الذين شاركت معاهم اتصال لن يستطيعو الاتصال بعد الان.
-
-
- Continue
- واصل
-
-
- Cancel
- إلغاء
-
-
-
+ Saveاحفظ
@@ -856,66 +893,62 @@ Already installed containers were found on the server. All installed containers
PageProtocolXraySettings
-
+ XRay settings
-
+ إعدادات XRay
-
+ Disguised as traffic from
- متنكراً في حركة مرور من
+ متنكراً في حركة مرور من
-
+ Save
- احفظ
+ احفظ
-
+ Unable change settings while there is an active connection
-
+ لا يمكن تغيير الإعدادات أثناء وجود اتصال نشطPageServiceDnsSettings
-
+ A DNS service is installed on your server, and it is only accessible via VPN.
تم تثبيت خدمة DNS علي الخادم الخاص بك, و فقط متاح من خلال VPN.
-
+ The DNS address is the same as the address of your server. You can configure DNS in the settings, under the connections tab.عنوان ال DNS متطابق لنفس عنوان الخادم بك, يمكنك تهيئة DNS في الاعدادات, تحت علامة تبويب الاتصال.
-
+ Remove احذف
-
+ Remove %1 from server?احذف %1 ?
-
+ Cannot remove AmneziaDNS from running server
-
+ لا يمكن إزالة AmneziaDNS من الخادم قيد التشغيل
- from server?
- من الخادم
-
-
-
+ Continueواصل
-
+ Cancelإلغاء
@@ -923,253 +956,218 @@ Already installed containers were found on the server. All installed containers
PageServiceSftpSettings
-
+ Settings updated successfullyتم تحديث الإعدادات بنجاح
-
+ SFTP settingsSFTP إعدادات
-
+ Hostاستضافة
-
-
-
-
+
+
+
+ Copiedتم الاستنساخ
-
+ Portمنفذ
-
+ User nameاسم المستخدم
-
+ Passwordكلمة المرور
-
+ Mount folder on deviceقم بتثبيت المجلد علي الجهاز
-
+ In order to mount remote SFTP folder as local drive, perform following steps: <br>لتثبيت مجلد SFTP كمحرك اقراص محلي, اتبع هذه الخطوات : <br>
-
-
+
+ <br>1. Install the latest version of <br>1. تحميل اخر اصدار من
-
-
+
+ <br>2. Install the latest version of <br>2. تحمير اخر اصدار من
-
+ Detailed instructionsتعليمات مفصلة
-
-
- Remove SFTP and all data stored there
- امسح SFTP وجميع البيانات المخزنة
-
-
-
- Remove SFTP and all data stored there?
- امسح SFTP وجميع البيانات المخزنة؟
-
-
-
- Continue
- واصل
-
-
-
- Cancel
- إلغاء
- PageServiceSocksProxySettings
-
+ Settings updated successfully
-
+ تم تحديث الإعدادات بنجاح
-
-
+
+ SOCKS5 settings
-
+ إعدادات SOCKS5
-
+ Host
- استضافة
+ استضافة
-
-
-
-
+
+
+
+ Copied
-
+ تم النسخ
-
-
+
+ Port
- منفذ
+ منفذ
-
+ User name
- اسم المستخدم
+ اسم المستخدم
-
-
+
+ Password
- كلمة المرور
+ كلمة المرور
-
+ Username
-
+ اسم المستخدم
-
-
+
+ Change connection settings
-
+ تغيير إعدادات الاتصال
-
+ The port must be in the range of 1 to 65535
-
+ يجب أن يكون المنفذ في النطاق من 1 إلى 65535
-
+ Password cannot be empty
-
+ لا يمكن ان تكون كلمة المرور فارغة
-
+ Username cannot be empty
-
+ اسم المستخدم لا يمكن ان يكون فارغPageServiceTorWebsiteSettings
-
+ Settings updated successfullyتم تحديث الإعدادات بنجاح
-
+ Tor website settingsTor إعدادات متصفح
-
+ Website addressعنوان المتصفح
-
+ Copiedتم الاستنساخ
-
+ Use <a href="https://www.torproject.org/download/" style="color: #FBB26A;">Tor Browser</a> to open this URL.
-
+ After creating your onion site, it takes a few minutes for the Tor network to make it available for use.
-
+ When configuring WordPress set the this onion address as domain.عند تكوين WordPress قم بتعيين عنوان ال onion هذا ك domain.
-
-
- Remove website
- احذف متصفح
-
-
-
- The site with all data will be removed from the tor network.
- سيتم حذف الموقع وجميع البيانات من الشبكة.
-
-
-
- Continue
- واصل
-
-
-
- Cancel
- إلغاء
- PageSettings
-
+ Settingsإعدادات
-
+ Serversالخوادم
-
+ Connectionالاتصال
-
+ Applicationتطبيق
-
+ Backupنسخة احتياطية
-
+ About AmneziaVPNعن AmneziaVPN
+ Dev console
+
+
+
+ Close applicationإغلاق التطبيق
@@ -1177,267 +1175,319 @@ Already installed containers were found on the server. All installed containers
PageSettingsAbout
- This is a free and open source application. If you like it, support the developers with a donation.
-And if you don't like the app, all the more support it - the donation will be used to improve the app.
- هذا تطبيق مجاني و مفتوح المصدر. إذا عجبك التطبيق, ادعم المطورين ب تبرع.
- وإذا لما يعجبك, فهذا سبب اكبر لدعمة - تستخدم التبرعات في تطوير التطبيق
-
-
-
+ Support Amneziaدعم Amenzia
-
+ Amnezia is a free and open-source application. You can support the developers if you like it.هو تطبيق مجاني ومفتوح المصدر يمكنك دعم مطورين Amnezia إذا اعجبك.
-
+ Contactsالتواصل
-
+ Telegram groupمجموعة ال Telegram
-
+ To discuss featuresلمناقشة الميزات
-
+ https://t.me/amnezia_vpn_en
-
+ Mailالبريد
-
+ For reviews and bug reportsلل مراجعات والابلاغات عن المشاكل
-
+ GitHubGitHub
-
+ https://github.com/amnezia-vpn/amnezia-client
-
+ Websiteموقع
-
- https://amnezia.org
-
-
-
-
+ Software version: %1%1 :إصدار البرنامج
-
+ Check for updatesتحقق من وجود تحديثات
-
+ Privacy Policyسياسات الخصوصية
- PageSettingsAppSplitTunneling
+ PageSettingsApiServerInfo
-
- Cannot change split tunneling settings during active connection
- لا يمكن تغير إعدادات تقسيم الانفاق بينما هناك اتصال مٌفعل
-
-
-
- Only the apps from the list should have access via VPN
+
+ For the region
-
- Apps from the list should not have access via VPN
+
+ Price
-
- App split tunneling
+
+ Work period
-
- Mode
- وضع
+
+ Speed
+
-
- Remove
- احذف
+
+ Support tag
+
-
+
+ Copied
+
+
+
+
+ Reload API config
+
+
+
+
+ Reload API config?
+
+
+
+
+ Continueواصل
-
+
+ Cancelإلغاء
-
- application name
+
+ Cannot reload API config during active connection
-
- Open executable file
+
+ Remove from application
+
+
+ Remove from application?
+
+
+
+
+ Cannot remove server during active connection
+ لا يمكن إزالة الخادم أثناء الاتصال النشط
+
+
+
+ PageSettingsAppSplitTunneling
+
+
+ Cannot change split tunneling settings during active connection
+ لا يمكن تغير إعدادات تقسيم الانفاق بينما هناك اتصال مٌفعل
+
+
+
+ Only the apps from the list should have access via VPN
+ يجب أن تتمتع التطبيقات الموجودة في القائمة فقط بإمكانية الوصول عبر VPN
+
+
+
+ Apps from the list should not have access via VPN
+ لا يجب ان تتمتع التطبيقات في القائمة بولوج ل VPN
+
+
+
+ App split tunneling
+ تقسيم نفق التطبيق
+
+
+
+ Mode
+ وضع
+
+
+
+ Remove
+ احذف
+
+
+
+ Continue
+ واصل
+
+
+
+ Cancel
+ إلغاء
+
+
+
+ application name
+ اسم التطبيق
+
+ Open executable file
+ افتح ملف قابل للتنفيذ
+
+
+ Executable files (*.*)
-
+ ملفات قابلة للتنفيذ (*.*)PageSettingsApplication
-
+ Applicationتطبيق
-
+ Allow application screenshotsاسمح بلقطات شاشة التطبيق
-
+ Enable notifications
-
+ تفعيل الإشعارات
-
+ Enable notifications to show the VPN state in the status bar
-
+ تفعيل الإشعارات لإظهار حالة ال VPN في شريط الحالة
-
+ Auto startتشغيل تلقائي
- Launch the application every time
- شغل البرنامج كل مرة
-
-
- starts
- يبدأ
-
-
-
+ Launch the application every time the device is startsقم بتشغيل التطبيق فكل مرة يتم فيها تشغيل الجهاز
-
+ Auto connectاتصال تلقائي
-
+ Connect to VPN on app startاتصل ب ال VPN عند تشغيل التطبيق
-
+ Start minimizedابدأ ب الحجم الادني
-
+ Launch application minimizedتشغيل التطبيق في الحد الادني
-
+ Languageاللغة
-
+ Loggingتسجيل
-
+ Enabledمٌفعل
-
+ Disabledمٌعطل
-
+ Reset settings and remove all data from the applicationإعادة ضبط الاعدادات ومسح جميع البيانات من التطبيق
-
+ Reset settings and remove all data from the application?إعادة ضبط الاعدادات ومسح جميع البيانات من التطبيق؟
-
+ All settings will be reset to default. All installed AmneziaVPN services will still remain on the server.سيتم ضبط الاعدادات الافتراضية. جميع خدمات AmneziaVPN المٌثبتة ستبقي علي الخادم.
-
+ Continueواصل
-
+ Cancelإلغاء
-
+ Cannot reset settings during active connection
-
+ لا يمكن إعادة ضبط الإعدادات اثناء تواجد اتصال فعالPageSettingsBackup
-
+ Settings restored from backup fileتم إعادة الاعدادات من ملف نسخة احتياطية
-
- It will help you instantly restore connection settings at the next installation
- سيساعدك علي إعادة إعدادات الاتصال بسرعة عند إعادة تثبيت التطبيق
- Back up your configuration
@@ -1507,147 +1557,131 @@ And if you don't like the app, all the more support it - the donation will
Cannot restore backup settings during active connection
-
+ لا يمكن استعادة إعدادات النسخ الاحتياطي أثناء الاتصال النشطPageSettingsConnection
-
+ Connectionالاتصال
-
+ When AmneziaDNS is not used or installedعندما يكون AmneziaDNS غير مٌثبت او غير مستخدم
-
+ Allows you to use the VPN only for certain Appsيسمح لك بأستخدام ال VPN علي تطبيقات معينة
- Use AmneziaDNS if installed on the server
- استخدم AmneziaDNS إذا كان مٌثبت علي الخادم
-
-
-
+ Use AmneziaDNSاستخدم AmneziaDNS
-
+ If AmneziaDNS is installed on the serverفي حالة كان AmneziaDNS مٌثبت علي الخادم
-
+ DNS serversخوادم DNS
-
+ Site-based split tunnelingانقسام الانفاق القائم علي الموقع
-
+ Allows you to select which sites you want to access through the VPNيسمح لك بتحديد اي موقع تريد الوصول له عن طريق ال VPN
-
+ App-based split tunnelingانقسام الانفاق القائم علي التطبيق
-
-
- KillSwitch
-
-
+ KillSwitch
+
+
+
+ Disables your internet if your encrypted VPN connection drops out for any reason.
-
+ يعطل اتصال الإنترنت الخاص بك إذا انقطع اتصال VPN المشفر لأي سبب من الأسباب.
-
+ Cannot change killSwitch settings during active connection
-
-
-
- Split site tunneling
- قسم نفق الموقع
-
-
- Allows you to connect to some sites through a secure connection, and to others bypassing it
- يسمحلك بألاتصال ببعض المواقع بسرية, وعلي الاخرين تجاوزه
-
-
- Separate application tunneling
- فرق نفق التطبيق
+ لا يمكن تغيير إعدادات KillSwitch اثناء تواجد اتصال فعالPageSettingsDns
-
+ Default server does not support custom DNSالخادم الافتراضي لا يدعم DNS مخصص
-
+ DNS serversخوادم ال DNS
-
+ If AmneziaDNS is not used or installedAmneziaVPN ليس مٌستخدم او مٌثبت
-
+ Primary DNSالرئيسي DNS
-
+ Secondary DNSالثانوي DNS
-
+ Restore defaultاستعادة الافتراضي
-
+ Restore default DNS settings?قم بأعادة ضبط إعدادات ال DNS الافتراضية؟
-
+ Continueواصل
-
+ Cancelإلغاء
-
+ Settings have been resetلم يتم إعادة ضبط الإعدادات
-
+ Saveاحفظ
-
+ Settings savedتم حفظ الإعدادات
@@ -1655,72 +1689,72 @@ And if you don't like the app, all the more support it - the donation will
PageSettingsLogging
-
+ Logging is enabled. Note that logs will be automatically disabled after 14 days, and all log files will be deleted.
-
+ تم تمكين التسجيل. لاحظ أنه سيتم تعطيل السجلات تلقائيًا بعد 14 يومًا، وسيتم حذف جميع ملفات السجل.
-
+ Loggingالتسجيل
-
+ Enabling this function will save application's logs automatically. By default, logging functionality is disabled. Enable log saving in case of application malfunction.سيتم حفظ سجلات البرنامج بشكل تلقائي عند تفعيل هذه الميزة, بشكل افتراضي, هذه الميزة مٌعطلة. قم بتفعيل هذه الميزة في حالة هناك خلل في التطبيق.
-
+ Save logsاحفظ السجلات
-
+ Open folder with logsافتح مجلد يحتوي علي سجلات
-
+ Saveاحفظ
-
+ Logs files (*.log)ملفات الولوج (*.log)
-
+ Logs file savedتم حفظ ملف السجل
-
+ Save logs to fileاحفظ السجلات في ملف
-
+ Clear logs?مسح السجلات؟
-
+ Continueواصل
-
+ Cancelإلغاء
-
+ Logs have been cleaned upتم مسح السجلات
-
+ Clear logsاحذف السجلات
@@ -1728,34 +1762,22 @@ And if you don't like the app, all the more support it - the donation will
PageSettingsServerData
-
+ All installed containers have been added to the applicationتمت إضافة جميع الحاويات المٌثبتة للتطبيق
-
+ No new installed containers foundلم يتم العثور علي اي حاويات جديدة مٌثبتة
- Clear Amnezia cache
- حذف ذاكرة تخزين Amnezia المؤقتة
-
-
- May be needed when changing other settings
- قد يكون ضروري عند تغير الإعدادات الاخري
-
-
- Clear cached profiles?
- حذف الملفات الشخصية المخزنة مؤقتاً؟
-
-
-
+ Do you want to reboot the server?هل تريد إعادة تشغيل الخادم؟
-
+ Do you want to clear server from Amnezia software?هل تريد حذف الخادم من Amnezia?
@@ -1764,94 +1786,94 @@ And if you don't like the app, all the more support it - the donation will
-
-
-
-
-
- Continue
- واصل
-
+ Continue
+ واصل
+
+
+
+
+
+ Cancelإلغاء
-
+ Check the server for previously installed Amnezia servicesافحص الخادم عن اي خدمات Amnezia مٌثبتة سابقاُ
-
+ Add them to the application if they were not displayedاضفهم إلي التطبيق إذا لم يكونو ظاهرين
-
+ Reboot serverإعادة تشغيل الخادم
-
+ The reboot process may take approximately 30 seconds. Are you sure you wish to proceed?عملية إعادة التشغيل قد تستغرق 30 ثانية, هل تريد الاستكمال؟
-
+ Cannot reboot server during active connection
-
+ لا يمكن إعادة تشغيل الخادم أثناء الاتصال النشط
-
+ Remove server from applicationاحذف خادم من التطبيق
-
+ Do you want to remove the server from application?هل تريد حذف الخادم من التطبيق؟
-
+ Cannot remove server during active connection
-
+ لا يمكن إزالة الخادم أثناء الاتصال النشط
-
+ All users whom you shared a connection with will no longer be able to connect to it.جميع المستخدمين الذين شاركت معهم اتصال لن يستطيعو الاتصال مرة اخري.
-
+ Cannot clear server from Amnezia software during active connection
-
+ لا يمكن مسح الخادم من برنامج Amnezia أثناء الاتصال النشط
-
+ Reset API configإعادة تكوين API
-
+ Do you want to reset API config?هل تريد إعادة تكوين API?
-
+ Cannot reset API config during active connection
-
+ لا يمكن إعادة تعيين تكوين API أثناء الاتصال النشط
-
+ All installed AmneziaVPN services will still remain on the server.جميع خدمات AmneziaVPN المٌثبتة ستظل علي الخادم.
-
+ Clear server from Amnezia softwareاحذف خادم من Amnezia
@@ -1859,27 +1881,27 @@ And if you don't like the app, all the more support it - the donation will
PageSettingsServerInfo
-
+ Server nameاسم الخادم
-
+ Saveاحفظ
-
+ Protocolsالبروتوكولات
-
+ Servicesالخدمات
-
+ Managementالإدارة
@@ -1887,67 +1909,59 @@ And if you don't like the app, all the more support it - the donation will
PageSettingsServerProtocol
-
+ settings الإعدادات
-
+ Clear %1 profile
-
+ مسح ملف تعريف %1
-
+ Clear %1 profile?
-
+ مسح ملف تعريف %1؟
-
+
-
+ Unable to clear %1 profile while there is an active connection
-
+ غير قادر على مسح ملف تعريف %1 أثناء وجود اتصال نشط
-
+ Remove احذف
-
+
+ Remove %1 from server?
+
+
+
+ All users with whom you shared a connection will no longer be able to connect to it.جميع المستخدمين الذين شاركت معاهم اتصال لن يستطيعو الاتصال بعد الان.
-
+ Cannot remove active container
-
+ لا يمكن إزالة الحاوية النشطة
- from server?
- من الخادم؟
-
-
-
- Remove %1 from server?
- احذف %1 من الخادم ?
-
-
- All users with whom you shared a connection will no longer be able to connect to it
- جميع المستخدمين الذين شاركت اتصال معهم لن يستطيعو الاتصال بعد الان
-
-
-
-
+
+ Continueواصل
-
-
+
+ Cancelإلغاء
@@ -1955,7 +1969,7 @@ And if you don't like the app, all the more support it - the donation will
PageSettingsServersList
-
+ Serversالخوادم
@@ -1963,221 +1977,322 @@ And if you don't like the app, all the more support it - the donation will
PageSettingsSplitTunneling
- Only the addresses in the list must be opened via VPN
- يجب فتح العنواين التي في القائمة عبر VPN
-
-
- Addresses from the list should never be opened via VPN
- لا يجب ابداً فتح العنواين التي في القائمة عن طريق VPN
-
-
- Split site tunneling
- قسم نفق الموقع
-
-
-
+ Default server does not support split tunneling functionالسرفر الافتراضي لا يدعم ميزة تقسيم الانفاق
-
+ Addresses from the list should not be accessed via VPNلا يجب الولوج للعنواين المذكورة هنا من خلال ال VPN
-
+ Split tunnelingتقسيم الانفاق
-
+ Modeوضع
-
+ Remove احذف
-
+ Continueواصل
-
+ Cancelإلغاء
-
+ Only the sites listed here will be accessed through the VPNسيتم الولوج للمواقع المذكورة هنا فقط عن طريق ال VPN
-
+ Cannot change split tunneling settings during active connectionلا يمكن تغير إعدادات تقسيم الانفاق بينما هناك اتصال مٌفعل
-
+ website or IPموقع او IP
-
+ Import / Export Sites
-
+ Importاسترد
-
+ Save site listاحفظ قائمة المواقع
-
+ Save sitesاحفظ المواقع
-
-
-
+
+
+ Sites files (*.json)
-
+ Import a list of sitesاسترد قائمة من المواقع
-
+ Replace site listتبديل قائمة المواقع
-
-
+
+ Open sites fileافتح ملف المواقع
-
+ Add imported sites to existing onesإضافة المواقع المستردة للمواقع الموجودة
+
+ PageSetupWizardApiServiceInfo
+
+
+ For the region
+
+
+
+
+ Price
+
+
+
+
+ Work period
+
+
+
+
+ Speed
+
+
+
+
+ Features
+
+
+
+
+ Connect
+ اتصل
+
+
+
+ PageSetupWizardApiServicesList
+
+
+ VPN by Amnezia
+
+
+
+
+ Choose a VPN service that suits your needs.
+
+
+PageSetupWizardConfigSource
- Server connection
- اتصال الخادم
+ اتصال الخادم
- Do not use connection code from public sources. It may have been created to intercept your data.
-
-It's okay as long as it's from someone you trust.
- لا تستخدم رمز الاتصال من المصادر العامة. ربما تم إنشاؤه لاعتراض بياناتك
-
-لا بأس طالما انه من شخص تثق به.
-
-
- Do not use connection codes from untrusted sources, as they may be created to intercept your data.
- لا تستخدم رموز اتصال من مصادر غير موثوقة, حيث قد يكون تم إنشاؤها لاعتراض بياناتك.
+ لا تستخدم رموز اتصال من مصادر غير موثوقة, حيث قد يكون تم إنشاؤها لاعتراض بياناتك.
- What do you have?
- ماذا لديك؟
+ ماذا لديك؟
- File with connection settings or backup
- ملف إعدادات اتصال او نسخ احتياطي
+ ملف إعدادات اتصال او نسخ احتياطي
+
+
+
+ Connection
+ الاتصال
+
+
+
+ Insert the key, add a configuration file or scan the QR-code
+
+ Insert key
+
+
+
+
+ Insert
+ ادخل
+
+
+
+ Continue
+ واصل
+
+
+
+ Other connection options
+
+
+
+
+ VPN by Amnezia
+
+
+
+
+ Connect to classic paid and free VPN services from Amnezia
+
+
+
+
+ Self-hosted VPN
+
+
+
+
+ Configure Amnezia VPN on your own server
+
+
+
+
+ Restore from backup
+ استرجاع من ملف يحتوي علي نسخة احتياطية
+
+
+
+ Open backup file
+ افتح ملف نسخ احتياطي
+
+
+
+ Backup files (*.backup)
+ ملفات نٌسخ احتياطية (*.backup)
+
+
+ File with connection settingsملف إعدادات اتصال
-
+ Open config fileافتح ملف تكوين
-
+ QR codeرمز QR
-
+
+ I have nothing
+ ليس لدي اي شئ
+
+ Key as text
- مفتاح كنص
+ مفتاح كنصPageSetupWizardCredentials
-
+ Configure your serverتكوين الخادم الخاص بك
-
+ Server IP address [:port]عنوان خادم IP [:منفذ]
-
+ Continueواصل
-
+ All data you enter will remain strictly confidential and will not be shared or disclosed to the Amnezia or any third partiesستظل جميع البيانات التي تدخلها سرية للغاية ولن تتم مشاركتها أو الكشف عنها ل Amnezia أو أي طرف ثالث
-
+ 255.255.255.255:22
-
+ SSH Username
-
+ Password or SSH private keyكلمة مرور او مفتاح SSH خاص
-
+
+ How to run your VPN server
+
+
+
+
+ Where to get connection data, step-by-step instructions for buying a VPS
+
+
+
+ Ip address cannot be emptyلا يمكن لعنوان IP ان يكون فارغ
-
+ Enter the address in the format 255.255.255.255:88ادخل العنوان في شكل 255.255.255.255:88
-
+ Login cannot be emptyتسجيل دخول لا يمكن ان يكون فارغ
-
+ Password/private key cannot be emptyكلمة مرور/مفتاح خاص لأ يمكن ان يكونو فارغين
@@ -2185,22 +2300,22 @@ It's okay as long as it's from someone you trust.
PageSetupWizardEasy
-
+ What is the level of internet control in your region?ما هو مستوي التحكم في الانترنت في منطقتك؟
-
+ Choose a VPN protocolاختر بروتوكول VPN
-
+ Skip setupتخطي الإعداد
-
+ Continueواصل
@@ -2208,38 +2323,38 @@ It's okay as long as it's from someone you trust.
PageSetupWizardInstalling
-
-
+
+ Usually it takes no more than 5 minutesعادة لا تستغرق اكثر من 5 دقائق
-
+ The server has already been added to the applicationتمت إضافة الخادم بالفعل للتطبيق
-
+ Amnezia has detected that your server is currently اكتشف Amnezia الخادم الخاص بك موجود حاليًا
-
+ busy installing other software. Amnezia installation مشغول بتثبيت برامج اخري, تثبيت Amnezia
-
+ Cancel installationإلغاء التثبيت
-
+ will pause until the server finishes installing other softwareسيتوقف مؤقتًا حتى ينتهي الخادم من تثبيت البرامج الأخرى
-
+ Installingجاري التثبيت
@@ -2247,50 +2362,50 @@ It's okay as long as it's from someone you trust.
PageSetupWizardProtocolSettings
-
+ Installing %1تثبيت %1
-
+ More detailedاكثر تفصيلاً
-
+ Closeاغلق
-
+ Network protocolبروتوكول شبكة
-
+ Portمنفذ
-
+ Installتثبيت
-
+ The port must be in the range of 1 to 65535
-
+ يجب أن يكون المنفذ في النطاق من 1 إلى 65535PageSetupWizardProtocols
-
+ VPN protocolVPN بروتوكول
-
+ Choose the one with the highest priority for you. Later, you can install other protocols and additional services, such as DNS proxy and SFTP.اختر بالنسبة للأولوية القصوى بالنسبة لك. ويمكنك لاحقًا تثبيت بروتوكولات وخدمات إضافية أخرى، مثل وكيل DNS وSFTP.
@@ -2298,7 +2413,7 @@ It's okay as long as it's from someone you trust.
PageSetupWizardQrReader
-
+ Point the camera at the QR code and hold for a couple of seconds. قم بتوجيه الكاميرا نحو رمز QR و اثبت لبضع ثوان.
@@ -2306,61 +2421,56 @@ It's okay as long as it's from someone you trust.
PageSetupWizardStart
- Settings restored from backup file
- تم استرداد الإعدادات من ملف نسخة احتياطية
+ تم استرداد الإعدادات من ملف نسخة احتياطية
- Free service for creating a personal VPN on your server.
- خدمة مجانية لأنشاء VPN شخصي علي الخادم الشخصي.
+ خدمة مجانية لأنشاء VPN شخصي علي الخادم الشخصي.
- Helps you access blocked content without revealing your privacy, even to VPN providers.
- يساعدك في الولوج للمحتوي المحظور بدون إظهار خصوصيات, حتي لمزود ال VPN.
+ يساعدك في الولوج للمحتوي المحظور بدون إظهار خصوصيات, حتي لمزود ال VPN.
- I have the data to connect
- لدي البيانات المطلوبة للأتصال
+ لدي البيانات المطلوبة للأتصال
- I have nothing
- ليس لدي اي شئ
+ ليس لدي اي شئ
-
- https://amnezia.org/instructions/0_starter-guide
-
+
+ Let's get started
+ PageSetupWizardTextKey
-
+ Connection keyمفتاح اتصال
-
+ A line that starts with vpn://...يجب ان تٌكتب بهذه الطريقة حتي بوجود التحذير كي تظهر بشكل صحيح داخل التطبيقسطر يبدأ ب ...//:vpn
-
+ Keyمفتاح
-
+ Insertادخل
-
+ Continueواصل
@@ -2368,32 +2478,32 @@ It's okay as long as it's from someone you trust.
PageSetupWizardViewConfig
-
+ New connectionاتصال جديد
-
+ Collapse contentطي المحتوي
-
+ Show contentاظهر المحتوي
-
+ Enable WireGuard obfuscation. It may be useful if WireGuard is blocked on your provider.
-
+ تمكين تشويش WireGuard. قد يكون من المفيد إذا تم حظر WireGuard على مزود الخدمة الخاص بك.
-
+ Use connection codes only from sources you trust. Codes from public sources may have been created to intercept your data.استخدم رموز اتصال فقط من المصادر التي تثق بها, ربما تم إنشاء رموز من مصادر عامة لاعتراض بياناتك.
-
+ Connectاتصل
@@ -2401,223 +2511,207 @@ It's okay as long as it's from someone you trust.
PageShare
-
+ Save OpenVPN configاحفظ تكوين OpenVPN
-
+ Save WireGuard configاحفظ تكوين WireGuard
-
+ Save AmneziaWG configاحفظ تكوين AmneziaWG
-
+ Save Shadowsocks configاحفظ تكوين Shadowsocks
-
+ Save Cloak configاحفظ تكوين Cloak
-
+ Save XRay config
-
+ حفظ تكوين XRay
-
+ For the AmneziaVPN appAmneziaVPN من اجل تطبيق
-
+ OpenVPN native formatتنسيق OpenVPN الاصلي
-
+ WireGuard native formatتنسيق WireGuard الاصلي
-
+ AmneziaWG native formatتنسيق AmneziaWG اصلي
-
+ Shadowsocks native formatتنسيق Shadowsocks الاصلي
-
+ Cloak native formatتنسيق Cloak الاصلي
-
+ XRay native format
-
+ الشكل الاصلي ل XRay
-
+ Share VPN Accessشارك اتصال VPN
-
+ Share full access to the server and VPNشارك ولوج كامل للخادم و ال VPN
-
+ Use for your own devices, or share with those you trust to manage the server.استخدمه للأجهزة الخاصة بك، أو شاركه مع من تثق بهم لإدارة الخادم.
-
-
+
+ Usersالمستخدمين
-
+ Share VPN access without the ability to manage the serverشارك اتصال VPN بدون القدرة علي إدارة الخادم
-
+ Searchابحث
-
+ Creation date: %1
-
+ تاريخ الإنشاء: %1
-
+ Latest handshake: %1
-
+ اخر تصافح: %1
-
+ Data received: %1
-
+ البيانات المستلمة: %1
-
+ Data sent: %1
-
+ البيانات المٌرسلة: %1
- Creation date:
- تاريخ الإنشاء:
-
-
-
+ Renameإعادة التسمية
-
+ Client nameاسم العميل
-
+ Saveاحفظ
-
+ Revokeسحب وإبطال
-
+ Revoke the config for a user - %1?سحب وإبطال للمستخدم - %1?
-
+ The user will no longer be able to connect to your server.المستخدم لن يكون قادر علي الاتصال بعد الان.
-
+ Continueواصل
-
+ Cancelإلغاء
-
+ Connectionالاتصال
- Full access to server
- ولوج كامل للخادم
-
-
- Servers
- الخوادم
-
-
-
-
+
+ Serverخادم
-
+ File with connection settings to ملف بإعدادات إلي
- Protocols
- البروتوكولات
-
-
-
-
+
+ Protocolبروتوكول
-
+ Connection to اتصال إلي
-
+ Config revokedتم سحب وإبطال التكوين
-
+ User nameاسم المستخدم
-
-
+
+ Connection formatتنسيق الاتصال
-
-
+
+ Shareشارك
@@ -2625,50 +2719,50 @@ It's okay as long as it's from someone you trust.
PageShareFullAccess
-
+ Full access to the server and VPNولوج كامل للخادم و ال VPN
-
+ We recommend that you use full access to the server only for your own additional devices.
نحن ننصحك بأستخدام ولوج كامل للخادم فقط لأجهزتك الاضافية.
-
+ If you share full access with other people, they can remove and add protocols and services to the server, which will cause the VPN to work incorrectly for all users. إذا شاركت ولوج كامل مع الاشخاص, سيكونو قادرين علي حذف وإضافة بروتوكولات و خدمات إلي الخادم, والذي سيجعل VPN يعمل بشكل غير صحيح لجميع المستخدمين.
-
+ Serverخادم
-
+ Accessing التواصل
-
+ File with accessing settings to ملف مع إعدادات الوصول إلي
-
+ Shareمشاركة
-
+ Connection to اتصال إلي
-
+ File with connection settings to معلف مع إعدادات الاتصال إلي
@@ -2676,15 +2770,20 @@ It's okay as long as it's from someone you trust.
PageStart
-
+ Logging was disabled after 14 days, log files were deleted
+ تم تعطيل التسجيل بعد 14 يومًا، وتم حذف ملفات السجل
+
+
+
+ Settings restored from backup filePopupType
-
+ Closeاغلاق
@@ -2936,7 +3035,7 @@ It's okay as long as it's from someone you trust.
SOCKS5 proxy server
-
+
@@ -3014,50 +3113,6 @@ It's okay as long as it's from someone you trust.
Timeout connecting to serverانتهت مدة الاتصال بالخادم
-
- Sftp error: File does not exist
- خطأ Sftp: الملف غير موجود
-
-
- Sftp error: Permission denied
- خطأ Sftp: تم حظر الصلحيات
-
-
- Sftp error: Generic failure
- خطأ Sftp: فشل عام
-
-
- Sftp error: Garbage received from server
- خطأ Sftp: تم استلام نفايات من الخادم
-
-
- Sftp error: No connection has been set up
- خطأ Sftp: لم يتم إعداد اتصال
-
-
- Sftp error: There was a connection, but we lost it
- خطأ Sftp: كان هناك اتصال, ولكن خسرناه
-
-
- Sftp error: Operation not supported by libssh yet
- خطأ Sftp: العملية ليست مدعومة من libssh بعد
-
-
- Sftp error: No such file or directory path exists
- خطأ Sftp: لا يوجد مسار ملف او مجلد مثل هذا
-
-
- Sftp error: An attempt to create an already existing file or directory has been made
- خطأ Sftp: محاولة إنشاء ملف او مجلد موجود بالفعل
-
-
- Sftp error: Write-protected filesystem
- خطأ Sftp: نظام كتابة الملفات محمي
-
-
- Sftp error: No media was in remote drive
- خطأ Sftp: لا يوجد وسائط في القرص البعيد
- VPN connection error
@@ -3074,7 +3129,7 @@ It's okay as long as it's from someone you trust.
هذا التكوين بالفعل تمت إضافتة للبرنامج
-
+ ErrorCode: %1.
@@ -3086,17 +3141,17 @@ It's okay as long as it's from someone you trust.
Background service is not running
-
+ خدمة الخلفية ليست قيد التشغيلServer error: Packet manager error
-
+ خطأ في الخادم: خطأ في مدير الحزمSCP error: Generic failure
-
+ خطأ SCP: فشل عام
@@ -3151,50 +3206,55 @@ It's okay as long as it's from someone you trust.
In the response from the server, an empty config was received
-
+ في الاستجابة من الخادم، تم تلقي تكوين فارغSSL error occurred
-
+ حدث خطأ SSLServer response timeout on api request
-
+ انتهت مهلة استجابة الخادم عند طلب واجهة برمجة التطبيقات
-
- QFile error: The file could not be opened
+
+ Missing AGW public key
- QFile error: An error occurred when reading from the file
-
+ QFile error: The file could not be opened
+ خطأ QFile: لا يمكن فتح الملف
- QFile error: The file could not be accessed
-
+ QFile error: An error occurred when reading from the file
+ خطأ QFile: ظهر خطأ اثناء القراءه من الملف
- QFile error: An unspecified error occurred
-
+ QFile error: The file could not be accessed
+ خطأ QFile: لا يمكن الوصول للملف
- QFile error: A fatal error occurred
-
+ QFile error: An unspecified error occurred
+ خطأ QFile: ظهر خطأ غير محدد
- QFile error: The operation was aborted
-
+ QFile error: A fatal error occurred
+ خطأ QFile: حدث خطأ فادح
-
+
+ QFile error: The operation was aborted
+ خطأ QFile: تم إحباط العملية
+
+
+ Internal errorخطأ داخلي
@@ -3239,12 +3299,12 @@ It's okay as long as it's from someone you trust.
XRay with REALITY - Suitable for countries with the highest level of internet censorship. Traffic masking as web traffic at the TLS level, and protection against detection by active probing methods.
-
+ الأشعة السينية مع الواقع - مناسبة للبلدان التي لديها أعلى مستوى من الرقابة على الإنترنت. إخفاء حركة المرور كحركة مرور على الويب على مستوى TLS، والحماية من الكشف عن طريق طرق التحقيق النشطة.IKEv2/IPsec - Modern stable protocol, a bit faster than others, restores connection after signal loss. It has native support on the latest versions of Android and iOS.
-
+ IKEv2/IPsec - بروتوكول مستقر حديث، أسرع قليلاً من البروتوكولات الأخرى، يستعيد الاتصال بعد فقدان الإشارة. يتمتع بدعم أصلي على أحدث إصدارات Android وiOS.
@@ -3319,7 +3379,10 @@ WireGuard is very susceptible to blocking due to its distinct packet signatures.
It uniquely identifies censors during the TLS handshake phase, seamlessly operating as a proxy for legitimate clients while diverting censors to genuine websites like google.com, thus presenting an authentic TLS certificate and data.
This advanced capability differentiates REALITY from similar technologies by its ability to disguise web traffic as coming from random, legitimate sites without the need for specific configurations.
Unlike older protocols such as VMess, VLESS, and the XTLS-Vision transport, REALITY's innovative "friend or foe" recognition at the TLS handshake enhances security and circumvents detection by sophisticated DPI systems employing active probing techniques. This makes REALITY a robust solution for maintaining internet freedom in environments with stringent censorship.
-
+ تم تصميم بروتوكول REALITY، وهو تطور رائد قام به مبدعو XRay، خصيصًا لمواجهة أعلى مستويات الرقابة على الإنترنت من خلال نهجه الجديد في التهرب.
+فهو يحدد بشكل فريد الرقباء أثناء مرحلة مصافحة TLS، ويعمل بسلاسة كوكيل للعملاء الشرعيين بينما يحول الرقباء إلى مواقع الويب الأصلية مثل google.com، وبالتالي يقدم شهادة وبيانات TLS أصلية.
+هذه الإمكانية المتقدمة تميز REALITY عن التقنيات المشابهة من خلال قدرتها على إخفاء حركة مرور الويب على أنها قادمة من مواقع عشوائية وشرعية دون الحاجة إلى تكوينات محددة.
+على عكس البروتوكولات القديمة مثل VMess وVLESS ونقل XTLS-Vision، فإن التعرف المبتكر على "الصديق أو العدو" من REALITY عند مصافحة TLS يعزز الأمان ويتحايل على الكشف بواسطة أنظمة DPI المتطورة التي تستخدم تقنيات التحقيق النشطة. وهذا يجعل من REALITY حلاً قويًا للحفاظ على حرية الإنترنت في البيئات التي تخضع لرقابة صارمة.
@@ -3350,10 +3413,6 @@ For more detailed information, you can
AmneziaWG - Special protocol from Amnezia, based on WireGuard. It's fast like WireGuard, but very resistant to blockages. Recommended for regions with high levels of censorship.بروتوكول AmneziaWG - بروتوكول خاص من Amnezia, يعتمد علي WireGuard. سريع مثل WireGuard, لكن مقاوم جداً للحجب. ينصح للمناطق ذات مستوي عالي من الرقابة.
-
- IKEv2/IPsec - Modern stable protocol, a bit faster than others, restores connection after signal loss.
- بروتوكول IKEv2/IPsec - بروتوكول مستقر حديث, اسرع بقليل من الباقي, يسترجع الاتصال بعد خسارة الاشارة.
- Deploy a WordPress site on the Tor network in two clicks.
@@ -3502,139 +3561,139 @@ While it offers a blend of security, stability, and speed, it's essential t
vmess:// url is invalid
-
+ عنوان //:vmess غير صحيحInvalid streamSettings protocol:
-
+ بروتوكول streamSettings غير صحيح: Unknown transport method:
-
+ طريقة نقل غير معروفة: VMess string should start with 'vmess://'
-
+ نص VMess يجب ان يبدأ ب '//:vmess'VMess string should be a valid base64 string
-
+ نص VMess يجب ان يكون نص base64 صحيحJSON should not be empty
-
+ لا يجب ان يكون JSON فارغVLESS link should start with vless://
-
+ رابط VLESS يجب ان يبدأ ب //:vlesslink parse failed: %1
-
+ فشل تحليل الرابط: %1empty host
-
+ مضيف فارغmissing port
-
+ منفذ مفقودmissing uuid
-
+ uuid مفقودInvalid ssd link: json: field %1 must exist
-
+ رابط ssd غير صالح: json: يجب أن يكون الحقل %1 موجودًاInvalid ssd link: json: field %1 must be valid port number
-
+ رابط ssd غير صالح: json: الحقل %1 يجب أن يكون رقم منفذ صالحًاInvalid ssd link: json: field %1 must be of type 'string'
-
+ رابط ssd غير صالح: json: يجب أن يكون الحقل %1 من النوع "string"Invalid ssd link: json: field %1 must be an array
-
+ رابط ssd غير صالح: json: الحقل %1 يجب أن يكون قائمةSkipping invalid ssd server: server must be an object
-
+ تخطي خادم ssd غير صالح: يجب أن يكون الخادم كائنًاSkipping invalid ssd server: missing required field %1
-
+ تخطي خادم ssd غير صالح: الحقل المطلوب %1 مفقودSkipping invalid ssd server: field %1 should be of type 'string'
-
+ تخطي خادم ssd غير صالح: يجب أن يكون الحقل %1 من النوع "string"Invalid ssd link: should begin with ssd://
-
+ رابط ssd غير صالح: يجب أن يبدأ بـ //:ssdInvalid ssd link: base64 parse failed
-
+ رابط SSD غير صالح: فشل تحليل Base64Invalid ssd link: json parse failed
-
+ رابط ssd غير صالح: فشل تحليل jsonInvalid ssd link: rc4-md5 encryption is not supported by v2ray-core
-
+ رابط ssd غير صالح: تشفير rc4-md5 غير مدعوم بواسطة v2ray-coreSS URI is too short
-
+ عنوان SS قصير جداًCan't find the colon separator between method and password
-
+ لا يمكن العثور على فاصل النقطتين بين method وكلمة المرورCan't find the at separator between password and hostname
-
+ لا يمكن العثور على فاصل النقطتين بين كلمة المرور وكلمة واسم المستضيفCan't find the colon separator between hostname and port
-
+ لا يمكن العثور على فاصل النقطتين بين اسم المستضيف و المنفذSelectLanguageDrawer
-
+ Choose languageاختر لغة
@@ -3642,13 +3701,13 @@ While it offers a blend of security, stability, and speed, it's essential t
Settings
-
+ Server #1خادم #1
-
-
+
+ Serverخادم
@@ -3665,51 +3724,43 @@ While it offers a blend of security, stability, and speed, it's essential t
All settings have been reset to default valuesتم استرجاع جميع الإعدادات للإعدادات الافتراضية
-
- Cached profiles cleared
- تم حذف الملفات الشخصية المٌخزنة مؤقتاُ
- ShareConnectionDrawer
-
-
+
+ Save AmneziaVPN configاحفظ تكوين AmneziaVPN
-
+ Shareشارك
-
+ Copyانسخ
-
-
+
+ Copiedتم النسخ
-
+ Copy config stringانسخ نص التكوين
-
+ Show connection settingsاظهر إعدادات الاتصال
- Show content
- 展示内容
-
-
-
+ To read the QR code in the Amnezia app, select "Add server" → "I have data to connect" → "QR code, key or settings file"حتي تقرأ رمز ال QR في تطبيق Amnezia, اختار "إضافة خادم" - "لدي بيانات الاتصال" - "رمز Qr, او مفتاح تعريف او ملف إعدادات"
@@ -3793,7 +3844,7 @@ While it offers a blend of security, stability, and speed, it's essential t
TextFieldWithHeaderType
-
+ The field can't be emptyالحقل لا يمكن ان يكون فارغ
@@ -3852,43 +3903,35 @@ While it offers a blend of security, stability, and speed, it's essential t
amnezia::ContainerProps
-
+ Lowمنخفض
-
+ Highمتوسط او عالي
- Extreme
- شديد
-
-
-
+ I just want to increase the level of my privacy.انا فقط اريد زيادة مستوي الخصوصية.
-
+ I want to bypass censorship. This option recommended in most cases.أريد تجاوز الرقابة. يوصى بهذا الخيار في معظم الحالات.
-
- Most VPN protocols are blocked. Recommended if other options are not working.
- يتم حظر معظم بروتوكولات VPN. يوصى به إذا كانت الخيارات الأخرى لا تعمل.
- main2
-
+ Private key passphraseعبارة المرور الخاصة بالمفتاح
-
+ Saveاحفظ
diff --git a/client/translations/amneziavpn_fa_IR.ts b/client/translations/amneziavpn_fa_IR.ts
index 0b5b264c..5b2c5818 100644
--- a/client/translations/amneziavpn_fa_IR.ts
+++ b/client/translations/amneziavpn_fa_IR.ts
@@ -1,6 +1,54 @@
+
+ ApiServicesModel
+
+
+ Classic VPN for comfortable work, downloading large files and watching videos. Works for any sites. Speed up to %1 MBit/s
+
+
+
+
+ VPN to access blocked sites in regions with high levels of Internet censorship.
+
+
+
+
+ Amnezia Premium - A classic VPN for comfortable work, downloading large files, and watching videos in high resolution. It works for all websites, even in countries with the highest level of internet censorship.
+
+
+
+
+ Amnezia Free is a free VPN to bypass blocking in countries with high levels of internet censorship
+
+
+
+
+ %1 MBit/s
+
+
+
+
+ %1 days
+
+
+
+
+ VPN will open only popular sites blocked in your region, such as Instagram, Facebook, Twitter and others. Other sites will be opened from your real IP address, <a href="%1/free" style="color: #FBB26A;">more details on the website.</a>
+
+
+
+
+ Free
+
+
+
+
+ %1 $/month
+
+
+AppSplitTunnelingController
@@ -27,7 +75,7 @@
ConnectButton
-
+ Unable to disconnect during configuration preparation
@@ -35,63 +83,63 @@
ConnectionController
-
+ VPN Protocols is not installed.
Please install VPN container at firstپروتکل ویپیان نصب نشده است
لطفا کانتینر ویپیان را نصب کنید
-
+ Connecting...در حال ارتباط...
-
+ Connectedمتصل
-
+ Preparing...
-
+ Settings updated successfully, reconnnection...تنظیمات به روز رسانی شد
در حال اتصال دوباره...
-
+ Settings updated successfullyتنظیمات با موفقیت بهروزرسانی شدند
-
+ The selected protocol is not supported on the current platformپروتکل انتخاب شده بر روی این پلتفرم پشتیبانی نمیشود
-
+ unable to create configuration
-
+ Reconnecting...اتصال دوباره...
-
-
-
+
+
+ Connectاتصال
-
+ Disconnecting...قطع ارتباط...
@@ -132,7 +180,7 @@
&پیوست
-
+ &SelectAll&انتخاب همه
@@ -230,84 +278,104 @@ Can't be disabled for current server
InstallController
-
+ %1 installed successfully. %1 با موفقیت نصب شد.
-
+ %1 is already installed on the server. %1 در حال حاضر بر روی سرور نصب شده است.
-
+
Added containers that were already installed on the server
کانتینرهایی که بر روی سرور موجود بودند اضافه شدند
-
+
Already installed containers were found on the server. All installed containers have been added to the application
کانتینرهای نصب شده بر روی سرور شناسایی شدند. تمام کانتینترهای نصب شده به نرم افزار اضافه شدند
-
+ Settings updated successfullyتنظیمات با موفقیت بهروزرسانی شدند
-
+ Server '%1' was rebootedسرور %1 راه اندازی مجدد شد
-
+ Server '%1' was removedسرور %1 حذف شد
-
+ All containers from server '%1' have been removedتمام کانتینترها از سرور %1 حذف شدند
-
+ %1 has been removed from the server '%2'%1 از سرور %2 حذف شد
-
+
+ Api config removed
+
+
+
+ %1 cached profile cleared
-
+ Please login as the userلطفا به عنوان کاربر وارد شوید
-
+ Server added successfullyسرور با موفقیت اضافه شد
+
+
+ %1 installed successfully.
+
+
+
+
+ API config reloaded
+
+
+
+
+ Successfully changed the country of connection to %1
+
+ InstalledAppsDrawer
-
+ Choose application
-
+ application name
-
+ Add selected
@@ -362,45 +430,53 @@ Already installed containers were found on the server. All installed containers
PageDeinstalling
-
+ Removing services from %1حذف سرویسها از %1
-
+ Usually it takes no more than 5 minutesمعمولا بیش از 5 دقیقه طول نمیکشد
+
+ PageDevMenu
+
+
+ Gateway endpoint
+
+
+PageHome
-
+ Logging enabled
-
+ Split tunneling enabledفعال شدن تونل تقسیمشده
-
+ Split tunneling disabledتونل تقسیمشده غیرفعال شده
-
+ VPN protocolپروتکل ویپیان
-
+ Serversسرورها
-
+ Unable change server while there is an active connectionامکان تغییر سرور در هنگام متصل بودن وجود ندارد
@@ -408,17 +484,17 @@ Already installed containers were found on the server. All installed containers
PageProtocolAwgSettings
-
+ AmneziaWG settingsتنظیمات AmneziaWG
-
+ Portپورت
-
+ MTU
@@ -431,42 +507,87 @@ Already installed containers were found on the server. All installed containers
آیا میخواهید AmneziaWG از سرور حذف شود؟
-
+ All users with whom you shared a connection with will no longer be able to connect to it.همه کاربرانی که با آنها ارتباطی به اشتراک گذاشتهاید دیگر قادر به اتصال به آن نخواهند بود.
-
+ Saveذخیره
-
+
+ Jc - Junk packet count
+
+
+
+
+ Jmin - Junk packet minimum size
+
+
+
+
+ Jmax - Junk packet maximum size
+
+
+
+
+ S1 - Init packet junk size
+
+
+
+
+ S2 - Response packet junk size
+
+
+
+
+ H1 - Init packet magic header
+
+
+
+
+ H2 - Response packet magic header
+
+
+
+
+ H4 - Transport packet magic header
+
+
+
+
+ H3 - Underload packet magic header
+
+
+
+ The values of the H1-H4 fields must be unique
-
+ The value of the field S1 + message initiation size (148) must not equal S2 + message response size (92)
-
+ Save settings?تنظیمات را ذخیره کن?
-
+ Continueادامه
-
+ Cancelکنسل
-
+ Unable change settings while there is an active connection
@@ -474,33 +595,33 @@ Already installed containers were found on the server. All installed containers
PageProtocolCloakSettings
-
+ Cloak settingsتنظیمات Cloak
-
+ Disguised as traffic fromپنهان کردن به عنوان ترافیک از
-
+ Portپورت
-
+ Cipherرمزگذاری
-
+ Saveذخیره
-
+ Unable change settings while there is an active connection
@@ -508,170 +629,170 @@ Already installed containers were found on the server. All installed containers
PageProtocolOpenVpnSettings
-
+ OpenVPN settingsتنظیمات OpenVPN
-
+ VPN address subnetزیرشبکه آدرس VPN
-
+ Network protocolپروتکل شبکه
-
+ Portپورت
-
+ Auto-negotiate encryptionرمزگذاری خودکار
-
+ Hashهش
-
+ SHA512SHA512
-
+ SHA384SHA384
-
+ SHA256SHA256
-
+ SHA3-512SHA3-512
-
+ SHA3-384SHA3-384
-
+ SHA3-256SHA3-256
-
+ whirlpoolwhirlpool
-
+ BLAKE2b512BLAKE2b512
-
+ BLAKE2s256BLAKE2s256
-
+ SHA1SHA1
-
+ Cipherرمزگذاری
-
+ AES-256-GCMAES-256-GCM
-
+ AES-192-GCMAES-192-GCM
-
+ AES-128-GCMAES-128-GCM
-
+ AES-256-CBCAES-256-CBC
-
+ AES-192-CBCAES-192-CBC
-
+ AES-128-CBCAES-128-CBC
-
+ ChaCha20-Poly1305ChaCha20-Poly1305
-
+ ARIA-256-CBCARIA-256-CBC
-
+ CAMELLIA-256-CBCCAMELLIA-256-CBC
-
+ nonenone
-
+ TLS authاعتبار TLS
-
+ Block DNS requests outside of VPNمسدود کردن درخواستهای DNS خارج از ویپیان
-
+ Additional client configuration commandsتنظیمات و دستورات اضافه برنامه متصل شونده
-
-
+
+ Commands:دستورات:
-
+ Additional server configuration commandsتنظیمات و دستورات اضافه سرور
-
+ Unable change settings while there is an active connection
@@ -696,7 +817,7 @@ Already installed containers were found on the server. All installed containers
کنسل
-
+ Saveذخیره
@@ -704,32 +825,32 @@ Already installed containers were found on the server. All installed containers
PageProtocolRaw
-
+ settings تنظیمات
-
+ Show connection optionsنمایش تنظیمات اتصال
-
+ Connection options %1تنظیمات اتصال %1
-
+ Remove حذف
-
+ Remove %1 from server?%1 از سرور حذف شود؟
-
+ All users with whom you shared a connection with will no longer be able to connect to it.همه کاربرانی که با آنها ارتباطی به اشتراک گذاشتهاید دیگر قادر به اتصال به آن نخواهند بود.
@@ -738,12 +859,12 @@ Already installed containers were found on the server. All installed containers
همه کاربرانی که با آن این پروتکل VPN را به اشتراک گذاشتهاید دیگر نمیتوانند به آن متصل شوند.
-
+ Continueادامه
-
+ Cancelکنسل
@@ -751,28 +872,28 @@ Already installed containers were found on the server. All installed containers
PageProtocolShadowSocksSettings
-
+ Shadowsocks settingsتنظیمات Shadowsocks
-
+ Portپورت
-
+ Cipherرمزگذاری
-
+ Saveذخیره
-
+ Unable change settings while there is an active connection
@@ -780,22 +901,22 @@ Already installed containers were found on the server. All installed containers
PageProtocolWireGuardSettings
-
+ WG settings
-
+ Portپورت
-
+ MTU
-
+ Unable change settings while there is an active connection
@@ -808,7 +929,7 @@ Already installed containers were found on the server. All installed containers
کنسل
-
+ Saveذخیره
@@ -816,22 +937,22 @@ Already installed containers were found on the server. All installed containers
PageProtocolXraySettings
-
+ XRay settings
-
+ Disguised as traffic fromپنهان کردن به عنوان ترافیک از
-
+ Saveذخیره
-
+ Unable change settings while there is an active connection
@@ -846,39 +967,39 @@ Already installed containers were found on the server. All installed containers
PageServiceDnsSettings
-
+ A DNS service is installed on your server, and it is only accessible via VPN.
یک سرویس DSN بر روی سرور شما نصب شده و فقط از طریق ویپیان قابل دسترسی میباشد.
-
+ The DNS address is the same as the address of your server. You can configure DNS in the settings, under the connections tab.آدرس DSN همان آدرس سرور شماست. میتوانید از قسمت تنظیمات و تب اتصالات DSN خود را تنظیم کنید.
-
+ Remove جذف
-
+ Remove %1 from server?%1 از سرور حذف شود؟
-
+ Continueادامه
-
+ Cancelکنسل
-
+ Cannot remove AmneziaDNS from running server
@@ -886,157 +1007,153 @@ Already installed containers were found on the server. All installed containers
PageServiceSftpSettings
-
+ Settings updated successfullyتنظیمات با موفقیت بهروزرسانی شد
-
+ SFTP settingsتنظیمات SFTP
-
+ Hostهاست
-
-
-
-
+
+
+
+ Copiedکپی شد
-
+ Portپورت
-
+ User nameنام کاربری
-
+ Passwordرمز عبور
-
+ Mount folder on deviceبارگذاری پوشه بر روی دستگاه
-
+ In order to mount remote SFTP folder as local drive, perform following steps: <br>برای بارگذاری پوشه SFTP بر روی درایو محلی قدمهای زیر را انجام دهید: <br>
-
-
+
+ <br>1. Install the latest version of <br> 1. آخرین نسخه را نصب کنید
-
-
+
+ <br>2. Install the latest version of <br> 2. آخرین نسخه را نصب کنید
-
+ Detailed instructionsجزییات دستورالعملها
- Remove SFTP and all data stored there
- حذف SFTP و تمام دادههای ذخیره شده در آن
+ حذف SFTP و تمام دادههای ذخیره شده در آن
- Remove SFTP and all data stored there?
- پوشه SFTP و تمام دادههای آن حذف شوند؟
+ پوشه SFTP و تمام دادههای آن حذف شوند؟
- Continue
- ادامه
+ ادامه
- Cancel
- کنسل
+ کنسلPageServiceSocksProxySettings
-
+ Settings updated successfully
-
-
+
+ SOCKS5 settings
-
+ Hostهاست
-
-
-
-
+
+
+
+ Copiedکپی شد
-
-
+
+ Portپورت
-
+ User nameنام کاربری
-
-
+
+ Passwordرمز عبور
-
+ Username
-
-
+
+ Change connection settings
-
+ The port must be in the range of 1 to 65535
-
+ Password cannot be empty
-
+ Username cannot be empty
@@ -1044,95 +1161,96 @@ Already installed containers were found on the server. All installed containers
PageServiceTorWebsiteSettings
-
+ Settings updated successfullyتنظیمات با موفقیت بهروزرسانی شد
-
+ Tor website settingsتنظیمات وبسایت Tor
-
+ Website addressآدرس وبسایت
-
+ Copiedکپی شد
-
+ Use <a href="https://www.torproject.org/download/" style="color: #FBB26A;">Tor Browser</a> to open this URL.
-
+ After creating your onion site, it takes a few minutes for the Tor network to make it available for use.پس از ایجاد سایت پیاز خود، چند دقیقه طول میکشد تا شبکه تور آن را برای استفاده فراهم کند.
-
+ When configuring WordPress set the this onion address as domain.زمانی که سایت وردپرس را تنظیم میکنید این آدرس پیازی را به عنوان دامنه قرار دهید.
- Remove website
- حذف وب سایت
+ حذف وب سایت
- The site with all data will be removed from the tor network.
- سایت با تمام دادهها از شبکه Tor حذف خواهد شد.
+ سایت با تمام دادهها از شبکه Tor حذف خواهد شد.
- Continue
- ادامه
+ ادامه
- Cancel
- کنسل
+ کنسلPageSettings
-
+ Settingsتنظیمات
-
+ Serversسرورها
-
+ Connectionارتباط
-
+ Applicationنرمافزار
-
+ Backupبکآپ
-
+ About AmneziaVPNدرباره Amnezia
+ Dev console
+
+
+
+ Close applicationبستن نرمافزار
@@ -1140,135 +1258,209 @@ Already installed containers were found on the server. All installed containers
PageSettingsAbout
-
+ Support Amneziaپشتیبانی از Amnezia
-
+ Amnezia is a free and open-source application. You can support the developers if you like it.Amnezia یک برنامه رایگان و متن باز است. اگر دوست دارید می توانید از توسعه دهندگان حمایت کنید.
-
+ Contactsمخاطب
-
+ Telegram groupگروه تلگرام
-
+ To discuss featuresبرای گفتگو در مورد ویژگیها
-
+ https://t.me/amnezia_vpn_enhttps://t.me/amnezia_vpn
-
+ Mailایمیل
-
+ For reviews and bug reportsبرای ارائه نظرات و گزارشات باگ
-
+ GitHubGitHub
-
+ https://github.com/amnezia-vpn/amnezia-clienthttps://github.com/amnezia-vpn/amnezia-client
-
+ Websiteوب سایت
- https://amnezia.org
- https://amnezia.org
+ https://amnezia.org
-
+ Software version: %1%1 :نسخه نرمافزار
-
+ Check for updatesبررسی بروزرسانی
-
+ Privacy Policy
- PageSettingsAppSplitTunneling
+ PageSettingsApiServerInfo
-
- Cannot change split tunneling settings during active connection
- نمی توان تنظیمات تونل تقسیم را در طول اتصال فعال تغییر داد
-
-
-
- Only the apps from the list should have access via VPN
+
+ For the region
-
- Apps from the list should not have access via VPN
+
+ Price
-
- App split tunneling
+
+ Work period
-
- Mode
- حالت
-
-
-
- Remove
+
+ Speed
-
+
+ Support tag
+
+
+
+
+ Copied
+ کپی شد
+
+
+
+ Reload API config
+
+
+
+
+ Reload API config?
+
+
+
+
+ Continue
-
+
+ Cancelکنسل
-
+
+ Cannot reload API config during active connection
+
+
+
+
+ Remove from application
+
+
+
+
+ Remove from application?
+
+
+
+
+ Cannot remove server during active connection
+
+
+
+
+ PageSettingsAppSplitTunneling
+
+
+ Cannot change split tunneling settings during active connection
+ نمی توان تنظیمات تونل تقسیم را در طول اتصال فعال تغییر داد
+
+
+
+ Only the apps from the list should have access via VPN
+
+
+
+
+ Apps from the list should not have access via VPN
+
+
+
+
+ App split tunneling
+
+
+
+
+ Mode
+ حالت
+
+
+
+ Remove
+
+
+
+
+ Continue
+
+
+
+
+ Cancel
+ کنسل
+
+
+ application name
-
+ Open executable file
-
+ Executable files (*.*)
@@ -1276,102 +1468,102 @@ Already installed containers were found on the server. All installed containers
PageSettingsApplication
-
+ Applicationنرم افزار
-
+ Allow application screenshotsمجوز اسکرینشات در برنامه
-
+ Enable notifications
-
+ Enable notifications to show the VPN state in the status bar
-
+ Auto startشروع خودکار
-
+ Launch the application every time the device is startsراهاندازی نرمافزار با هر بار روشن شدن دستگاه
-
+ Auto connectاتصال خودکار
-
+ Connect to VPN on app startاتصال به ویپیان با شروع نرمافزار
-
+ Start minimizedشروع به صورت کوچک
-
+ Launch application minimizedراهاندازی برنامه به صورت کوچک
-
+ Languageزبان
-
+ Loggingگزارشات
-
+ Enabledفعال
-
+ Disabledغیر فعال
-
+ Reset settings and remove all data from the applicationریست کردن تنظیمات و حذف تمام دادهها از نرمافزار
-
+ Reset settings and remove all data from the application?ریست کردن تنظیمات و حذف تمام دادهها از نرمافزار؟
-
+ All settings will be reset to default. All installed AmneziaVPN services will still remain on the server.تمام تنظیمات به حالت پیشفرض ریست میشوند. تمام سرویسهای Amnezia بر روی سرور باقی میمانند.
-
+ Continueادامه
-
+ Cancelکنسل
-
+ Cannot reset settings during active connection
@@ -1379,7 +1571,7 @@ Already installed containers were found on the server. All installed containers
PageSettingsBackup
-
+ Settings restored from backup fileتنظیمات از فایل پشتیبان بازیابی شد
@@ -1458,62 +1650,62 @@ Already installed containers were found on the server. All installed containers
PageSettingsConnection
-
+ Connectionارتباط
-
+ Use AmneziaDNSاستفاده از AmneziaDNS
-
+ If AmneziaDNS is installed on the serverاگر AmneziaDNS بر روی سرور نصب شده باشد
-
+ DNS serversسرورهای DNS
-
+ When AmneziaDNS is not used or installedوقتی AmneziaDNS استفاده نشده یا نصب نشده است
-
+ Allows you to use the VPN only for certain Appsبه شما امکان می دهد از VPN فقط برای برخی برنامه ها استفاده کنید
-
+ KillSwitch
-
+ Disables your internet if your encrypted VPN connection drops out for any reason.
-
+ Cannot change killSwitch settings during active connection
-
+ Site-based split tunnelingجداسازی ترافیک بر اساس سایت
-
+ Allows you to select which sites you want to access through the VPNمیتوانید مشخص کنید که چه سایتهایی از ویپیان استفاده کنند
-
+ App-based split tunnelingجداسازی ترافیک بر اساس نرمافزار
@@ -1521,62 +1713,62 @@ Already installed containers were found on the server. All installed containers
PageSettingsDns
-
+ Default server does not support custom DNSسرور پیشفرض از دیاناس سفارشی پشتیبانی نمیکند
-
+ DNS serversسرورهای DNS
-
+ If AmneziaDNS is not used or installedاگر AmneziaDNS نصب نباشد یا استفاده نشود
-
+ Primary DNSDNS اصلی
-
+ Secondary DNSDNS ثانویه
-
+ Restore defaultبازگشت به پیشفرض
-
+ Restore default DNS settings?بازگشت به تنظیمات پیشفرض DNS؟
-
+ Continueادامه
-
+ Cancelکنسل
-
+ Settings have been resetتنظیمات ریست شد
-
+ Saveذخیره
-
+ Settings savedذخیره تنظیمات
@@ -1584,72 +1776,72 @@ Already installed containers were found on the server. All installed containers
PageSettingsLogging
-
+ Logging is enabled. Note that logs will be automatically disabled after 14 days, and all log files will be deleted.
-
+ Loggingگزارشات
-
+ Enabling this function will save application's logs automatically. By default, logging functionality is disabled. Enable log saving in case of application malfunction.فعال کردن این عملکرد باعث ذخیره خودکار لاگهای برنامه میشود. به طور پیشفرض، قابلیت ثبت لاگ غیرفعال است. در صورت بروز خطا در برنامه، ذخیره لاگ را فعال کنید.
-
+ Save logsذخیره گزارشات
-
+ Open folder with logsباز کردن پوشه گزارشات
-
+ Saveذخیره
-
+ Logs files (*.log)Logs files (*.log)
-
+ Logs file savedفایل گزارشات ذخیره شد
-
+ Save logs to fileذخیره گزارشات در فایل
-
+ Clear logs?پاک کردن گزارشات؟
-
+ Continueادامه
-
+ Cancelکنسل
-
+ Logs have been cleaned upگزارشات پاک شدند
-
+ Clear logsپاک کردن گزارشات
@@ -1657,7 +1849,7 @@ Already installed containers were found on the server. All installed containers
PageSettingsServerData
-
+ All installed containers have been added to the applicationتمام کانتینرهای نصب شده به نرمافزار اضافه شدند
@@ -1674,7 +1866,7 @@ Already installed containers were found on the server. All installed containers
پاک کردن پروفایل ذخیره شده؟
-
+ No new installed containers foundکانتینر نصب شده جدیدی پیدا نشد
@@ -1683,104 +1875,104 @@ Already installed containers were found on the server. All installed containers
-
-
-
-
-
- Continue
- ادامه
-
+ Continue
+ ادامه
+
+
+
+
+
+ Cancelکنسل
-
+ Check the server for previously installed Amnezia servicesچک کردن سرویسهای نصب شده Amnezia بر روی سرور
-
+ Add them to the application if they were not displayedاضافه کردن آنها به نرمافزار اگر نمایش داده نشدهاند
-
+ Reboot serverسرور را دوباره راهاندازی کنید
-
+ Do you want to reboot the server?آیا میخواهید سرور را دوباره راهاندازی کنید؟
-
+ The reboot process may take approximately 30 seconds. Are you sure you wish to proceed?فرآیند راهاندازی ممکن است حدود ۳۰ ثانیه طول بکشد. آیا مطمئن هستید که میخواهید ادامه دهید؟
-
+ Cannot reboot server during active connection
-
+ Do you want to remove the server from application?آیا میخواهید سرور را از برنامه حذف کنید؟
-
+ Cannot remove server during active connection
-
+ Do you want to clear server from Amnezia software?آیا میخواهید سرور را از نرمافزار Amnezia پاک کنید؟
-
+ All users whom you shared a connection with will no longer be able to connect to it.همه کاربرانی که با آنها ارتباطی به اشتراک گذاشتهاید دیگر قادر به اتصال به آن نخواهند بود.
-
+ Cannot clear server from Amnezia software during active connection
-
+ Reset API configتنظیمات API را بازنشانی کنید
-
+ Do you want to reset API config?آیا می خواهید پیکربندی API را بازنشانی کنید؟
-
+ Cannot reset API config during active connection
-
+ Remove server from applicationحذف کردن سرور از نرمافزار
-
+ All installed AmneziaVPN services will still remain on the server.تمام سرویسهای نصبشده Amnezia همچنان بر روی سرور باقی خواهند ماند.
-
+ Clear server from Amnezia softwareپاک کردن سرور از نرمافزار Amnezia
@@ -1788,27 +1980,27 @@ Already installed containers were found on the server. All installed containers
PageSettingsServerInfo
-
+ Server nameنام سرور
-
+ Saveذخیره
-
+ Protocolsپروتکلها
-
+ Servicesسرویسها
-
+ Managementمدیریت
@@ -1816,59 +2008,59 @@ Already installed containers were found on the server. All installed containers
PageSettingsServerProtocol
-
+ settings تنظیمات
-
+ Clear %1 profile
-
+ Clear %1 profile?
-
+
-
+ Unable to clear %1 profile while there is an active connection
-
+ Remove حذف
-
+ Remove %1 from server?حذف %1 از سرور؟
-
+ All users with whom you shared a connection will no longer be able to connect to it.تمام کاربرانی که این ارتباط را با آنها به اشتراک گذاشتهاید دیگر نمیتوانند به آن متصل شوند.
-
+ Cannot remove active container
-
-
+
+ Continueادامه
-
-
+
+ Cancelکنسل
@@ -1876,7 +2068,7 @@ Already installed containers were found on the server. All installed containers
PageSettingsServersList
-
+ Serversسرورها
@@ -1884,110 +2076,155 @@ Already installed containers were found on the server. All installed containers
PageSettingsSplitTunneling
-
+ Default server does not support split tunneling functionسرور پیشفرض از عملکرد تونلسازی تقسیم شده پشتیبانی نمیکند
-
+ Addresses from the list should not be accessed via VPNدسترسی به آدرسهای لیست بدون ویپیان
-
+ Split tunnelingجداسازی ترافیک
-
+ Modeحالت
-
+ Remove حذف
-
+ Continueادامه
-
+ Cancelکنسل
-
+ Cannot change split tunneling settings during active connectionنمی توان تنظیمات تونل تقسیم را در طول اتصال فعال تغییر داد
-
+ Only the sites listed here will be accessed through the VPNتنها سایتهای موجود در اینجا از طریق VPN دسترسی داده خواهند شد
-
+ website or IPوبسایت یا آدرس IP
-
+ Import / Export Sitesوارد کردن / صادر کردن وبسایتها
-
+ Importبارگذاری
-
+ Save site listذخیره لیست سایتها
-
+ Save sitesذخیره سایتها
-
-
-
+
+
+ Sites files (*.json)Sites files (*.json)
-
+ Import a list of sitesبارگذاری لیست سایتها
-
+ Replace site listجایگزین کردن لیست سایت
-
-
+
+ Open sites fileباز کردن فایل سایتها
-
+ Add imported sites to existing onesاضافه کردن سایتهای بارگذاری شده به سایتهای موجود
+
+ PageSetupWizardApiServiceInfo
+
+
+ For the region
+
+
+
+
+ Price
+
+
+
+
+ Work period
+
+
+
+
+ Speed
+
+
+
+
+ Features
+
+
+
+
+ Connect
+ اتصال
+
+
+
+ PageSetupWizardApiServicesList
+
+
+ VPN by Amnezia
+
+
+
+
+ Choose a VPN service that suits your needs.
+
+
+PageSetupWizardConfigSource
- Server connection
- ارتباط سرور
+ ارتباط سرورDo not use connection code from public sources. It may have been created to intercept your data.
@@ -1998,95 +2235,171 @@ It's okay as long as it's from someone you trust.
ایرادی ندارد که از طرف کسی باشد که به او اعتماد دارید.
- Do not use connection codes from untrusted sources, as they may be created to intercept your data.
- از کدهای اتصال از منابع نامعتبر استفاده نکنید، زیرا ممکن است برای رهگیری داده های شما ایجاد شده باشند.
+ از کدهای اتصال از منابع نامعتبر استفاده نکنید، زیرا ممکن است برای رهگیری داده های شما ایجاد شده باشند.
- What do you have?
- چی داری؟
+ چی داری؟
-
+ File with connection settingsفایل شامل تنظیمات اتصال
- File with connection settings or backup
- فایل شامل تنظیمات اتصال یا بکآپ
+ فایل شامل تنظیمات اتصال یا بکآپ
-
+
+ Connection
+ ارتباط
+
+
+
+ Insert the key, add a configuration file or scan the QR-code
+
+
+
+
+ Insert key
+
+
+
+
+ Insert
+ وارد کردن
+
+
+
+ Continue
+
+
+
+
+ Other connection options
+
+
+
+
+ VPN by Amnezia
+
+
+
+
+ Connect to classic paid and free VPN services from Amnezia
+
+
+
+
+ Self-hosted VPN
+
+
+
+
+ Configure Amnezia VPN on your own server
+
+
+
+
+ Restore from backup
+ بازیابی از پشتیبان
+
+
+
+ Open backup file
+ باز کردن فایل پشتیبان
+
+
+
+ Backup files (*.backup)
+ Backup files (*.backup)
+
+
+ Open config fileباز کردن فایل تنظیمات
-
+ QR codeQR-Code
-
+
+ I have nothing
+ من هیچی ندارم
+
+ Key as text
- متن شامل کلید
+ متن شامل کلیدPageSetupWizardCredentials
-
+ Server IP address [:port]آدرس آیپی سرور (:پورت)
-
+ Continueادامه
-
+ Enter the address in the format 255.255.255.255:88آدرس را با فرمت 255.255.255.255:88 وارد کنید
-
+ Configure your serverسرور خود را پیکربندی کنید
-
+ 255.255.255.255:22
-
+ SSH Username
-
+ Password or SSH private keyرمز عبور یا کلید خصوصی SSH
-
+ All data you enter will remain strictly confidential and will not be shared or disclosed to the Amnezia or any third partiesتمام دادههایی که شما وارد میکنید به شدت محرمانه است و با Amnezia یا هر شخص ثالث دیگری به اشتراک گذاشته نمیشود
-
+
+ How to run your VPN server
+
+
+
+
+ Where to get connection data, step-by-step instructions for buying a VPS
+
+
+
+ Ip address cannot be emptyآدرس آیپی نمیتواند خالی باشد
-
+ Login cannot be emptyنامکاربری نمیتواند خالی باشد
-
+ Password/private key cannot be emptyپسورد یا کلید خصوصی نمیتواند خالی باشد
@@ -2094,22 +2407,22 @@ It's okay as long as it's from someone you trust.
PageSetupWizardEasy
-
+ What is the level of internet control in your region?سطح کنترل اینترنت در منطقه شما چگونه است؟
-
+ Choose a VPN protocolیک پروتکل VPN را انتخاب کنید
-
+ Skip setupرد شدن از تنظیم
-
+ Continueادامه
@@ -2117,38 +2430,38 @@ It's okay as long as it's from someone you trust.
PageSetupWizardInstalling
-
+ The server has already been added to the applicationسرور در حال حاضر به نرمافزار اضافه شده است
-
+ Amnezia has detected that your server is currently Amnezia has detected that your server is currently
-
+ busy installing other software. Amnezia installation مشغول نصب نرم افزارهای دیگر نصب Amnezia
-
+ will pause until the server finishes installing other softwareمتوقف شده تا زمانی که سرور نصب نرمافزار دیگر را تمام کند
-
+ Installingدر حال نصب
-
+ Cancel installationلغو عملیات نصب
-
-
+
+ Usually it takes no more than 5 minutesمعمولا بیش از 5 دقیقه طول نمیکشد
@@ -2156,37 +2469,37 @@ It's okay as long as it's from someone you trust.
PageSetupWizardProtocolSettings
-
+ Installing %1در حال نصب %1
-
+ More detailedجزییات بیشتر
-
+ Closeبستن
-
+ Network protocolپروتکل شبکه
-
+ Portپورت
-
+ Installنصب
-
+ The port must be in the range of 1 to 65535
@@ -2194,12 +2507,12 @@ It's okay as long as it's from someone you trust.
PageSetupWizardProtocols
-
+ VPN protocolپروتکل ویپیان
-
+ Choose the one with the highest priority for you. Later, you can install other protocols and additional services, such as DNS proxy and SFTP.پروتکلی که بیشترین اولویت را برای شما دارد انتخاب کنید. بعدا، میتوانید پروتکلها و سرویسهای اضافه مانند پروکسی DNS و SFTP را هم نصب کنید.
@@ -2207,7 +2520,7 @@ It's okay as long as it's from someone you trust.
PageSetupWizardQrReader
-
+ Point the camera at the QR code and hold for a couple of seconds. دوربین را روی QR Code بگیرید و برای چند ثانیه آن را نگه دارید.
@@ -2215,60 +2528,55 @@ It's okay as long as it's from someone you trust.
PageSetupWizardStart
- Settings restored from backup file
- تنظیمات از فایل بکآپ بازیابی شدند
+ تنظیمات از فایل بکآپ بازیابی شدند
- Free service for creating a personal VPN on your server.
- سرویس رایگان برای ایجاد ویپیان شخصی بر روی سرور خودتان.
+ سرویس رایگان برای ایجاد ویپیان شخصی بر روی سرور خودتان.
- Helps you access blocked content without revealing your privacy, even to VPN providers.
- به شما کمک میکند که بدون فاش کردن حریم شخصی خودتان, حتی برای ارائه دهنده ویپیان به محتوای مسدود شده دسترسی پیدا کنید.
+ به شما کمک میکند که بدون فاش کردن حریم شخصی خودتان, حتی برای ارائه دهنده ویپیان به محتوای مسدود شده دسترسی پیدا کنید.
- I have the data to connect
- من داده برای اتصال دارم
+ من داده برای اتصال دارم
- I have nothing
- من هیچی ندارم
+ من هیچی ندارم
-
- https://amnezia.org/instructions/0_starter-guide
-
+
+ Let's get started
+ PageSetupWizardTextKey
-
+ Connection keyکلید ارتباط
-
+ A line that starts with vpn://...خطی که با آن شروع می شود vpn://...
-
+ Keyکلید
-
+ Insertوارد کردن
-
+ Continueادامه
@@ -2276,32 +2584,32 @@ It's okay as long as it's from someone you trust.
PageSetupWizardViewConfig
-
+ New connectionارتباط جدید
-
+ Collapse contentجمع کردن محتوا
-
+ Show contentنمایش محتوا
-
+ Enable WireGuard obfuscation. It may be useful if WireGuard is blocked on your provider.
-
+ Use connection codes only from sources you trust. Codes from public sources may have been created to intercept your data.از کدهای اتصال فقط از منابع مورد اعتماد خود استفاده کنید. ممکن است کدهایی از منابع عمومی برای رهگیری داده های شما ایجاد شده باشند
-
+ Connectاتصال
@@ -2309,144 +2617,144 @@ It's okay as long as it's from someone you trust.
PageShare
-
+ OpenVPN native formatفرمت OpenVPN
-
+ WireGuard native formatفرمت WireGuard
-
+ Connectionارتباط
-
-
+
+ Serverسرور
-
+ Config revokedتنظیمات ابطالشد
-
+ Connection to ارتباط با
-
+ File with connection settings to فایل شامل تنظیمات ارتباط با
-
+ Save OpenVPN configذخیره تنظیمات OpenVPN
-
+ Save WireGuard configذخیره تنظیمات WireGuard
-
+ Save AmneziaWG configتنظیمات AmneziaWG را ذخیره کنید
-
+ Save Shadowsocks configذخیره تنظیمات Shadowsocks
-
+ Save Cloak configذخیره تنظیمات Cloak
-
+ Save XRay config
-
+ For the AmneziaVPN appبرای نرمافزار AmneziaVPN
-
+ AmneziaWG native formatفرمت بومی AmneziaWG
-
+ Shadowsocks native formatفرمت Shadowsocks
-
+ Cloak native formatفرمت Cloak
-
+ XRay native format
-
+ Share VPN Accessاتصال vpn را به اشتراک بگذارید
-
+ Share full access to the server and VPNبه اشتراک گذاشتن دسترسی کامل به سرور و ویپیان
-
+ Use for your own devices, or share with those you trust to manage the server.برای دستگاههای خودتان استفاده کنید یا با آنهایی که برای مدیریت سرور به آنها اعتماد دارید به اشتراک بگذارید.
-
-
+
+ Usersکاربران
-
+ User nameنام کاربری
-
+ Searchجستجو
-
+ Creation date: %1
-
+ Latest handshake: %1
-
+ Data received: %1
-
+ Data sent: %1
@@ -2455,65 +2763,65 @@ It's okay as long as it's from someone you trust.
تاریخ ایجاد:
-
+ Renameتغییر نام
-
+ Client nameنام کلاینت
-
+ Saveذخیره
-
+ Revokeابطال
-
+ Revoke the config for a user - %1?لغو پیکربندی برای یک کاربر - %1?
-
+ The user will no longer be able to connect to your server.کاربر دیگر نمیتواند به سرور وصل شود.
-
+ Continueادامه
-
+ Cancelکنسل
-
+ Share VPN access without the ability to manage the serverبه اشتراک گذاشتن دسترسی ویپیان بدون امکان مدیریت سرور
-
-
+
+ Protocolپروتکل
-
-
+
+ Connection formatفرمت ارتباط
-
-
+
+ Shareاشتراکگذاری
@@ -2521,50 +2829,50 @@ It's okay as long as it's from someone you trust.
PageShareFullAccess
-
+ Full access to the server and VPNدسترسی کامل به سرور و ویپیان
-
+ We recommend that you use full access to the server only for your own additional devices.
ما پیشنهاد میکنیم که ازحالت دسترسی کامل به سرور فقط برای دستگاههای دیگر خودتان استفاده کنید.
-
+ If you share full access with other people, they can remove and add protocols and services to the server, which will cause the VPN to work incorrectly for all users. اگر دسترسی کامل را با دیگران به اشتراک بگذارید، آنها میتوانند پروتکلها و سرویسها را حذف یا اضافه کنند که باعث میشود که ویپیان دیگر برای سایر کاربران کار نکند.
-
+ Serverسرور
-
+ Accessing در حال دسترسی به
-
+ File with accessing settings to فایل شامل تنظیمات دسترسی به
-
+ Shareاشتراکگذاری
-
+ Connection to ارتباط با
-
+ File with connection settings to فایل شامل تنظیمات ارتباط با
@@ -2572,15 +2880,20 @@ It's okay as long as it's from someone you trust.
PageStart
-
+ Logging was disabled after 14 days, log files were deleted
+
+
+ Settings restored from backup file
+
+ PopupType
-
+ Closeبستن
@@ -2971,7 +3284,7 @@ It's okay as long as it's from someone you trust.
این پیکربندی قبلاً به برنامه اضافه شده است
-
+ ErrorCode: %1. کد خطا: %1.
@@ -3056,37 +3369,42 @@ It's okay as long as it's from someone you trust.
-
- QFile error: The file could not be opened
+
+ Missing AGW public key
- QFile error: An error occurred when reading from the file
+ QFile error: The file could not be opened
- QFile error: The file could not be accessed
+ QFile error: An error occurred when reading from the file
- QFile error: An unspecified error occurred
+ QFile error: The file could not be accessed
- QFile error: A fatal error occurred
+ QFile error: An unspecified error occurred
+ QFile error: A fatal error occurred
+
+
+
+ QFile error: The operation was aborted
-
+ Internal errorInternal error
@@ -3539,7 +3857,7 @@ For more detailed information, you can
SelectLanguageDrawer
-
+ Choose languageانتخاب زبان
@@ -3547,13 +3865,13 @@ For more detailed information, you can
Settings
-
+ Server #1Server #1
-
-
+
+ ServerServer
@@ -3578,39 +3896,39 @@ For more detailed information, you can
ShareConnectionDrawer
-
-
+
+ Save AmneziaVPN configذخیره تنظیمات AmneziaVPN
-
+ Shareاشتراکگذاری
-
+ Copyکپی
-
-
+
+ Copiedکپی شد
-
+ Copy config stringکپیکردن متن تنظیمات
-
+ Show connection settingsنمایش تنظیمات ارتباط
-
+ To read the QR code in the Amnezia app, select "Add server" → "I have data to connect" → "QR code, key or settings file"برای خواندن QR Code در نرمافزار AmneziaVPN "اضافه کردن سرور" -> "من داده برای اتصال دارم" -> "QR Code، کلید یا فایل تنظیمات"
@@ -3694,7 +4012,7 @@ For more detailed information, you can
TextFieldWithHeaderType
-
+ The field can't be emptyاین فیلد نمیتواند خالی باشد.
@@ -3753,12 +4071,12 @@ For more detailed information, you can
amnezia::ContainerProps
-
+ Lowپایین
-
+ Highمتوسط یا بالا
@@ -3767,12 +4085,12 @@ For more detailed information, you can
شدید
-
+ I just want to increase the level of my privacy.من فقط میخواهم سطح حریم شخصی خودم را بالا ببرم
-
+ I want to bypass censorship. This option recommended in most cases.من میخواهم از سانسور عبور کنم. این گزینه در اکثر موارد توصیه میشود
@@ -3784,12 +4102,12 @@ For more detailed information, you can
main2
-
+ Private key passphraseعبارت کلید خصوصی
-
+ Saveذخیره
diff --git a/client/translations/amneziavpn_hi_IN.ts b/client/translations/amneziavpn_hi_IN.ts
index e63fe3ff..e5cd57d8 100644
--- a/client/translations/amneziavpn_hi_IN.ts
+++ b/client/translations/amneziavpn_hi_IN.ts
@@ -1,6 +1,54 @@
+
+ ApiServicesModel
+
+
+ Classic VPN for comfortable work, downloading large files and watching videos. Works for any sites. Speed up to %1 MBit/s
+
+
+
+
+ VPN to access blocked sites in regions with high levels of Internet censorship.
+
+
+
+
+ Amnezia Premium - A classic VPN for comfortable work, downloading large files, and watching videos in high resolution. It works for all websites, even in countries with the highest level of internet censorship.
+
+
+
+
+ Amnezia Free is a free VPN to bypass blocking in countries with high levels of internet censorship
+
+
+
+
+ %1 MBit/s
+
+
+
+
+ %1 days
+
+
+
+
+ VPN will open only popular sites blocked in your region, such as Instagram, Facebook, Twitter and others. Other sites will be opened from your real IP address, <a href="%1/free" style="color: #FBB26A;">more details on the website.</a>
+
+
+
+
+ Free
+
+
+
+
+ %1 $/month
+
+
+AppSplitTunnelingController
@@ -27,7 +75,7 @@
ConnectButton
-
+ Unable to disconnect during configuration preparationकॉन्फ़िगरेशन तैयारी के दौरान डिस्कनेक्ट करने में असमर्थ
@@ -35,62 +83,62 @@
ConnectionController
-
-
-
+
+
+ Connectकनेक्ट
-
+ VPN Protocols is not installed.
Please install VPN container at firstपीएन प्रोटोकॉल स्थापित नहीं है.
कृपया पहले वीपीएन कंटेनर स्थापित करें
-
+ Connectedजुड़ा हुआ
-
+ The selected protocol is not supported on the current platformचयनित प्रोटोकॉल वर्तमान प्लेटफ़ॉर्म पर समर्थित नहीं है
-
+ unable to create configurationकॉन्फ़िगरेशन बनाने में असमर्थ
-
+ Connecting...कनेक्ट...
-
+ Reconnecting...पुनः कनेक्ट हो रहा है...
-
+ Disconnecting...डिस्कनेक्ट हो रहा है...
-
+ Preparing...तैयार कर रहे हैं...
-
+ Settings updated successfully, reconnnection...सेटिंग्स सफलतापूर्वक अपडेट हो गईं...
-
+ Settings updated successfullyसेटिंग्स सफलतापूर्वक अपडेट हो गईं
@@ -131,7 +179,7 @@
&चपकाएं
-
+ &SelectAll&सबका चयन करें
@@ -226,84 +274,104 @@ Can't be disabled for current server
InstallController
-
+ %1 installed successfully. %1 सफलतापूर्वक स्थापित हुआ.
-
+ %1 is already installed on the server. %1 पहले से ही सर्वर पर स्थापित है.
-
+
Added containers that were already installed on the server
सर्वर पर पहले से स्थापित कंटेनर जोड़े गए
-
+
Already installed containers were found on the server. All installed containers have been added to the application
सर्वर पर पहले से स्थापित कंटेनर पाए गए। सभी स्थापित कंटेनरों को एप्लिकेशन में जोड़ दिया गया है
-
+ Settings updated successfullyसेटिंग्स सफलतापूर्वक अपडेट हो गईं
-
+ Server '%1' was rebootedसर्वर '%1' रीबूट किया गया था
-
+ Server '%1' was removedसर्वर '%1' रीबूट किया गया था
-
+ All containers from server '%1' have been removedसर्वर '%1' से सभी कंटेनर हटा दिए गए हैं
-
+ %1 has been removed from the server '%2'%1 को सर्वर '%2' से हटा दिया गया है
-
+
+ Api config removed
+
+
+
+ %1 cached profile cleared%1 कैश्ड प्रोफ़ाइल साफ़ की गई
-
+ Please login as the userकृपया उपयोगकर्ता के रूप में लॉगिन करें
-
+ Server added successfullyसर्वर सफलतापूर्वक जोड़ा गया
+
+
+ %1 installed successfully.
+
+
+
+
+ API config reloaded
+
+
+
+
+ Successfully changed the country of connection to %1
+
+ InstalledAppsDrawer
-
+ Choose applicationएप्लिकेशन चुनें
-
+ application nameआवेदन का नाम
-
+ Add selectedचुने हुए को जोड़ो
@@ -358,45 +426,53 @@ Already installed containers were found on the server. All installed containers
PageDeinstalling
-
+ Removing services from %1सर्वर से %1 हटाया गया
-
+ Usually it takes no more than 5 minutesआमतौर पर इसमें 5 मिनट से अधिक समय नहीं लगता है
+
+ PageDevMenu
+
+
+ Gateway endpoint
+
+
+PageHome
-
+ Logging enabledलॉगिंग सक्षम
-
+ Split tunneling enabledस्प्लिट टनलिंग सक्षम
-
+ Split tunneling disabledस्प्लिट टनलिंग अक्षम
-
+ VPN protocolVPN प्रोटोकॉल
-
+ Serversसर्वर
-
+ Unable change server while there is an active connectionसक्रिय कनेक्शन होने पर सर्वर बदलने में असमर्थ
@@ -404,57 +480,102 @@ Already installed containers were found on the server. All installed containers
PageProtocolAwgSettings
-
+ AmneziaWG settingsAmneziaडब्ल्यूजी सेटिंग्स
-
+ Portपोर्ट
-
+ MTUएमटीयू
-
+
+ Jc - Junk packet count
+
+
+
+
+ Jmin - Junk packet minimum size
+
+
+
+
+ Jmax - Junk packet maximum size
+
+
+
+
+ S1 - Init packet junk size
+
+
+
+
+ S2 - Response packet junk size
+
+
+
+
+ H1 - Init packet magic header
+
+
+
+
+ H2 - Response packet magic header
+
+
+
+
+ H4 - Transport packet magic header
+
+
+
+
+ H3 - Underload packet magic header
+
+
+
+ Saveसहेजें
-
+ The values of the H1-H4 fields must be uniqueH1-H4 फ़ील्ड का मान अद्वितीय होना चाहिए
-
+ The value of the field S1 + message initiation size (148) must not equal S2 + message response size (92)फ़ील्ड S1 + संदेश आरंभ आकार (148) का मान S2 + संदेश प्रतिक्रिया आकार (92) के बराबर नहीं होना चाहिए
-
+ Save settings?सेटिंग्स सेव करें?
-
+ All users with whom you shared a connection with will no longer be able to connect to it.वे सभी उपयोगकर्ता जिनके साथ आपने कनेक्शन साझा किया था, वे अब इससे कनेक्ट नहीं हो पाएंगे.
-
+ Unable change settings while there is an active connectionसक्रिय कनेक्शन होने पर सेटिंग बदलने में असमर्थ
-
+ Continueजारी रखना
-
+ Cancelरद्द करना
@@ -462,33 +583,33 @@ Already installed containers were found on the server. All installed containers
PageProtocolCloakSettings
-
+ Cloak settingsलबादा सेटिंग
-
+ Disguised as traffic fromसे यातायात के रूप में प्रच्छन्न
-
+ Portपोर्ट
-
+ Cipherसाइफर
-
+ Saveसहेजें
-
+ Unable change settings while there is an active connectionसक्रिय कनेक्शन होने पर सेटिंग बदलने में असमर्थ
@@ -496,175 +617,175 @@ Already installed containers were found on the server. All installed containers
PageProtocolOpenVpnSettings
-
+ OpenVPN settingsOpenVPN सेटिंग्स
-
+ VPN address subnetVPN एड्रेस सबनेट
-
+ Network protocolनेटवर्क प्रोटोकॉल
-
+ Portपोर्ट
-
+ Auto-negotiate encryptionस्वतः-निगोशिएट एन्क्रिप्शन
-
+ Hash
-
+ SHA512
-
+ SHA384
-
+ SHA256
-
+ SHA3-512
-
+ SHA3-384
-
+ SHA3-256
-
+ whirlpool
-
+ BLAKE2b512
-
+ BLAKE2s256अक्षम
-
+ SHA1
-
+ Cipherसाइफर
-
+ AES-256-GCM
-
+ AES-192-GCM
-
+ AES-128-GCMएईएस-128-जीसीएम
-
+ AES-256-CBC
-
+ AES-192-CBC
-
+ AES-128-CBCएईएस-128-सीबीसी
-
+ ChaCha20-Poly1305चाचा20-पॉली1305
-
+ ARIA-256-CBCएआरआईए-256-सीबीसी
-
+ CAMELLIA-256-CBCकैमेलिया-256-सीबीसी
-
+ noneकोई नहीं
-
+ TLS authटीएलएस प्राधिकरण
-
+ Block DNS requests outside of VPNVPN के बाहर डीएनएस अनुरोधों को ब्लॉक करें
-
+ Additional client configuration commandsअतिरिक्त क्लाइंट कॉन्फ़िगरेशन आदेश
-
-
+
+ Commands:आदेश:
-
+ Additional server configuration commandsअतिरिक्त सर्वर कॉन्फ़िगरेशन आदेश
-
+ Saveसहेजें
-
+ Unable change settings while there is an active connectionसक्रिय कनेक्शन होने पर सेटिंग बदलने में असमर्थ
@@ -672,42 +793,42 @@ Already installed containers were found on the server. All installed containers
PageProtocolRaw
-
+ settings समायोजन
-
+ Show connection optionsकनेक्शन विकल्प दिखाएँ
-
+ Connection options %1कनेक्शन विकल्प%1
-
+ Remove निकालना
-
+ Remove %1 from server?सर्वर से %1 हटाएँ?
-
+ All users with whom you shared a connection with will no longer be able to connect to it.वे सभी उपयोगकर्ता जिनके साथ आपने कनेक्शन साझा किया था, वे अब इससे कनेक्ट नहीं हो पाएंगे.
-
+ Continueजारी रखना
-
+ Cancelरद्द करना
@@ -715,28 +836,28 @@ Already installed containers were found on the server. All installed containers
PageProtocolShadowSocksSettings
-
+ Shadowsocks settingsशैडोसॉक्स सेटिंग्स
-
+ Portपोर्ट
-
+ Cipherसाइफर
-
+ Saveसहेजें
-
+ Unable change settings while there is an active connectionसक्रिय कनेक्शन होने पर सेटिंग बदलने में असमर्थ
@@ -744,27 +865,27 @@ Already installed containers were found on the server. All installed containers
PageProtocolWireGuardSettings
-
+ WG settingsडब्ल्यूजी सेटिंग्स
-
+ Portबंदरगाह
-
+ MTUएमटीयू
-
+ Saveसहेजें
-
+ Unable change settings while there is an active connectionसक्रिय कनेक्शन होने पर सेटिंग बदलने में असमर्थ
@@ -772,22 +893,22 @@ Already installed containers were found on the server. All installed containers
PageProtocolXraySettings
-
+ XRay settingsएक्सरे सेटिंग्स
-
+ Disguised as traffic fromसे यातायात के रूप में प्रच्छन्न
-
+ Saveसहेजें
-
+ Unable change settings while there is an active connectionसक्रिय कनेक्शन होने पर सेटिंग बदलने में असमर्थ
@@ -795,39 +916,39 @@ Already installed containers were found on the server. All installed containers
PageServiceDnsSettings
-
+ A DNS service is installed on your server, and it is only accessible via VPN.
आपके सर्वर पर एक DNS सेवा स्थापित है, और यह केवल वीपीएन के माध्यम से पहुंच योग्य है.
-
+ The DNS address is the same as the address of your server. You can configure DNS in the settings, under the connections tab.DNS पता आपके सर्वर के पते के समान है। आप कनेक्शन टैब के अंतर्गत सेटिंग्स में DNS को कॉन्फ़िगर कर सकते हैं.
-
+ Remove निकालना
-
+ Remove %1 from server?सर्वर से %1 हटाएँ?
-
+ Continueजारी रखना
-
+ Cancelरद्द करना
-
+ Cannot remove AmneziaDNS from running serverचल रहे सर्वर से एम्नेज़िया डीएनएस को नहीं हटाया जा सकता
@@ -835,157 +956,153 @@ Already installed containers were found on the server. All installed containers
PageServiceSftpSettings
-
+ Settings updated successfullyसेटिंग्स सफलतापूर्वक अपडेट हो गईं
-
+ SFTP settingsएसएफटीपी सेटिंग्स
-
+ Hostमेज़बान
-
-
-
-
+
+
+
+ Copiedकॉपी किया गया
-
+ Portपोर्ट
-
+ User nameउपयोगकर्ता नाम
-
+ Passwordपासवर्ड
-
+ Mount folder on deviceडिवाइस पर फ़ोल्डर माउंट करें
-
+ In order to mount remote SFTP folder as local drive, perform following steps: <br>दूरस्थ SFTP फ़ोल्डर को स्थानीय ड्राइव के रूप में माउंट करने के लिए, निम्नलिखित चरण निष्पादित करें: <br>
-
-
+
+ <br>1. Install the latest version of <br>1. का नवीनतम संस्करण स्थापित करें
-
-
+
+ <br>2. Install the latest version of <br>2. का नवीनतम संस्करण स्थापित करें
-
+ Detailed instructionsविस्तृत निर्देश
- Remove SFTP and all data stored there
- एसएफटीपी और वहां संग्रहीत सभी डेटा हटा दें
+ एसएफटीपी और वहां संग्रहीत सभी डेटा हटा दें
- Remove SFTP and all data stored there?
- एसएफटीपी और वहां संग्रहीत सभी डेटा हटाएं?
+ एसएफटीपी और वहां संग्रहीत सभी डेटा हटाएं?
- Continue
- जारी रखना
+ जारी रखना
- Cancel
- रद्द करना
+ रद्द करनाPageServiceSocksProxySettings
-
+ Settings updated successfullyसेटिंग्स सफलतापूर्वक अपडेट हो गईं
-
-
+
+ SOCKS5 settings
-
+ Hostमेज़बान
-
-
-
-
+
+
+
+ Copiedकॉपी किया गया
-
-
+
+ Port
-
+ User nameउपयोगकर्ता नाम
-
-
+
+ Passwordपासवर्ड
-
+ Username
-
-
+
+ Change connection settings
-
+ The port must be in the range of 1 to 65535
-
+ Password cannot be empty
-
+ Username cannot be empty
@@ -993,95 +1110,96 @@ Already installed containers were found on the server. All installed containers
PageServiceTorWebsiteSettings
-
+ Settings updated successfullyसेटिंग्स सफलतापूर्वक अपडेट हो गईं
-
+ Tor website settingsटोर वेबसाइट सेटिंग्स
-
+ Website addressवेबसाइट का पता
-
+ Copiedकॉपी किया गया
-
+ Use <a href="https://www.torproject.org/download/" style="color: #FBB26A;">Tor Browser</a> to open this URL.इस यूआरएल को खोलने के लिए <a href='https://www.torproject.org/download/' style='color: #FBB26A;'>Tor ब्राउज़र</a> का उपयोग करें।
-
+ After creating your onion site, it takes a few minutes for the Tor network to make it available for use.आपकी onionसाइट बनाने के बाद, टोर नेटवर्क को इसे उपयोग के लिए उपलब्ध कराने में कुछ मिनट लगते हैं.
-
+ When configuring WordPress set the this onion address as domain.वर्डप्रेस को कॉन्फ़िगर करते समय इस प्याज पते को डोमेन के रूप में सेट करें.
- Remove website
- वेबसाइट हटाएँ
+ वेबसाइट हटाएँ
- The site with all data will be removed from the tor network.
- सभी डेटा वाली साइट को टोर नेटवर्क से हटा दिया जाएगा.
+ सभी डेटा वाली साइट को टोर नेटवर्क से हटा दिया जाएगा.
- Continue
- जारी रखना
+ जारी रखना
- Cancel
- रद्द करना
+ रद्द करनाPageSettings
-
+ Settingsसमायोजन
-
+ Serversसर्वर
-
+ Connectionकनेक्शन
-
+ Applicationएप्लिकेशन
-
+ Backupबैकअप
-
+ About AmneziaVPNAmneziaVPN के बारे में
+ Dev console
+
+
+
+ Close applicationएप्लिकेशन बंद करो
@@ -1089,85 +1207,155 @@ Already installed containers were found on the server. All installed containers
PageSettingsAbout
-
+ Support AmneziaAmnezia का समर्थन करें
-
+ Amnezia is a free and open-source application. You can support the developers if you like it.एमनेज़िया एक निःशुल्क और ओपन-सोर्स एप्लिकेशन है। यदि आपको यह पसंद है तो आप डेवलपर्स का समर्थन कर सकते हैं।.
-
+ Contactsसंपर्क
-
+ Telegram groupटेलीग्राम समूह
-
+ To discuss featuresसुविधाओं पर चर्चा करना
-
+ https://t.me/amnezia_vpn_en
-
+ Mailमेल
-
+ For reviews and bug reportsसमीक्षाओं और बग रिपोर्टों के लिए
-
+ GitHubGitHub
-
+ https://github.com/amnezia-vpn/amnezia-clienthttps://github.com/amnezia-vpn/amnezia-client
-
+ Websiteवेबसाइट
-
- https://amnezia.org
-
-
-
-
+ Software version: %1सॉफ़्टवेयर संस्करण: %1
-
+ Check for updatesअद्यतन के लिए जाँच
-
+ Privacy Policyगोपनीयता नीति
+
+ PageSettingsApiServerInfo
+
+
+ For the region
+
+
+
+
+ Price
+
+
+
+
+ Work period
+
+
+
+
+ Speed
+
+
+
+
+ Support tag
+
+
+
+
+ Copied
+ कॉपी किया गया
+
+
+
+ Reload API config
+
+
+
+
+ Reload API config?
+
+
+
+
+
+ Continue
+ जारी रखना
+
+
+
+
+ Cancel
+ रद्द करना
+
+
+
+ Cannot reload API config during active connection
+
+
+
+
+ Remove from application
+
+
+
+
+ Remove from application?
+
+
+
+
+ Cannot remove server during active connection
+ सक्रिय कनेक्शन के दौरान सर्वर को हटाया नहीं जा सकता
+
+PageSettingsAppSplitTunneling
-
+ Cannot change split tunneling settings during active connectionसक्रिय कनेक्शन के दौरान स्प्लिट टनलिंग सेटिंग्स को नहीं बदला जा सकता
@@ -1180,52 +1368,52 @@ Already installed containers were found on the server. All installed containers
सूची के ऐप्स को वीपीएन के माध्यम से एक्सेस नहीं किया जाना चाहिए
-
+ Only the apps from the list should have access via VPN
-
+ Apps from the list should not have access via VPN
-
+ App split tunnelingऐप स्प्लिट टनलिंग
-
+ Modeतरीका
-
+ Remove निकालना
-
+ Continueजारी रखना
-
+ Cancelरद्द करना
-
+ application nameआवेदन का नाम
-
+ Open executable fileनिष्पादन योग्य फ़ाइल खोलें
-
+ Executable files (*.*)निष्पादनीय फाइल (*.*)
@@ -1233,102 +1421,102 @@ Already installed containers were found on the server. All installed containers
PageSettingsApplication
-
+ Applicationएप्लिकेशन
-
+ Allow application screenshotsएप्लिकेशन स्क्रीनशॉट की अनुमति दें
-
+ Enable notifications
-
+ Enable notifications to show the VPN state in the status bar
-
+ Auto startऑटो स्टार्ट
-
+ Launch the application every time the device is startsहर बार डिवाइस चालू होने पर एप्लिकेशन लॉन्च करें
-
+ Auto connectऑटो कनेक्ट
-
+ Connect to VPN on app startऐप शुरू होने पर वीपीएन से कनेक्ट करें
-
+ Start minimizedस्टार्ट को मिनिमाइज किया गया
-
+ Launch application minimizedलॉन्च एप्लिकेशन को न्यूनतम किया गया
-
+ Languageभाषा
-
+ Loggingलॉगिंग
-
+ Enabledसक्रिय किया
-
+ Disabledअक्षम
-
+ Reset settings and remove all data from the applicationसेटिंग्स रीसेट करें और एप्लिकेशन से सभी डेटा हटा दें
-
+ Reset settings and remove all data from the application?सेटिंग्स रीसेट करें और एप्लिकेशन से सभी डेटा हटा दें?
-
+ All settings will be reset to default. All installed AmneziaVPN services will still remain on the server.सभी सेटिंग्स डिफ़ॉल्ट पर रीसेट हो जाएंगी. सभी स्थापित AmneziaVPN सेवाएँ अभी भी सर्वर पर रहेंगी।.
-
+ Continueजारी रखना
-
+ Cancelरद्द करना
-
+ Cannot reset settings during active connectionसक्रिय कनेक्शन के दौरान सेटिंग्स रीसेट नहीं की जा सकतीं
@@ -1336,7 +1524,7 @@ Already installed containers were found on the server. All installed containers
PageSettingsBackup
-
+ Settings restored from backup fileबैकअप फ़ाइल से सेटिंग्स पुनर्स्थापित की गईं
@@ -1415,62 +1603,62 @@ Already installed containers were found on the server. All installed containers
PageSettingsConnection
-
+ Connectionकनेक्शन
-
+ When AmneziaDNS is not used or installedजब AmneziaDNS का उपयोग या स्थापित नहीं किया जाता है
-
+ Allows you to use the VPN only for certain Appsआपको केवल कुछ ऐप्स के लिए वीपीएन का उपयोग करने की अनुमति देता है
-
+ Use AmneziaDNSAmneziaडीएनएस का प्रयोग करें
-
+ If AmneziaDNS is installed on the serverयदि AmneziaDNS सर्वर पर स्थापित है
-
+ DNS serversDNS सर्वर
-
+ Site-based split tunnelingसाइट-आधारित विभाजित टनलिंग
-
+ Allows you to select which sites you want to access through the VPNआपको यह चुनने की अनुमति देता है कि आप वीपीएन के माध्यम से किन साइटों तक पहुंचना चाहते हैं
-
+ App-based split tunnelingऐप-आधारित स्प्लिट टनलिंग
-
+ KillSwitchस्विच बन्द कर दो
-
+ Disables your internet if your encrypted VPN connection drops out for any reason.यदि आपका एन्क्रिप्टेड वीपीएन कनेक्शन किसी भी कारण से बंद हो जाता है तो आपका इंटरनेट अक्षम कर देता है.
-
+ Cannot change killSwitch settings during active connectionसक्रिय कनेक्शन के दौरान किलस्विच सेटिंग्स को नहीं बदला जा सकता
@@ -1478,62 +1666,62 @@ Already installed containers were found on the server. All installed containers
PageSettingsDns
-
+ Default server does not support custom DNSडिफ़ॉल्ट सर्वर कस्टम डीएनएस का समर्थन नहीं करता है
-
+ DNS serversDNS सर्वर
-
+ If AmneziaDNS is not used or installedयदि AmneziaDNS का उपयोग या स्थापित नहीं किया गया है
-
+ Primary DNSप्राथमिक डीएनएस
-
+ Secondary DNSद्वितीयक डीएनएस
-
+ Restore defaultडिफ़ॉल्ट बहाल
-
+ Restore default DNS settings?डिफ़ॉल्ट DNS सेटिंग्स पुनर्स्थापित करें?
-
+ Continueजारी रखना
-
+ Cancelरद्द करना
-
+ Settings have been resetसेटिंग्स रीसेट कर दी गई हैं
-
+ Saveसहेजें
-
+ Settings savedसेटिंग्स को सहेजा गया
@@ -1541,72 +1729,72 @@ Already installed containers were found on the server. All installed containers
PageSettingsLogging
-
+ Logging is enabled. Note that logs will be automatically disabled after 14 days, and all log files will be deleted.लॉगिंग सक्षम है. ध्यान दें कि 14 दिनों के बाद लॉग स्वचालित रूप से अक्षम हो जाएंगे, और सभी लॉग फ़ाइलें हटा दी जाएंगी.
-
+ Loggingलॉगिंग
-
+ Enabling this function will save application's logs automatically. By default, logging functionality is disabled. Enable log saving in case of application malfunction.इस फ़ंक्शन को सक्षम करने से एप्लिकेशन के लॉग स्वचालित रूप से सहेजे जाएंगे, डिफ़ॉल्ट रूप से, लॉगिंग कार्यक्षमता अक्षम है। एप्लिकेशन की खराबी की स्थिति में लॉग सेविंग सक्षम करें.
-
+ Save logsलॉग सहेजें
-
+ Open folder with logsलॉग के साथ फ़ोल्डर खोलें
-
+ Saveसहेजें
-
+ Logs files (*.log)लॉग फ़ाइलें (*.log)
-
+ Logs file savedलॉग फ़ाइल सहेजी गई
-
+ Save logs to fileफ़ाइल में लॉग सहेजें
-
+ Clear logs?लॉग साफ़ करें?
-
+ Continueजारी रखना
-
+ Cancelरद्द करना
-
+ Logs have been cleaned upलॉग साफ़ कर दिए गए हैं
-
+ Clear logsलॉग साफ़ करें
@@ -1614,22 +1802,22 @@ Already installed containers were found on the server. All installed containers
PageSettingsServerData
-
+ All installed containers have been added to the applicationसभी स्थापित कंटेनरों को एप्लिकेशन में जोड़ दिया गया है
-
+ No new installed containers foundकोई नया स्थापित कंटेनर नहीं मिला
-
+ Do you want to reboot the server?क्या आप सर्वर को रीबूट करना चाहते हैं?
-
+ Do you want to clear server from Amnezia software?क्या आप एमनेज़िया सॉफ़्टवेयर से सर्वर साफ़ करना चाहते हैं?
@@ -1638,94 +1826,94 @@ Already installed containers were found on the server. All installed containers
-
-
-
-
-
- Continue
- जारी रखना
-
+ Continue
+ जारी रखना
+
+
+
+
+
+ Cancelरद्द करना
-
+ Check the server for previously installed Amnezia servicesपहले से स्थापित एमनेज़िया सेवाओं के लिए सर्वर की जाँच करें
-
+ Add them to the application if they were not displayedयदि वे प्रदर्शित नहीं थे तो उन्हें एप्लिकेशन में जोड़ें
-
+ Reboot serverसर्वर रीबूट करें
-
+ The reboot process may take approximately 30 seconds. Are you sure you wish to proceed?रीबूट प्रक्रिया में लगभग 30 सेकंड लग सकते हैं। आप निश्चित है आप आगे बढ़ना चाहते है?
-
+ Cannot reboot server during active connectionसक्रिय कनेक्शन के दौरान सर्वर को रीबूट नहीं किया जा सकता
-
+ Remove server from applicationएप्लिकेशन से सर्वर हटाएं
-
+ Do you want to remove the server from application?क्या आप एप्लिकेशन से सर्वर हटाना चाहते हैं?
-
+ Cannot remove server during active connectionसक्रिय कनेक्शन के दौरान सर्वर को हटाया नहीं जा सकता
-
+ All users whom you shared a connection with will no longer be able to connect to it.वे सभी उपयोगकर्ता जिनके साथ आपने कनेक्शन साझा किया था, वे अब इससे कनेक्ट नहीं हो पाएंगे.
-
+ Cannot clear server from Amnezia software during active connectionसक्रिय कनेक्शन के दौरान एमनेज़िया सॉफ़्टवेयर से सर्वर साफ़ नहीं किया जा सकता
-
+ Reset API configएपीआई कॉन्फिगरेशन रीसेट करें
-
+ Do you want to reset API config?क्या आप एपीआई कॉन्फिगरेशन रीसेट करना चाहते हैं?
-
+ Cannot reset API config during active connectionसक्रिय कनेक्शन के दौरान एपीआई कॉन्फिगरेशन को रीसेट नहीं किया जा सकता
-
+ All installed AmneziaVPN services will still remain on the server.सभी स्थापित AmneziaVPN सेवाएँ अभी भी सर्वर पर रहेंगी.
-
+ Clear server from Amnezia softwareएमनेज़िया सॉफ़्टवेयर से सर्वर साफ़ करें
@@ -1733,27 +1921,27 @@ Already installed containers were found on the server. All installed containers
PageSettingsServerInfo
-