From 8164026891c8c916c5a542d5c4d58b0f38fa3079 Mon Sep 17 00:00:00 2001 From: "vladimir.kuznetsov" Date: Thu, 26 Oct 2023 23:34:39 +0500 Subject: [PATCH 01/15] fixed server config update, after container config change --- client/amnezia_application.cpp | 2 ++ client/ui/models/containers_model.cpp | 12 ++---------- client/ui/models/containers_model.h | 1 + client/ui/models/servers_model.cpp | 6 ++++++ client/ui/models/servers_model.h | 2 ++ 5 files changed, 13 insertions(+), 10 deletions(-) diff --git a/client/amnezia_application.cpp b/client/amnezia_application.cpp index 3e227863..25a131f8 100644 --- a/client/amnezia_application.cpp +++ b/client/amnezia_application.cpp @@ -288,6 +288,8 @@ void AmneziaApplication::initModels() &ContainersModel::setCurrentlyProcessedServerIndex); connect(m_serversModel.get(), &ServersModel::defaultServerIndexChanged, m_containersModel.get(), &ContainersModel::setCurrentlyProcessedServerIndex); + connect(m_containersModel.get(), &ContainersModel::containersModelUpdated, m_serversModel.get(), + &ServersModel::updateContainersConfig); m_languageModel.reset(new LanguageModel(m_settings, this)); m_engine->rootContext()->setContextProperty("LanguageModel", m_languageModel.get()); diff --git a/client/ui/models/containers_model.cpp b/client/ui/models/containers_model.cpp index 6a4c0e63..3fff22d4 100644 --- a/client/ui/models/containers_model.cpp +++ b/client/ui/models/containers_model.cpp @@ -22,10 +22,6 @@ bool ContainersModel::setData(const QModelIndex &index, const QVariant &value, i DockerContainer container = ContainerProps::allContainers().at(index.row()); switch (role) { - case NameRole: - // return ContainerProps::containerHumanNames().value(container); - case DescriptionRole: - // return ContainerProps::containerDescriptions().value(container); case ConfigRole: { m_settings->setContainerConfig(m_currentlyProcessedServerIndex, container, value.toJsonObject()); m_containers = m_settings->containers(m_currentlyProcessedServerIndex); @@ -35,19 +31,15 @@ bool ContainersModel::setData(const QModelIndex &index, const QVariant &value, i break; } } - case ServiceTypeRole: - // return ContainerProps::containerService(container); - case DockerContainerRole: - // return container; - case IsInstalledRole: - // return m_settings->containers(m_currentlyProcessedServerIndex).contains(container); case IsDefaultRole: { //todo remove m_settings->setDefaultContainer(m_currentlyProcessedServerIndex, container); m_defaultContainerIndex = container; emit defaultContainerChanged(); } + default: break; } + emit containersModelUpdated(); emit dataChanged(index, index); return true; } diff --git a/client/ui/models/containers_model.h b/client/ui/models/containers_model.h index 997b21e3..8f087d87 100644 --- a/client/ui/models/containers_model.h +++ b/client/ui/models/containers_model.h @@ -73,6 +73,7 @@ protected: signals: void defaultContainerChanged(); + void containersModelUpdated(); private: QMap m_containers; diff --git a/client/ui/models/servers_model.cpp b/client/ui/models/servers_model.cpp index a2a28630..f3b2337f 100644 --- a/client/ui/models/servers_model.cpp +++ b/client/ui/models/servers_model.cpp @@ -193,6 +193,12 @@ bool ServersModel::isDefaultServerConfigContainsAmneziaDns() return primaryDns == protocols::dns::amneziaDnsIp; } +void ServersModel::updateContainersConfig() +{ + auto server = m_settings->server(m_currentlyProcessedServerIndex); + m_servers.replace(m_currentlyProcessedServerIndex, server); +} + QHash ServersModel::roleNames() const { QHash roles; diff --git a/client/ui/models/servers_model.h b/client/ui/models/servers_model.h index ad1d5a83..97d8015f 100644 --- a/client/ui/models/servers_model.h +++ b/client/ui/models/servers_model.h @@ -59,6 +59,8 @@ public slots: bool isDefaultServerConfigContainsAmneziaDns(); + void updateContainersConfig(); + protected: QHash roleNames() const override; From 4848091203cc865203d7cb7831264a8dc70a279d Mon Sep 17 00:00:00 2001 From: useribs Date: Mon, 30 Oct 2023 20:09:13 +0300 Subject: [PATCH 02/15] Update servercontroller.cpp, replace 2 calls (shred ; rm) with one (shred -u) --- client/core/servercontroller.cpp | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/client/core/servercontroller.cpp b/client/core/servercontroller.cpp index da76e1ff..398b46b3 100644 --- a/client/core/servercontroller.cpp +++ b/client/core/servercontroller.cpp @@ -167,11 +167,8 @@ ErrorCode ServerController::uploadTextFileToContainer(DockerContainer container, return ErrorCode::ServerContainerMissingError; } - runScript(credentials, - replaceVars(QString("sudo shred %1").arg(tmpFileName), genVarsForScript(credentials, container))); - - runScript(credentials, replaceVars(QString("sudo rm %1").arg(tmpFileName), genVarsForScript(credentials, container))); - + runScript(credentials, + replaceVars(QString("sudo shred -u %1").arg(tmpFileName), genVarsForScript(credentials, container))); return e; } From 9cfcb714aebfd7c31a105e647621479dd1068946 Mon Sep 17 00:00:00 2001 From: "vladimir.kuznetsov" Date: Mon, 30 Oct 2023 14:20:21 +0500 Subject: [PATCH 03/15] added native config generation for ss and cloak --- client/ui/controllers/exportController.cpp | 80 +++++++++++++++++++ client/ui/controllers/exportController.h | 2 + .../qml/Pages2/PageSetupWizardCredentials.qml | 10 ++- client/ui/qml/Pages2/PageShare.qml | 43 ++++++++-- 4 files changed, 127 insertions(+), 8 deletions(-) diff --git a/client/ui/controllers/exportController.cpp b/client/ui/controllers/exportController.cpp index ef5cc4e3..06bddb8a 100644 --- a/client/ui/controllers/exportController.cpp +++ b/client/ui/controllers/exportController.cpp @@ -10,6 +10,8 @@ #include "configurators/openvpn_configurator.h" #include "configurators/wireguard_configurator.h" +#include "configurators/shadowsocks_configurator.h" +#include "configurators/cloak_configurator.h" #include "core/errorstrings.h" #include "systemController.h" #ifdef Q_OS_ANDROID @@ -155,6 +157,8 @@ void ExportController::generateOpenVpnConfig() m_config.append(line + "\n"); } + m_qrCodes = generateQrCodeImageSeries(m_config.toUtf8()); + emit exportConfigChanged(); } @@ -187,6 +191,82 @@ void ExportController::generateWireGuardConfig() m_config.append(line + "\n"); } + m_qrCodes = generateQrCodeImageSeries(m_config.toUtf8()); + + emit exportConfigChanged(); +} + +void ExportController::generateShadowSocksConfig() +{ + clearPreviousConfig(); + + int serverIndex = m_serversModel->getCurrentlyProcessedServerIndex(); + ServerCredentials credentials = + qvariant_cast(m_serversModel->data(serverIndex, ServersModel::Roles::CredentialsRole)); + + DockerContainer container = static_cast(m_containersModel->getCurrentlyProcessedContainerIndex()); + QModelIndex containerModelIndex = m_containersModel->index(container); + QJsonObject containerConfig = + qvariant_cast(m_containersModel->data(containerModelIndex, ContainersModel::Roles::ConfigRole)); + containerConfig.insert(config_key::container, ContainerProps::containerToString(container)); + + ErrorCode errorCode = ErrorCode::NoError; + QString config = m_configurator->shadowSocksConfigurator->genShadowSocksConfig(credentials, container, containerConfig, &errorCode); + + if (errorCode) { + emit exportErrorOccurred(errorString(errorCode)); + return; + } + config = m_configurator->processConfigWithExportSettings(serverIndex, container, Proto::ShadowSocks, config); + QJsonObject configJson = QJsonDocument::fromJson(config.toUtf8()).object(); + + m_config = QString("%1:%2@%3:%4") + .arg(configJson.value("method").toString(), + configJson.value("password").toString(), + configJson.value("server").toString(), + configJson.value("server_port").toString()); + + m_config = "ss://" + m_config.toUtf8().toBase64(); + + m_qrCodes = generateQrCodeImageSeries(m_config.toUtf8()); + + emit exportConfigChanged(); +} + +void ExportController::generateCloakConfig() +{ + clearPreviousConfig(); + + int serverIndex = m_serversModel->getCurrentlyProcessedServerIndex(); + ServerCredentials credentials = + qvariant_cast(m_serversModel->data(serverIndex, ServersModel::Roles::CredentialsRole)); + + DockerContainer container = static_cast(m_containersModel->getCurrentlyProcessedContainerIndex()); + QModelIndex containerModelIndex = m_containersModel->index(container); + QJsonObject containerConfig = + qvariant_cast(m_containersModel->data(containerModelIndex, ContainersModel::Roles::ConfigRole)); + containerConfig.insert(config_key::container, ContainerProps::containerToString(container)); + + ErrorCode errorCode = ErrorCode::NoError; + QString config = m_configurator->cloakConfigurator->genCloakConfig(credentials, container, containerConfig, &errorCode); + + if (errorCode) { + emit exportErrorOccurred(errorString(errorCode)); + return; + } + config = m_configurator->processConfigWithExportSettings(serverIndex, container, Proto::Cloak, config); + QJsonObject configJson = QJsonDocument::fromJson(config.toUtf8()).object(); + + configJson.remove(config_key::transport_proto); + configJson.insert("ProxyMethod", "shadowsocks"); + + QStringList lines = QString(QJsonDocument(configJson).toJson()).replace("\r", "").split("\n"); + for (const QString &line : lines) { + m_config.append(line + "\n"); + } + + m_qrCodes = generateQrCodeImageSeries(m_config.toUtf8()); + emit exportConfigChanged(); } diff --git a/client/ui/controllers/exportController.h b/client/ui/controllers/exportController.h index 24eaa5c8..ee94e741 100644 --- a/client/ui/controllers/exportController.h +++ b/client/ui/controllers/exportController.h @@ -31,6 +31,8 @@ public slots: void generateConnectionConfig(); void generateOpenVpnConfig(); void generateWireGuardConfig(); + void generateShadowSocksConfig(); + void generateCloakConfig(); QString getConfig(); QList getQrCodes(); diff --git a/client/ui/qml/Pages2/PageSetupWizardCredentials.qml b/client/ui/qml/Pages2/PageSetupWizardCredentials.qml index 5c32b0c5..3eadb647 100644 --- a/client/ui/qml/Pages2/PageSetupWizardCredentials.qml +++ b/client/ui/qml/Pages2/PageSetupWizardCredentials.qml @@ -54,7 +54,7 @@ PageType { regularExpression: InstallController.ipAddressPortRegExp() } - onTextFieldTextChanged: { + onFocusChanged: { textField.text = textField.text.replace(/^\s+|\s+$/g, ''); } } @@ -81,6 +81,10 @@ PageType { clickedFunc: function() { hidePassword = !hidePassword } + + onFocusChanged: { + textField.text = textField.text.replace(/^\s+|\s+$/g, ''); + } } BasicButtonType { @@ -90,6 +94,7 @@ PageType { text: qsTr("Continue") onClicked: function() { + forceActiveFocus() if (!isCredentialsFilled()) { return } @@ -112,8 +117,7 @@ PageType { Layout.fillWidth: true Layout.topMargin: 12 - text: qsTr("All data you enter will remain strictly confidential -and will not be shared or disclosed to the Amnezia or any third parties") + text: qsTr("All data you enter will remain strictly confidential and will not be shared or disclosed to the Amnezia or any third parties") } } } diff --git a/client/ui/qml/Pages2/PageShare.qml b/client/ui/qml/Pages2/PageShare.qml index ced7a5ff..577a9b3a 100644 --- a/client/ui/qml/Pages2/PageShare.qml +++ b/client/ui/qml/Pages2/PageShare.qml @@ -20,7 +20,9 @@ PageType { AmneziaConnection, AmneziaFullAccess, OpenVpn, - WireGuard + WireGuard, + ShadowSocks, + Cloak } Connections { @@ -44,18 +46,32 @@ PageType { break; } case PageShare.ConfigType.OpenVpn: { - ExportController.generateOpenVpnConfig(); + ExportController.generateOpenVpnConfig() shareConnectionDrawer.configCaption = qsTr("Save OpenVPN config") shareConnectionDrawer.configExtension = ".ovpn" shareConnectionDrawer.configFileName = "amnezia_for_openvpn" - break; + break } case PageShare.ConfigType.WireGuard: { - ExportController.generateWireGuardConfig(); + ExportController.generateWireGuardConfig() shareConnectionDrawer.configCaption = qsTr("Save WireGuard config") shareConnectionDrawer.configExtension = ".conf" shareConnectionDrawer.configFileName = "amnezia_for_wireguard" - break; + break + } + case PageShare.ConfigType.ShadowSocks: { + ExportController.generateShadowSocksConfig() + shareConnectionDrawer.configCaption = qsTr("Save ShadowSocks config") + shareConnectionDrawer.configExtension = ".json" + shareConnectionDrawer.configFileName = "amnezia_for_shadowsocks" + break + } + case PageShare.ConfigType.Cloak: { + ExportController.generateCloakConfig() + shareConnectionDrawer.configCaption = qsTr("Save Cloak config") + shareConnectionDrawer.configExtension = ".json" + shareConnectionDrawer.configFileName = "amnezia_for_cloak" + break } } @@ -96,6 +112,16 @@ PageType { property string name: qsTr("WireGuard native format") property var type: PageShare.ConfigType.WireGuard } + QtObject { + id: shadowSocksConnectionFormat + property string name: qsTr("ShadowSocks native format") + property var type: PageShare.ConfigType.ShadowSocks + } + QtObject { + id: cloakConnectionFormat + property string name: qsTr("Cloak native format") + property var type: PageShare.ConfigType.Cloak + } FlickableType { anchors.top: parent.top @@ -322,6 +348,13 @@ PageType { root.connectionTypesModel.push(openVpnConnectionFormat) } else if (index === ContainerProps.containerFromString("amnezia-wireguard")) { root.connectionTypesModel.push(wireGuardConnectionFormat) + } else if (index === ContainerProps.containerFromString("amnezia-shadowsocks")) { + root.connectionTypesModel.push(openVpnConnectionFormat) + root.connectionTypesModel.push(shadowSocksConnectionFormat) + } else if (index === ContainerProps.containerFromString("amnezia-openvpn-cloak")) { + root.connectionTypesModel.push(openVpnConnectionFormat) + root.connectionTypesModel.push(shadowSocksConnectionFormat) + root.connectionTypesModel.push(cloakConnectionFormat) } } } From 071738116ed1d0ca76be9d94159e8b4c5339c4ff Mon Sep 17 00:00:00 2001 From: Mykola Baibuz Date: Fri, 3 Nov 2023 17:29:40 -0400 Subject: [PATCH 04/15] Update Windows OpenVPN binary This binary builded with ENABLE_DEBUG flag. This flag needed for ROUTE_GATEWAY varible output in log. --- client/3rd-prebuilt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/3rd-prebuilt b/client/3rd-prebuilt index ac32d335..fcf3022a 160000 --- a/client/3rd-prebuilt +++ b/client/3rd-prebuilt @@ -1 +1 @@ -Subproject commit ac32d33555bd62f0b0af314b1e5119d6d78a1a4e +Subproject commit fcf3022a2724402f68cc11bcbed9b43ea9ffcc07 From 5e9f688000cfdea5ba5afd212343d583a7616588 Mon Sep 17 00:00:00 2001 From: Mykola Baibuz Date: Sat, 4 Nov 2023 15:28:59 -0400 Subject: [PATCH 05/15] Use DNS over VPN for ForwardSites mode split tunnel This feature was in previous version of Split Tunnel --- client/vpnconnection.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/client/vpnconnection.cpp b/client/vpnconnection.cpp index dea40f24..2505a9ea 100644 --- a/client/vpnconnection.cpp +++ b/client/vpnconnection.cpp @@ -377,7 +377,8 @@ void VpnConnection::appendSplitTunnelingConfig() // Allow traffic to Amezia DNS if (routeMode == Settings::VpnOnlyForwardSites){ - sitesJsonArray.append(amnezia::protocols::dns::amneziaDnsIp); + sitesJsonArray.append(m_vpnConfiguration.value(config_key::dns1).toString()); + sitesJsonArray.append(m_vpnConfiguration.value(config_key::dns2).toString()); } m_vpnConfiguration.insert(config_key::splitTunnelType, routeMode); From 72de38b4fb5ec462ed0c05c37d27071b4072b650 Mon Sep 17 00:00:00 2001 From: tiaga Date: Fri, 10 Nov 2023 23:18:47 +0700 Subject: [PATCH 06/15] Upload new versions to R2 A new GitHub Actions workflow for a tagged commit which uploads installers for a desktop version to Cloudflare R2. --- .github/workflows/tag-upload.yml | 64 ++++++++++++++++++++++++++++++++ 1 file changed, 64 insertions(+) create mode 100644 .github/workflows/tag-upload.yml diff --git a/.github/workflows/tag-upload.yml b/.github/workflows/tag-upload.yml new file mode 100644 index 00000000..22629ed3 --- /dev/null +++ b/.github/workflows/tag-upload.yml @@ -0,0 +1,64 @@ +name: 'Upload a new version' + +on: + push: + tags: + - '[0-9]+.[0-9]+.[0-9]+.[0-9]+' + +jobs: + upload: + runs-on: ubuntu-latest + name: upload + steps: + - name: Checkout CMakeLists.txt + uses: actions/checkout@v4 + with: + ref: ${{ github.ref_name }} + sparse-checkout: | + CMakeLists.txt + sparse-checkout-cone-mode: false + + - name: Verify git tag + run: | + GIT_TAG=${{ github.ref_name }} + CMAKE_TAG=$(grep 'project.*VERSION' CMakeLists.txt | sed -E 's/.* ([0-9]+.[0-9]+.[0-9]+.[0-9]+)$/\1/') + + if [[ "$GIT_TAG" == "$CMAKE_TAG" ]]; then + echo "Git tag ($GIT_TAG) and version in CMakeLists.txt ($CMAKE_TAG) are the same. Continuing..." + else + echo "Git tag ($GIT_TAG) and version in CMakeLists.txt ($CMAKE_TAG) are not the same! Cancelling..." + exit 1 + fi + + - name: Download artifacts from the "${{ github.ref_name }}" tag + uses: robinraju/release-downloader@v1.8 + with: + tag: ${{ github.ref_name }} + fileName: "AmneziaVPN_(Linux_|)${{ github.ref_name }}*" + out-file-path: ${{ github.ref_name }} + + - name: Upload beta version + uses: jakejarvis/s3-sync-action@master + if: contains(github.event.base_ref, 'dev') + with: + args: --include "AmneziaVPN*" --delete + env: + AWS_S3_BUCKET: updates + AWS_ACCESS_KEY_ID: ${{ secrets.CF_R2_ACCESS_KEY_ID }} + AWS_SECRET_ACCESS_KEY: ${{ secrets.CF_R2_SECRET_ACCESS_KEY }} + AWS_S3_ENDPOINT: https://${{ vars.CF_ACCOUNT_ID }}.r2.cloudflarestorage.com + SOURCE_DIR: ${{ github.ref_name }} + DEST_DIR: beta/${{ github.ref_name }} + + - name: Upload stable version + uses: jakejarvis/s3-sync-action@master + if: contains(github.event.base_ref, 'master') + with: + args: --include "AmneziaVPN*" --delete + env: + AWS_S3_BUCKET: updates + AWS_ACCESS_KEY_ID: ${{ secrets.CF_R2_ACCESS_KEY_ID }} + AWS_SECRET_ACCESS_KEY: ${{ secrets.CF_R2_SECRET_ACCESS_KEY }} + AWS_S3_ENDPOINT: https://${{ vars.CF_ACCOUNT_ID }}.r2.cloudflarestorage.com + SOURCE_DIR: ${{ github.ref_name }} + DEST_DIR: stable/${{ github.ref_name }} From 362a82f94496075b2187cf1bfbe0d2acf79894c0 Mon Sep 17 00:00:00 2001 From: tiaga Date: Tue, 14 Nov 2023 16:57:04 +0700 Subject: [PATCH 07/15] Improve logic of install_docker.sh - check packages update only when it's required - avoid `dnf/yum update` for RHEL-based systems --- client/server_scripts/install_docker.sh | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/client/server_scripts/install_docker.sh b/client/server_scripts/install_docker.sh index 58f92540..e6708ddf 100644 --- a/client/server_scripts/install_docker.sh +++ b/client/server_scripts/install_docker.sh @@ -1,19 +1,19 @@ -if which apt-get > /dev/null 2>&1; then pm=$(which apt-get); docker_pkg="docker.io"; dist="debian";\ -elif which dnf > /dev/null 2>&1; then pm=$(which dnf); docker_pkg="docker"; dist="fedora";\ -elif which yum > /dev/null 2>&1; then pm=$(which yum); docker_pkg="docker"; dist="centos";\ +if which apt-get > /dev/null 2>&1; then pm=$(which apt-get); silent_inst="-yq install"; check_pkgs="-yq update"; docker_pkg="docker.io"; dist="debian";\ +elif which dnf > /dev/null 2>&1; then pm=$(which dnf); silent_inst="-yq install"; check_pkgs="-yq check-update"; docker_pkg="docker"; dist="fedora";\ +elif which yum > /dev/null 2>&1; then pm=$(which yum); silent_inst="-y -q install"; check_pkgs="-y -q check-update"; docker_pkg="docker"; dist="centos";\ else echo "Packet manager not found"; exit 1; fi;\ -echo "Dist: $dist, Packet manager: $pm, Docker pkg: $docker_pkg";\ +echo "Dist: $dist, Packet manager: $pm, Install command: $silent_inst, Check pkgs command: $check_pkgs, Docker pkg: $docker_pkg";\ if [ "$dist" = "debian" ]; then export DEBIAN_FRONTEND=noninteractive; fi;\ -if ! command -v sudo > /dev/null 2>&1; then $pm update -yq; $pm install -yq sudo; fi;\ -if ! command -v fuser > /dev/null 2>&1; then sudo $pm install -yq psmisc; fi;\ -if ! command -v lsof > /dev/null 2>&1; then sudo $pm install -yq lsof; fi;\ -if ! command -v docker > /dev/null 2>&1; then sudo $pm update -yq; sudo $pm install -yq $docker_pkg;\ +if ! command -v sudo > /dev/null 2>&1; then $pm $check_pkgs; $pm $silent_inst sudo; fi;\ +if ! command -v fuser > /dev/null 2>&1; then sudo $pm $check_pkgs; sudo $pm $silent_inst psmisc; fi;\ +if ! command -v lsof > /dev/null 2>&1; then sudo $pm $check_pkgs; sudo $pm $silent_inst lsof; fi;\ +if ! command -v docker > /dev/null 2>&1; then sudo $pm $check_pkgs; sudo $pm $silent_inst $docker_pkg;\ if [ "$dist" = "fedora" ] || [ "$dist" = "centos" ] || [ "$dist" = "debian" ]; then sudo systemctl enable docker && sudo systemctl start docker; fi;\ fi;\ if [ "$dist" = "debian" ]; then \ docker_service=$(systemctl list-units --full --all | grep docker.service | grep -v inactive | grep -v dead | grep -v failed);\ - if [ -z "$docker_service" ]; then sudo $pm update -yq; sudo $pm install -yq curl $docker_pkg; fi;\ + if [ -z "$docker_service" ]; then sudo $pm $check_pkgs; sudo $pm $silent_inst curl $docker_pkg; fi;\ sleep 3 && sudo systemctl start docker && sleep 3;\ fi;\ -if ! command -v sudo > /dev/null 2>&1; then echo "Failed to install Docker";exit 1;fi;\ +if ! command -v sudo > /dev/null 2>&1; then echo "Failed to install Docker"; exit 1; fi;\ docker --version From b0004fd9dc9bc1afc465af84fcea010e15cc4741 Mon Sep 17 00:00:00 2001 From: pokamest Date: Tue, 14 Nov 2023 12:50:52 +0000 Subject: [PATCH 08/15] Version bump --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index abb382cb..2d38a422 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.1.0.0 +project(${PROJECT} VERSION 4.1.0.1 DESCRIPTION "AmneziaVPN" HOMEPAGE_URL "https://amnezia.org/" ) From abb2cae1f8a6c49bf56da86e7ea29ca50f6637ef Mon Sep 17 00:00:00 2001 From: tiaga Date: Tue, 14 Nov 2023 23:39:15 +0700 Subject: [PATCH 09/15] Change Qt mirror for builds Use UC Berkeley mirror for installing Qt during a build. In addition, don't trigger builds on a tag push. --- .github/workflows/deploy.yml | 27 ++++++++++++++++----------- 1 file changed, 16 insertions(+), 11 deletions(-) diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml index 54631669..719fcd72 100644 --- a/.github/workflows/deploy.yml +++ b/.github/workflows/deploy.yml @@ -1,7 +1,12 @@ name: 'Deploy workflow' +on: + push: + branches: + - '**' -on: [push] +env: + QT_MIRROR: https://mirrors.ocf.berkeley.edu/qt/ # https://download.qt.io/static/mirrorlist/ jobs: Build-Linux-Ubuntu: @@ -25,7 +30,7 @@ jobs: setup-python: 'true' tools: 'tools_ifw' set-env: 'true' - extra: '--external 7z' + extra: '--external 7z --base ${{ env.QT_MIRROR }}' - name: 'Get sources' uses: actions/checkout@v3 @@ -89,7 +94,7 @@ jobs: setup-python: 'true' tools: 'tools_ifw' set-env: 'true' - extra: '--external 7z' + extra: '--external 7z --base ${{ env.QT_MIRROR }}' - name: 'Setup mvsc' uses: ilammy/msvc-dev-cmd@v1 @@ -119,15 +124,14 @@ jobs: # ------------------------------------------------------ - Build-IOS: - name: 'Build-IOS' + Build-iOS: + name: 'Build-iOS' runs-on: macos-12 env: QT_VERSION: 6.5.2 steps: - # Just select XCode - name: 'Setup xcode' uses: maxim-lobanov/setup-xcode@v1 with: @@ -143,6 +147,7 @@ jobs: arch: 'clang_64' dir: ${{ runner.temp }} set-env: 'true' + extra: '--base ${{ env.QT_MIRROR }}' - name: 'Install iOS Qt' uses: jurplel/install-qt-action@v3 @@ -154,7 +159,7 @@ jobs: dir: ${{ runner.temp }} setup-python: 'true' set-env: 'true' - extra: '--external 7z' + extra: '--external 7z --base ${{ env.QT_MIRROR }}' - name: 'Install go' uses: actions/setup-go@v3 @@ -174,7 +179,7 @@ jobs: - name: 'Setup ccache' uses: hendrikmuhs/ccache-action@v1.2 - - name: Install dependencies + - name: 'Install dependencies' run: pip install jsonschema jinja2 - name: 'Build project' @@ -232,7 +237,7 @@ jobs: setup-python: 'true' tools: 'tools_ifw' set-env: 'true' - extra: '--external 7z' + extra: '--external 7z --base ${{ env.QT_MIRROR }}' - name: 'Get sources' uses: actions/checkout@v3 @@ -296,7 +301,7 @@ jobs: dir: ${{ runner.temp }} setup-python: 'true' set-env: 'true' - extra: '--external 7z' + extra: '--external 7z --base ${{ env.QT_MIRROR }}' - name: 'Install android Qt' uses: jurplel/install-qt-action@v3 @@ -309,7 +314,7 @@ jobs: dir: ${{ runner.temp }} setup-python: 'true' set-env: 'true' - extra: '--external 7z' + extra: '--external 7z --base ${{ env.QT_MIRROR }}' - name: 'Grant execute permission for qt-cmake' shell: bash From e8a2e54d059d02b6487eae4e9cb9d355464dc1bd Mon Sep 17 00:00:00 2001 From: pokamest Date: Wed, 15 Nov 2023 12:51:39 +0000 Subject: [PATCH 10/15] Typo fix --- client/core/defs.h | 2 +- client/core/errorstrings.cpp | 2 +- client/core/sshclient.cpp | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/client/core/defs.h b/client/core/defs.h index 35515103..9547dd92 100644 --- a/client/core/defs.h +++ b/client/core/defs.h @@ -36,7 +36,7 @@ enum ErrorCode ServerPacketManagerError, // Ssh connection errors - SshRequsetDeniedError, SshInterruptedError, SshInternalError, + SshRequestDeniedError, SshInterruptedError, SshInternalError, SshPrivateKeyError, SshPrivateKeyFormatError, SshTimeoutError, // Ssh sftp errors diff --git a/client/core/errorstrings.cpp b/client/core/errorstrings.cpp index cd66186d..b17a5a9e 100644 --- a/client/core/errorstrings.cpp +++ b/client/core/errorstrings.cpp @@ -19,7 +19,7 @@ QString errorString(ErrorCode code){ case(ServerUserNotInSudo): return QObject::tr("The user does not have permission to use sudo"); // Libssh errors - case(SshRequsetDeniedError): return QObject::tr("Ssh request was denied"); + case(SshRequestDeniedError): return QObject::tr("Ssh request was denied"); case(SshInterruptedError): return QObject::tr("Ssh request was interrupted"); case(SshInternalError): return QObject::tr("Ssh internal error"); case(SshPrivateKeyError): return QObject::tr("Invalid private key or invalid passphrase entered"); diff --git a/client/core/sshclient.cpp b/client/core/sshclient.cpp index 797bdc6f..0ac95662 100644 --- a/client/core/sshclient.cpp +++ b/client/core/sshclient.cpp @@ -333,7 +333,7 @@ namespace libssh { switch (errorCode) { case(SSH_NO_ERROR): return ErrorCode::NoError; - case(SSH_REQUEST_DENIED): return ErrorCode::SshRequsetDeniedError; + case(SSH_REQUEST_DENIED): return ErrorCode::SshRequestDeniedError; case(SSH_EINTR): return ErrorCode::SshInterruptedError; case(SSH_FATAL): return ErrorCode::SshInternalError; default: return ErrorCode::SshInternalError; From d38c7ce6a5b9c727a67e7129ea64d90e422a09de Mon Sep 17 00:00:00 2001 From: pokamest Date: Wed, 22 Nov 2023 13:57:05 +0000 Subject: [PATCH 11/15] Error codes cleanup --- client/core/defs.h | 2 -- client/core/errorstrings.cpp | 1 - 2 files changed, 3 deletions(-) diff --git a/client/core/defs.h b/client/core/defs.h index 9547dd92..7de55286 100644 --- a/client/core/defs.h +++ b/client/core/defs.h @@ -47,7 +47,6 @@ enum ErrorCode SshSftpNoMediaError, // Local errors - FailedToSaveConfigData, OpenVpnConfigMissing, OpenVpnManagementServerError, ConfigMissing, @@ -67,7 +66,6 @@ enum ErrorCode // 3rd party utils errors OpenSslFailed, - OpenVpnExecutableCrashed, ShadowSocksExecutableCrashed, CloakExecutableCrashed, diff --git a/client/core/errorstrings.cpp b/client/core/errorstrings.cpp index b17a5a9e..2a34576d 100644 --- a/client/core/errorstrings.cpp +++ b/client/core/errorstrings.cpp @@ -42,7 +42,6 @@ QString errorString(ErrorCode code){ case(SshSftpNoMediaError): return QObject::tr("Sftp error: No media was in remote drive"); // Local errors - case (FailedToSaveConfigData): return QObject::tr("Failed to save config to disk"); case (OpenVpnConfigMissing): return QObject::tr("OpenVPN config missing"); case (OpenVpnManagementServerError): return QObject::tr("OpenVPN management server error"); From 1bf808c9ee546135ffdb13d0d47f7db033c50de0 Mon Sep 17 00:00:00 2001 From: "vladimir.kuznetsov" Date: Sat, 25 Nov 2023 13:02:02 +0700 Subject: [PATCH 12/15] fixed qr code generation for native configs --- client/ui/controllers/exportController.cpp | 46 +++++++++++-------- client/ui/controllers/exportController.h | 3 ++ .../qml/Components/ShareConnectionDrawer.qml | 31 ++++++++++++- 3 files changed, 61 insertions(+), 19 deletions(-) diff --git a/client/ui/controllers/exportController.cpp b/client/ui/controllers/exportController.cpp index 06bddb8a..048eadb0 100644 --- a/client/ui/controllers/exportController.cpp +++ b/client/ui/controllers/exportController.cpp @@ -8,10 +8,10 @@ #include #include -#include "configurators/openvpn_configurator.h" -#include "configurators/wireguard_configurator.h" -#include "configurators/shadowsocks_configurator.h" #include "configurators/cloak_configurator.h" +#include "configurators/openvpn_configurator.h" +#include "configurators/shadowsocks_configurator.h" +#include "configurators/wireguard_configurator.h" #include "core/errorstrings.h" #include "systemController.h" #ifdef Q_OS_ANDROID @@ -157,8 +157,6 @@ void ExportController::generateOpenVpnConfig() m_config.append(line + "\n"); } - m_qrCodes = generateQrCodeImageSeries(m_config.toUtf8()); - emit exportConfigChanged(); } @@ -191,7 +189,8 @@ void ExportController::generateWireGuardConfig() m_config.append(line + "\n"); } - m_qrCodes = generateQrCodeImageSeries(m_config.toUtf8()); + qrcodegen::QrCode qr = qrcodegen::QrCode::encodeText(m_config.toUtf8(), qrcodegen::QrCode::Ecc::LOW); + m_qrCodes << svgToBase64(QString::fromStdString(toSvgString(qr, 1))); emit exportConfigChanged(); } @@ -211,7 +210,8 @@ void ExportController::generateShadowSocksConfig() containerConfig.insert(config_key::container, ContainerProps::containerToString(container)); ErrorCode errorCode = ErrorCode::NoError; - QString config = m_configurator->shadowSocksConfigurator->genShadowSocksConfig(credentials, container, containerConfig, &errorCode); + QString config = m_configurator->shadowSocksConfigurator->genShadowSocksConfig(credentials, container, + containerConfig, &errorCode); if (errorCode) { emit exportErrorOccurred(errorString(errorCode)); @@ -220,15 +220,20 @@ void ExportController::generateShadowSocksConfig() config = m_configurator->processConfigWithExportSettings(serverIndex, container, Proto::ShadowSocks, config); QJsonObject configJson = QJsonDocument::fromJson(config.toUtf8()).object(); - m_config = QString("%1:%2@%3:%4") - .arg(configJson.value("method").toString(), - configJson.value("password").toString(), - configJson.value("server").toString(), - configJson.value("server_port").toString()); + QStringList lines = QString(QJsonDocument(configJson).toJson()).replace("\r", "").split("\n"); + for (const QString &line : lines) { + m_config.append(line + "\n"); + } - m_config = "ss://" + m_config.toUtf8().toBase64(); + m_nativeConfigString = + QString("%1:%2@%3:%4") + .arg(configJson.value("method").toString(), configJson.value("password").toString(), + configJson.value("server").toString(), configJson.value("server_port").toString()); - m_qrCodes = generateQrCodeImageSeries(m_config.toUtf8()); + m_nativeConfigString = "ss://" + m_config.toUtf8().toBase64(); + + qrcodegen::QrCode qr = qrcodegen::QrCode::encodeText(m_nativeConfigString.toUtf8(), qrcodegen::QrCode::Ecc::LOW); + m_qrCodes << svgToBase64(QString::fromStdString(toSvgString(qr, 1))); emit exportConfigChanged(); } @@ -248,7 +253,8 @@ void ExportController::generateCloakConfig() containerConfig.insert(config_key::container, ContainerProps::containerToString(container)); ErrorCode errorCode = ErrorCode::NoError; - QString config = m_configurator->cloakConfigurator->genCloakConfig(credentials, container, containerConfig, &errorCode); + QString config = + m_configurator->cloakConfigurator->genCloakConfig(credentials, container, containerConfig, &errorCode); if (errorCode) { emit exportErrorOccurred(errorString(errorCode)); @@ -265,8 +271,6 @@ void ExportController::generateCloakConfig() m_config.append(line + "\n"); } - m_qrCodes = generateQrCodeImageSeries(m_config.toUtf8()); - emit exportConfigChanged(); } @@ -275,6 +279,11 @@ QString ExportController::getConfig() return m_config; } +QString ExportController::getNativeConfigString() +{ + return m_nativeConfigString; +} + QList ExportController::getQrCodes() { return m_qrCodes; @@ -299,7 +308,7 @@ QList ExportController::generateQrCodeImageSeries(const QByteArray &dat QByteArray ba = chunk.toBase64(QByteArray::Base64UrlEncoding | QByteArray::OmitTrailingEquals); qrcodegen::QrCode qr = qrcodegen::QrCode::encodeText(ba, qrcodegen::QrCode::Ecc::LOW); - QString svg = QString::fromStdString(toSvgString(qr, 0)); + QString svg = QString::fromStdString(toSvgString(qr, 1)); chunks.append(svgToBase64(svg)); } @@ -319,5 +328,6 @@ int ExportController::getQrCodesCount() void ExportController::clearPreviousConfig() { m_config.clear(); + m_nativeConfigString.clear(); m_qrCodes.clear(); } diff --git a/client/ui/controllers/exportController.h b/client/ui/controllers/exportController.h index ee94e741..25658529 100644 --- a/client/ui/controllers/exportController.h +++ b/client/ui/controllers/exportController.h @@ -22,6 +22,7 @@ public: Q_PROPERTY(QList qrCodes READ getQrCodes NOTIFY exportConfigChanged) Q_PROPERTY(int qrCodesCount READ getQrCodesCount NOTIFY exportConfigChanged) Q_PROPERTY(QString config READ getConfig NOTIFY exportConfigChanged) + Q_PROPERTY(QString nativeConfigString READ getNativeConfigString NOTIFY exportConfigChanged) public slots: void generateFullAccessConfig(); @@ -35,6 +36,7 @@ public slots: void generateCloakConfig(); QString getConfig(); + QString getNativeConfigString(); QList getQrCodes(); void exportConfig(const QString &fileName); @@ -61,6 +63,7 @@ private: std::shared_ptr m_configurator; QString m_config; + QString m_nativeConfigString; QList m_qrCodes; #ifdef Q_OS_ANDROID diff --git a/client/ui/qml/Components/ShareConnectionDrawer.qml b/client/ui/qml/Components/ShareConnectionDrawer.qml index 1158dadc..e354e951 100644 --- a/client/ui/qml/Components/ShareConnectionDrawer.qml +++ b/client/ui/qml/Components/ShareConnectionDrawer.qml @@ -112,6 +112,30 @@ DrawerType { } } + BasicButtonType { + Layout.fillWidth: true + Layout.topMargin: 8 + + visible: nativeConfigString.text !== "" + + defaultColor: "transparent" + hoveredColor: Qt.rgba(1, 1, 1, 0.08) + pressedColor: Qt.rgba(1, 1, 1, 0.12) + disabledColor: "#878B91" + textColor: "#D7D8DB" + borderWidth: 1 + + text: qsTr("Copy config string") + imageSource: "qrc:/images/controls/copy.svg" + + onClicked: { + nativeConfigString.selectAll() + nativeConfigString.copy() + nativeConfigString.select(0, 0) + PageController.showNotificationMessage(qsTr("Copied")) + } + } + BasicButtonType { Layout.fillWidth: true Layout.topMargin: 24 @@ -170,6 +194,12 @@ DrawerType { } TextField { + id: nativeConfigString + visible: false + text: ExportController.nativeConfigString + } + + TextArea { id: configText Layout.fillWidth: true @@ -213,7 +243,6 @@ DrawerType { Image { anchors.fill: parent - anchors.margins: 2 smooth: false source: ExportController.qrCodesCount ? ExportController.qrCodes[0] : "" From c164814abd92a35364837073e504f31909be8e3d Mon Sep 17 00:00:00 2001 From: "vladimir.kuznetsov" Date: Mon, 27 Nov 2023 10:59:48 +0700 Subject: [PATCH 13/15] fixed default server setting after importing --- client/ui/qml/Pages2/PageSetupWizardViewConfig.qml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/ui/qml/Pages2/PageSetupWizardViewConfig.qml b/client/ui/qml/Pages2/PageSetupWizardViewConfig.qml index ac35651f..65a6f319 100644 --- a/client/ui/qml/Pages2/PageSetupWizardViewConfig.qml +++ b/client/ui/qml/Pages2/PageSetupWizardViewConfig.qml @@ -24,7 +24,7 @@ PageType { } function onImportFinished() { - if (ConnectionController.isConnected) { + if (!ConnectionController.isConnected) { ServersModel.setDefaultServerIndex(ServersModel.getServersCount() - 1); } From 426ac49f6ff98b2562fa0b3ef154b106d2a27e60 Mon Sep 17 00:00:00 2001 From: "vladimir.kuznetsov" Date: Mon, 27 Nov 2023 12:46:59 +0700 Subject: [PATCH 14/15] fixed "auto-connect" option --- client/amnezia_application.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/amnezia_application.cpp b/client/amnezia_application.cpp index e3adf67a..240c6d35 100644 --- a/client/amnezia_application.cpp +++ b/client/amnezia_application.cpp @@ -354,7 +354,7 @@ void AmneziaApplication::initControllers() m_settingsController.reset(new SettingsController(m_serversModel, m_containersModel, m_languageModel, m_settings)); m_engine->rootContext()->setContextProperty("SettingsController", m_settingsController.get()); - if (m_settingsController->isAutoStartEnabled() && m_serversModel->getDefaultServerIndex() >= 0) { + if (m_settingsController->isAutoConnectEnabled() && m_serversModel->getDefaultServerIndex() >= 0) { QTimer::singleShot(1000, this, [this]() { m_connectionController->openConnection(); }); } From db602ac65bb6cb3b1bf028dbdfe54bb188165dd3 Mon Sep 17 00:00:00 2001 From: "vladimir.kuznetsov" Date: Wed, 29 Nov 2023 10:57:47 +0700 Subject: [PATCH 15/15] fixed ss string generation --- client/ui/controllers/exportController.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/ui/controllers/exportController.cpp b/client/ui/controllers/exportController.cpp index 048eadb0..4c084332 100644 --- a/client/ui/controllers/exportController.cpp +++ b/client/ui/controllers/exportController.cpp @@ -230,7 +230,7 @@ void ExportController::generateShadowSocksConfig() .arg(configJson.value("method").toString(), configJson.value("password").toString(), configJson.value("server").toString(), configJson.value("server_port").toString()); - m_nativeConfigString = "ss://" + m_config.toUtf8().toBase64(); + m_nativeConfigString = "ss://" + m_nativeConfigString.toUtf8().toBase64(); qrcodegen::QrCode qr = qrcodegen::QrCode::encodeText(m_nativeConfigString.toUtf8(), qrcodegen::QrCode::Ecc::LOW); m_qrCodes << svgToBase64(QString::fromStdString(toSvgString(qr, 1)));