Compare commits
22 Commits
fix/linux-
...
dev
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
7d4f3e0f50 | ||
|
|
b1a37b3779 | ||
|
|
86ae77e3d0 | ||
|
|
541a6e07d6 | ||
|
|
f135400d3b | ||
|
|
da184c0ddf | ||
|
|
4116c5c4bc | ||
|
|
667d98f7d7 | ||
|
|
44c10b39e3 | ||
|
|
e4b7e09f86 | ||
|
|
04c2b2af33 | ||
|
|
e643fa008c | ||
|
|
b575df05c7 | ||
|
|
85bd102efa | ||
|
|
717323f138 | ||
|
|
8ed7a5a1d3 | ||
|
|
6ece4e0ac5 | ||
|
|
9d45f3d7ad | ||
|
|
dcf53b989e | ||
|
|
e27f74e4fc | ||
|
|
dbe1a06e35 | ||
|
|
d251d5f0ac |
82
.github/workflows/deploy.yml
vendored
@@ -745,11 +745,37 @@ jobs:
|
||||
needs: Bake-Prebuilts-Android
|
||||
if: ${{ always() }}
|
||||
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
include:
|
||||
- label: 'android9-10'
|
||||
qt_version: '6.10.1'
|
||||
min_sdk: 28
|
||||
max_sdk: 29
|
||||
version_code_offset: 0
|
||||
build_aab: true
|
||||
- label: 'android11+'
|
||||
qt_version: '6.10.3'
|
||||
min_sdk: 30
|
||||
max_sdk: ''
|
||||
version_code_offset: 1
|
||||
build_aab: true
|
||||
- label: 'android9-10-qt610-3'
|
||||
qt_version: '6.10.3'
|
||||
min_sdk: 28
|
||||
max_sdk: 29
|
||||
version_code_offset: 0
|
||||
build_aab: false
|
||||
|
||||
env:
|
||||
ANDROID_PLATFORM: android-28
|
||||
ANDROID_PLATFORM: android-${{ matrix.min_sdk }}
|
||||
NDK_VERSION: 27.0.11718014
|
||||
QT_VERSION: 6.10.3
|
||||
QT_VERSION: ${{ matrix.qt_version }}
|
||||
QT_MODULES: 'qtremoteobjects qt5compat qtimageformats qtshadertools'
|
||||
APP_ANDROID_MIN_SDK: ${{ matrix.min_sdk }}
|
||||
APP_ANDROID_MAX_SDK: ${{ matrix.max_sdk }}
|
||||
APP_ANDROID_VERSION_CODE_OFFSET: ${{ matrix.version_code_offset }}
|
||||
PROD_AGW_PUBLIC_KEY: ${{ secrets.PROD_AGW_PUBLIC_KEY }}
|
||||
PROD_S3_ENDPOINT: ${{ secrets.PROD_S3_ENDPOINT }}
|
||||
FALLBACK_S3_ENDPOINT: ${{ secrets.FALLBACK_S3_ENDPOINT }}
|
||||
@@ -857,62 +883,82 @@ jobs:
|
||||
QT_ANDROID_KEYSTORE_PATH: ${{ github.workspace }}/android.keystore
|
||||
QT_ANDROID_KEYSTORE_ALIAS: ${{ secrets.ANDROID_RELEASE_KEYSTORE_KEY_ALIAS }}
|
||||
QT_ANDROID_KEYSTORE_STORE_PASS: ${{ secrets.ANDROID_RELEASE_KEYSTORE_KEY_PASS }}
|
||||
LABEL: ${{ matrix.label }}
|
||||
BUILD_AAB: ${{ matrix.build_aab }}
|
||||
shell: bash
|
||||
run: |
|
||||
deploy/build.sh -t android --sign --aab
|
||||
OUT=deploy/artifacts
|
||||
rm -rf $OUT && mkdir -p $OUT
|
||||
|
||||
if [[ "$BUILD_AAB" == "true" ]]; then
|
||||
deploy/build.sh -t android --sign --aab
|
||||
else
|
||||
deploy/build.sh -t android --sign
|
||||
fi
|
||||
|
||||
VERSION=$(grep CMAKE_PROJECT_VERSION:STATIC deploy/build/CMakeCache.txt | cut -d= -f2)
|
||||
|
||||
(cd deploy/build/client/android-build && mv AmneziaVPN.apk AmneziaVPN_${VERSION}_android9+_universal.apk)
|
||||
(cd deploy/build/client/android-build/build/outputs/bundle/release && mv android-build-release.aab AmneziaVPN_${VERSION}.aab)
|
||||
mv deploy/build/client/android-build/AmneziaVPN.apk \
|
||||
$OUT/AmneziaVPN_${VERSION}_${LABEL}_universal.apk
|
||||
|
||||
if [[ "$BUILD_AAB" == "true" ]]; then
|
||||
mv deploy/build/client/android-build/build/outputs/bundle/release/android-build-release.aab \
|
||||
$OUT/AmneziaVPN_${VERSION}_${LABEL}.aab
|
||||
fi
|
||||
|
||||
for abi in arm64-v8a armeabi-v7a x86 x86_64; do
|
||||
deploy/build.sh -t android --sign --abi ${abi} --build ./deploy/build/${abi}
|
||||
(cd deploy/build/${abi}/client/android-build && mv AmneziaVPN.apk AmneziaVPN_${VERSION}_android9+_${abi}.apk)
|
||||
mv deploy/build/${abi}/client/android-build/AmneziaVPN.apk \
|
||||
$OUT/AmneziaVPN_${VERSION}_${LABEL}_${abi}.apk
|
||||
done
|
||||
|
||||
ls -l $OUT
|
||||
|
||||
- name: 'Upload universal APK'
|
||||
uses: actions/upload-artifact@v7
|
||||
with:
|
||||
path: deploy/build/client/android-build/*.apk
|
||||
archive: false
|
||||
retention-days: 7
|
||||
|
||||
- name: 'Upload AAB'
|
||||
uses: actions/upload-artifact@v7
|
||||
with:
|
||||
path: deploy/build/client/android-build/build/outputs/bundle/release/*.aab
|
||||
path: deploy/artifacts/*_universal.apk
|
||||
archive: false
|
||||
retention-days: 7
|
||||
|
||||
- name: 'Upload arm64-v8a APK'
|
||||
uses: actions/upload-artifact@v7
|
||||
with:
|
||||
path: deploy/build/arm64-v8a/client/android-build/*.apk
|
||||
path: deploy/artifacts/*_arm64-v8a.apk
|
||||
archive: false
|
||||
retention-days: 7
|
||||
|
||||
- name: 'Upload armeabi-v7a APK'
|
||||
uses: actions/upload-artifact@v7
|
||||
with:
|
||||
path: deploy/build/armeabi-v7a/client/android-build/*.apk
|
||||
path: deploy/artifacts/*_armeabi-v7a.apk
|
||||
archive: false
|
||||
retention-days: 7
|
||||
|
||||
- name: 'Upload x86 APK'
|
||||
uses: actions/upload-artifact@v7
|
||||
with:
|
||||
path: deploy/build/x86/client/android-build/*.apk
|
||||
path: deploy/artifacts/*_x86.apk
|
||||
archive: false
|
||||
retention-days: 7
|
||||
|
||||
- name: 'Upload x86_64 APK'
|
||||
uses: actions/upload-artifact@v7
|
||||
with:
|
||||
path: deploy/build/x86_64/client/android-build/*.apk
|
||||
path: deploy/artifacts/*_x86_64.apk
|
||||
archive: false
|
||||
retention-days: 7
|
||||
|
||||
- name: 'Upload AAB'
|
||||
if: ${{ matrix.build_aab }}
|
||||
uses: actions/upload-artifact@v7
|
||||
with:
|
||||
path: deploy/artifacts/*.aab
|
||||
archive: false
|
||||
retention-days: 7
|
||||
|
||||
# ------------------------------------------------------
|
||||
|
||||
Extra:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
|
||||
@@ -4,7 +4,9 @@ set(CMAKE_CXX_STANDARD 17)
|
||||
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
||||
|
||||
set(PROJECT AmneziaVPN)
|
||||
set(AMNEZIAVPN_VERSION 5.0.1.0)
|
||||
if(NOT AMNEZIAVPN_VERSION)
|
||||
set(AMNEZIAVPN_VERSION 5.0.1.5 CACHE STRING "Client app version")
|
||||
endif()
|
||||
|
||||
set(QT_CREATOR_SKIP_PACKAGE_MANAGER_SETUP ON CACHE BOOL "" FORCE)
|
||||
set(CMAKE_PROJECT_TOP_LEVEL_INCLUDES
|
||||
@@ -28,7 +30,12 @@ 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 2141)
|
||||
|
||||
# bump by 2 on every release, because we're releasing two versions on the play store
|
||||
set(APP_ANDROID_VERSION_CODE 2152)
|
||||
if(DEFINED APP_ANDROID_VERSION_CODE_OFFSET)
|
||||
math(EXPR APP_ANDROID_VERSION_CODE "${APP_ANDROID_VERSION_CODE} + ${APP_ANDROID_VERSION_CODE_OFFSET}")
|
||||
endif()
|
||||
|
||||
if(${CMAKE_SYSTEM_NAME} STREQUAL "Linux")
|
||||
set(MZ_PLATFORM_NAME "linux")
|
||||
@@ -54,14 +61,14 @@ if(APPLE AND NOT IOS)
|
||||
endif()
|
||||
|
||||
configure_file(
|
||||
"${CMAKE_SOURCE_DIR}/deploy/data/pf-templates/amn.400.allowPIA.conf.in"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/deploy/data/pf-templates/amn.400.allowPIA.conf.in"
|
||||
"${CMAKE_CURRENT_BINARY_DIR}/amn.400.allowPIA.conf"
|
||||
@ONLY
|
||||
)
|
||||
|
||||
file(COPY_FILE
|
||||
"${CMAKE_CURRENT_BINARY_DIR}/amn.400.allowPIA.conf"
|
||||
"${CMAKE_SOURCE_DIR}/deploy/data/macos/pf/amn.400.allowPIA.conf"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/deploy/data/macos/pf/amn.400.allowPIA.conf"
|
||||
ONLY_IF_DIFFERENT
|
||||
)
|
||||
endif()
|
||||
|
||||
2
client/3rd/amneziawg-apple
vendored
@@ -1,6 +1,8 @@
|
||||
cmake_minimum_required(VERSION 3.25.0 FATAL_ERROR)
|
||||
|
||||
set(PROJECT AmneziaVPN)
|
||||
include(${CMAKE_CURRENT_LIST_DIR}/cmake/clientBrandingDefaults.cmake)
|
||||
|
||||
set(PROJECT ${CLIENT_TARGET_NAME})
|
||||
project(${PROJECT})
|
||||
|
||||
set_property(GLOBAL PROPERTY USE_FOLDERS ON)
|
||||
@@ -57,6 +59,9 @@ qt_add_executable(${PROJECT} MANUAL_FINALIZATION)
|
||||
target_include_directories(${PROJECT} PUBLIC
|
||||
$<BUILD_INTERFACE:${CMAKE_CURRENT_BINARY_DIR}>
|
||||
)
|
||||
target_compile_definitions(${PROJECT} PRIVATE
|
||||
CLIENT_KEYCHAIN_NAME_STR=\"${CLIENT_KEYCHAIN_NAME}\"
|
||||
)
|
||||
|
||||
if(WIN32 OR (APPLE AND NOT IOS AND NOT MACOS_NE) OR (LINUX AND NOT ANDROID))
|
||||
qt_add_repc_replicas(${PROJECT} ${CMAKE_CURRENT_LIST_DIR}/../ipc/ipc_interface.rep)
|
||||
@@ -67,24 +72,34 @@ qt6_add_resources(QRC ${QRC}
|
||||
${CMAKE_CURRENT_LIST_DIR}/images/images.qrc
|
||||
${CMAKE_CURRENT_LIST_DIR}/images/flagKit.qrc
|
||||
${CMAKE_CURRENT_LIST_DIR}/client_scripts/clientScripts.qrc
|
||||
${CMAKE_CURRENT_LIST_DIR}/ui/qml/qml.qrc
|
||||
${CLIENT_QML_QRC_FILE}
|
||||
${CMAKE_CURRENT_LIST_DIR}/server_scripts/serverScripts.qrc
|
||||
${CLIENT_EXTRA_QRC}
|
||||
)
|
||||
|
||||
# -- i18n begin
|
||||
set(AMNEZIAVPN_TS_FILES
|
||||
${CMAKE_CURRENT_LIST_DIR}/translations/amneziavpn_ru_RU.ts
|
||||
${CMAKE_CURRENT_LIST_DIR}/translations/amneziavpn_zh_CN.ts
|
||||
${CMAKE_CURRENT_LIST_DIR}/translations/amneziavpn_fa_IR.ts
|
||||
${CMAKE_CURRENT_LIST_DIR}/translations/amneziavpn_ar_EG.ts
|
||||
${CMAKE_CURRENT_LIST_DIR}/translations/amneziavpn_my_MM.ts
|
||||
${CMAKE_CURRENT_LIST_DIR}/translations/amneziavpn_uk_UA.ts
|
||||
${CMAKE_CURRENT_LIST_DIR}/translations/amneziavpn_ur_PK.ts
|
||||
${CMAKE_CURRENT_LIST_DIR}/translations/amneziavpn_hi_IN.ts
|
||||
)
|
||||
if(CLIENT_TS_FILES)
|
||||
set(AMNEZIAVPN_TS_FILES ${CLIENT_TS_FILES})
|
||||
else()
|
||||
set(AMNEZIAVPN_TS_FILES
|
||||
${CMAKE_CURRENT_LIST_DIR}/translations/${CLIENT_TS_PREFIX}_ru_RU.ts
|
||||
${CMAKE_CURRENT_LIST_DIR}/translations/${CLIENT_TS_PREFIX}_zh_CN.ts
|
||||
${CMAKE_CURRENT_LIST_DIR}/translations/${CLIENT_TS_PREFIX}_fa_IR.ts
|
||||
${CMAKE_CURRENT_LIST_DIR}/translations/${CLIENT_TS_PREFIX}_ar_EG.ts
|
||||
${CMAKE_CURRENT_LIST_DIR}/translations/${CLIENT_TS_PREFIX}_my_MM.ts
|
||||
${CMAKE_CURRENT_LIST_DIR}/translations/${CLIENT_TS_PREFIX}_uk_UA.ts
|
||||
${CMAKE_CURRENT_LIST_DIR}/translations/${CLIENT_TS_PREFIX}_ur_PK.ts
|
||||
${CMAKE_CURRENT_LIST_DIR}/translations/${CLIENT_TS_PREFIX}_hi_IN.ts
|
||||
${CMAKE_CURRENT_LIST_DIR}/translations/${CLIENT_TS_PREFIX}_es_ES.ts
|
||||
${CMAKE_CURRENT_LIST_DIR}/translations/${CLIENT_TS_PREFIX}_ko_KR.ts
|
||||
)
|
||||
endif()
|
||||
|
||||
file(GLOB_RECURSE AMNEZIAVPN_QML_FILES ${CMAKE_CURRENT_LIST_DIR}/ui/qml/*.qml)
|
||||
|
||||
qt6_add_translations(${PROJECT}
|
||||
TS_FILES ${AMNEZIAVPN_TS_FILES}
|
||||
SOURCES ${AMNEZIAVPN_QML_FILES}
|
||||
RESOURCE_PREFIX "/translations"
|
||||
)
|
||||
# -- i18n end
|
||||
@@ -101,13 +116,18 @@ endif()
|
||||
include(${CMAKE_CURRENT_LIST_DIR}/cmake/3rdparty.cmake)
|
||||
include(${CMAKE_CURRENT_LIST_DIR}/cmake/sources.cmake)
|
||||
|
||||
include_directories(
|
||||
set(_client_include_dirs
|
||||
${CMAKE_CURRENT_LIST_DIR}/../ipc
|
||||
${CMAKE_CURRENT_LIST_DIR}/../common/logger
|
||||
${CMAKE_CURRENT_LIST_DIR}/../common/crypto
|
||||
${CMAKE_CURRENT_LIST_DIR}
|
||||
${CMAKE_CURRENT_BINARY_DIR}
|
||||
)
|
||||
if(CLIENT_BRANDING_INCLUDE_DIR)
|
||||
list(APPEND _client_include_dirs ${CLIENT_BRANDING_INCLUDE_DIR})
|
||||
endif()
|
||||
list(APPEND _client_include_dirs ${CMAKE_CURRENT_LIST_DIR})
|
||||
include_directories(${_client_include_dirs})
|
||||
|
||||
if(MACOS_NE)
|
||||
message("MACOS_NE is ON")
|
||||
@@ -123,6 +143,26 @@ include_directories(mozilla/shared)
|
||||
include_directories(mozilla/models)
|
||||
|
||||
configure_file(${CMAKE_CURRENT_LIST_DIR}/../version.h.in ${CMAKE_CURRENT_BINARY_DIR}/version.h)
|
||||
file(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/core/utils)
|
||||
configure_file(
|
||||
${CMAKE_CURRENT_LIST_DIR}/core/utils/appUiConfig.h.in
|
||||
${CMAKE_CURRENT_BINARY_DIR}/core/utils/appUiConfig.h
|
||||
@ONLY
|
||||
)
|
||||
configure_file(
|
||||
${CMAKE_CURRENT_LIST_DIR}/core/utils/swiftBridgeConfig.h.in
|
||||
${CMAKE_CURRENT_BINARY_DIR}/core/utils/swiftBridgeConfig.h
|
||||
@ONLY
|
||||
)
|
||||
# Swift can't consume a `-DGROUP_ID="value"` compile define (Swift -D flags are
|
||||
# presence-only), unlike the Objective-C++ sources that read GROUP_ID directly.
|
||||
# Generate a Swift constant instead so Log.swift can use the branded app group.
|
||||
set(CLIENT_GROUP_IDENTIFIER_SWIFT_FILE ${CMAKE_CURRENT_BINARY_DIR}/platforms/ios/GroupIdentifier.swift)
|
||||
configure_file(
|
||||
${CMAKE_CURRENT_LIST_DIR}/platforms/ios/GroupIdentifier.swift.in
|
||||
${CLIENT_GROUP_IDENTIFIER_SWIFT_FILE}
|
||||
@ONLY
|
||||
)
|
||||
|
||||
if(CMAKE_BUILD_TYPE STREQUAL "Debug")
|
||||
target_compile_definitions(${PROJECT} PRIVATE "MZ_DEBUG")
|
||||
@@ -150,18 +190,6 @@ if(APPLE)
|
||||
cmake_policy(SET CMP0099 NEW)
|
||||
cmake_policy(SET CMP0114 NEW)
|
||||
|
||||
if(NOT BUILD_OSX_APP_IDENTIFIER)
|
||||
set(BUILD_OSX_APP_IDENTIFIER org.amnezia.AmneziaVPN CACHE STRING "OSX Application identifier")
|
||||
endif()
|
||||
if(NOT BUILD_IOS_APP_IDENTIFIER)
|
||||
set(BUILD_IOS_APP_IDENTIFIER org.amnezia.AmneziaVPN CACHE STRING "iOS Application identifier")
|
||||
endif()
|
||||
if(NOT BUILD_IOS_GROUP_IDENTIFIER)
|
||||
set(BUILD_IOS_GROUP_IDENTIFIER group.org.amnezia.AmneziaVPN CACHE STRING "iOS Group identifier")
|
||||
endif()
|
||||
if(NOT BUILD_VPN_DEVELOPMENT_TEAM)
|
||||
set(BUILD_VPN_DEVELOPMENT_TEAM X7UJ388FXK CACHE STRING "Amnezia VPN Development Team")
|
||||
endif()
|
||||
|
||||
set(CMAKE_XCODE_GENERATE_SCHEME FALSE)
|
||||
set(CMAKE_XCODE_ATTRIBUTE_DEVELOPMENT_TEAM ${BUILD_VPN_DEVELOPMENT_TEAM})
|
||||
|
||||
@@ -24,6 +24,7 @@
|
||||
#include "ui/models/installedAppsModel.h"
|
||||
#include "ui/utils/mtProxyPublicHostInput.h"
|
||||
#include "version.h"
|
||||
#include "core/utils/appUiConfig.h"
|
||||
|
||||
#include "platforms/ios/QRCodeReaderBase.h"
|
||||
#ifdef Q_OS_IOS
|
||||
@@ -102,7 +103,7 @@ void AmneziaApplication::init()
|
||||
{
|
||||
m_engine = new QQmlApplicationEngine;
|
||||
|
||||
const QUrl url(QStringLiteral("qrc:/ui/qml/main2.qml"));
|
||||
const QUrl url(QStringLiteral(APP_QML_ENTRYPOINT));
|
||||
QObject::connect(
|
||||
m_engine, &QQmlApplicationEngine::objectCreated, this,
|
||||
[this, url](QObject *obj, const QUrl &objUrl) {
|
||||
@@ -155,7 +156,7 @@ void AmneziaApplication::init()
|
||||
m_marketplaceUpdateController.reset(new MarketplaceUpdateController());
|
||||
m_marketplaceUpdateController->start();
|
||||
|
||||
m_engine->addImportPath("qrc:/ui/qml/Modules/");
|
||||
m_engine->addImportPath(QStringLiteral(APP_QML_IMPORT_PATH));
|
||||
|
||||
if (m_parser.isSet(m_optImport)) {
|
||||
const QString data = m_parser.value(m_optImport);
|
||||
@@ -244,7 +245,7 @@ void AmneziaApplication::loadFonts()
|
||||
{
|
||||
QQuickStyle::setStyle("Basic");
|
||||
|
||||
QFontDatabase::addApplicationFont(":/fonts/pt-root-ui_vf.ttf");
|
||||
QFontDatabase::addApplicationFont(QStringLiteral(APP_UI_FONT_RESOURCE));
|
||||
}
|
||||
|
||||
bool AmneziaApplication::parseCommands()
|
||||
@@ -271,7 +272,7 @@ bool AmneziaApplication::parseCommands()
|
||||
|
||||
#if !defined(Q_OS_ANDROID) && !defined(Q_OS_IOS) && !defined(MACOS_NE)
|
||||
void AmneziaApplication::startLocalServer() {
|
||||
const QString serverName("AmneziaVPNInstance");
|
||||
const QString serverName(APP_INSTANCE_NAME);
|
||||
QLocalServer::removeServer(serverName);
|
||||
|
||||
QLocalServer *server = new QLocalServer(this);
|
||||
|
||||
|
Before Width: | Height: | Size: 11 KiB After Width: | Height: | Size: 6.3 KiB |
|
Before Width: | Height: | Size: 6.6 KiB After Width: | Height: | Size: 3.6 KiB |
|
Before Width: | Height: | Size: 16 KiB After Width: | Height: | Size: 9.4 KiB |
|
Before Width: | Height: | Size: 25 KiB After Width: | Height: | Size: 18 KiB |
|
Before Width: | Height: | Size: 35 KiB After Width: | Height: | Size: 28 KiB |
@@ -148,6 +148,10 @@ open class Wireguard : Protocol() {
|
||||
?.let { setKeepaliveTimeout(it) }
|
||||
configData.optStringOrNull("MaxHandshakeAttempts")?.trim()?.takeIf { it.isNotEmpty() }
|
||||
?.let { setMaxHandshakeAttempts(it) }
|
||||
configData.optStringOrNull("RandomTrailers")?.trim()?.takeIf { it.isNotEmpty() }
|
||||
?.let { setRandomTrailers(it) }
|
||||
configData.optStringOrNull("DisableCookies")?.trim()?.takeIf { it.isNotEmpty() }
|
||||
?.let { setDisableCookies(it) }
|
||||
}
|
||||
|
||||
private fun start(
|
||||
|
||||
@@ -38,6 +38,8 @@ open class WireguardConfig protected constructor(
|
||||
val rejectAfterTime: String?,
|
||||
val keepaliveTimeout: String?,
|
||||
val maxHandshakeAttempts: String?,
|
||||
val randomTrailers: String?,
|
||||
val disableCookies: String?,
|
||||
) : ProtocolConfig(protocolConfigBuilder) {
|
||||
|
||||
protected constructor(builder: Builder) : this(
|
||||
@@ -71,6 +73,8 @@ open class WireguardConfig protected constructor(
|
||||
builder.rejectAfterTime,
|
||||
builder.keepaliveTimeout,
|
||||
builder.maxHandshakeAttempts,
|
||||
builder.randomTrailers,
|
||||
builder.disableCookies,
|
||||
)
|
||||
|
||||
fun toWgUserspaceString(): String = with(StringBuilder()) {
|
||||
@@ -108,6 +112,8 @@ open class WireguardConfig protected constructor(
|
||||
rejectAfterTime?.takeIf { it.isNotEmpty() }?.let { appendLine("reject_after_time=$it") }
|
||||
keepaliveTimeout?.takeIf { it.isNotEmpty() }?.let { appendLine("keepalive_timeout=$it") }
|
||||
maxHandshakeAttempts?.takeIf { it.isNotEmpty() }?.let { appendLine("max_handshake_attempts=$it") }
|
||||
randomTrailers?.takeIf { it.isNotEmpty() }?.let { appendLine("random_trailers=${it.toUapiBool()}") }
|
||||
disableCookies?.takeIf { it.isNotEmpty() }?.let { appendLine("disable_cookies=${it.toUapiBool()}") }
|
||||
}
|
||||
|
||||
private fun validateProtocolExtensionParameters() {
|
||||
@@ -177,6 +183,8 @@ open class WireguardConfig protected constructor(
|
||||
internal var rejectAfterTime: String? = null
|
||||
internal var keepaliveTimeout: String? = null
|
||||
internal var maxHandshakeAttempts: String? = null
|
||||
internal var randomTrailers: String? = null
|
||||
internal var disableCookies: String? = null
|
||||
|
||||
fun setEndpoint(endpoint: InetEndpoint) = apply { this.endpoint = endpoint }
|
||||
|
||||
@@ -213,6 +221,8 @@ open class WireguardConfig protected constructor(
|
||||
fun setRejectAfterTime(rejectAfterTime: String) = apply { this.rejectAfterTime = rejectAfterTime }
|
||||
fun setKeepaliveTimeout(keepaliveTimeout: String) = apply { this.keepaliveTimeout = keepaliveTimeout }
|
||||
fun setMaxHandshakeAttempts(maxHandshakeAttempts: String) = apply { this.maxHandshakeAttempts = maxHandshakeAttempts }
|
||||
fun setRandomTrailers(randomTrailers: String) = apply { this.randomTrailers = randomTrailers }
|
||||
fun setDisableCookies(disableCookies: String) = apply { this.disableCookies = disableCookies }
|
||||
|
||||
override fun build(): WireguardConfig = configBuild().run { WireguardConfig(this@Builder) }
|
||||
}
|
||||
@@ -224,3 +234,9 @@ open class WireguardConfig protected constructor(
|
||||
|
||||
@OptIn(ExperimentalStdlibApi::class)
|
||||
internal fun String.base64ToHex(): String = Base64.decode(this, Base64.DEFAULT).toHexString()
|
||||
|
||||
/** Converts awg-quick on/off (and 0/1/true/false) to UAPI 1/0 for amneziawg-go ParseBool. */
|
||||
internal fun String.toUapiBool(): String = when (trim().lowercase()) {
|
||||
"on", "1", "true", "t", "yes" -> "1"
|
||||
else -> "0"
|
||||
}
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
message("Client android ${CMAKE_ANDROID_ARCH_ABI} build")
|
||||
|
||||
set(APP_ANDROID_MIN_SDK 28)
|
||||
if(NOT DEFINED APP_ANDROID_MIN_SDK)
|
||||
set(APP_ANDROID_MIN_SDK 28)
|
||||
endif()
|
||||
set(ANDROID_PLATFORM "android-${APP_ANDROID_MIN_SDK}" CACHE STRING
|
||||
"The minimum API level supported by the application or library" FORCE)
|
||||
|
||||
@@ -13,7 +15,6 @@ set_target_properties(${PROJECT} PROPERTIES
|
||||
QT_ANDROID_MIN_SDK_VERSION ${APP_ANDROID_MIN_SDK}
|
||||
QT_ANDROID_TARGET_SDK_VERSION 36
|
||||
QT_ANDROID_SDK_BUILD_TOOLS_REVISION 36.0.0
|
||||
QT_ANDROID_PACKAGE_SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/android
|
||||
)
|
||||
|
||||
set(QT_ANDROID_MULTI_ABI_FORWARD_VARS "QT_NO_GLOBAL_APK_TARGET_PART_OF_ALL;CMAKE_BUILD_TYPE")
|
||||
@@ -53,3 +54,27 @@ file(COPY ${AMNEZIA_LIBXRAY_PATH} DESTINATION ${CMAKE_CURRENT_SOURCE_DIR}/androi
|
||||
find_package(openvpn-pt-android REQUIRED)
|
||||
set(LIBS ${LIBS} amnezia::openvpn-pt-android)
|
||||
set_property(TARGET ${PROJECT} APPEND PROPERTY QT_ANDROID_EXTRA_LIBS ${OPENVPN_PT_ANDROID_LIBCK_OVPN_PLUGIN_PATH})
|
||||
|
||||
set(APP_ANDROID_PACKAGE_SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/android)
|
||||
|
||||
if(APP_ANDROID_MAX_SDK)
|
||||
set(APP_ANDROID_PACKAGE_SOURCE_DIR ${CMAKE_CURRENT_BINARY_DIR}/android-package-source)
|
||||
file(REMOVE_RECURSE ${APP_ANDROID_PACKAGE_SOURCE_DIR})
|
||||
file(COPY ${CMAKE_CURRENT_SOURCE_DIR}/android/ DESTINATION ${APP_ANDROID_PACKAGE_SOURCE_DIR})
|
||||
|
||||
set(manifest_path ${APP_ANDROID_PACKAGE_SOURCE_DIR}/AndroidManifest.xml)
|
||||
set(manifest_anchor "android:installLocation=\"auto\">")
|
||||
file(READ ${manifest_path} manifest_contents)
|
||||
string(REPLACE
|
||||
"${manifest_anchor}"
|
||||
"${manifest_anchor}\n\n <uses-sdk android:maxSdkVersion=\"${APP_ANDROID_MAX_SDK}\" />"
|
||||
patched_contents "${manifest_contents}")
|
||||
if(patched_contents STREQUAL manifest_contents)
|
||||
message(FATAL_ERROR
|
||||
"Failed to set maxSdkVersion=${APP_ANDROID_MAX_SDK}: anchor '${manifest_anchor}' "
|
||||
"not found in ${CMAKE_CURRENT_SOURCE_DIR}/android/AndroidManifest.xml")
|
||||
endif()
|
||||
file(WRITE ${manifest_path} "${patched_contents}")
|
||||
endif()
|
||||
|
||||
set_property(TARGET ${PROJECT} PROPERTY QT_ANDROID_PACKAGE_SOURCE_DIR ${APP_ANDROID_PACKAGE_SOURCE_DIR})
|
||||
|
||||
3
client/cmake/branding/android.cmake
Normal file
@@ -0,0 +1,3 @@
|
||||
if(NOT CLIENT_ANDROID_PACKAGE)
|
||||
set(CLIENT_ANDROID_PACKAGE "org.amnezia.vpn" CACHE STRING "Android package name for Play Store version lookup")
|
||||
endif()
|
||||
22
client/cmake/branding/apple.cmake
Normal file
@@ -0,0 +1,22 @@
|
||||
if(NOT CLIENT_SWIFT_MODULE_NAME)
|
||||
set(CLIENT_SWIFT_MODULE_NAME "${CLIENT_APPLICATION_NAME}" CACHE STRING "Swift module name for Objective-C interop header")
|
||||
endif()
|
||||
if(NOT CLIENT_SWIFT_OBJC_HEADER_NAME)
|
||||
set(CLIENT_SWIFT_OBJC_HEADER_NAME "${CLIENT_SWIFT_MODULE_NAME}-Swift.h" CACHE STRING "Generated Swift Objective-C header name")
|
||||
endif()
|
||||
if(NOT CLIENT_NETWORK_EXTENSION_NAME)
|
||||
set(CLIENT_NETWORK_EXTENSION_NAME "${CLIENT_APPLICATION_NAME}NetworkExtension" CACHE STRING "Display name for Apple network extension targets")
|
||||
endif()
|
||||
|
||||
if(NOT BUILD_OSX_APP_IDENTIFIER)
|
||||
set(BUILD_OSX_APP_IDENTIFIER org.amnezia.AmneziaVPN CACHE STRING "OSX Application identifier")
|
||||
endif()
|
||||
if(NOT BUILD_IOS_APP_IDENTIFIER)
|
||||
set(BUILD_IOS_APP_IDENTIFIER org.amnezia.AmneziaVPN CACHE STRING "iOS Application identifier")
|
||||
endif()
|
||||
if(NOT BUILD_IOS_GROUP_IDENTIFIER)
|
||||
set(BUILD_IOS_GROUP_IDENTIFIER group.org.amnezia.AmneziaVPN CACHE STRING "iOS Group identifier")
|
||||
endif()
|
||||
if(NOT BUILD_VPN_DEVELOPMENT_TEAM)
|
||||
set(BUILD_VPN_DEVELOPMENT_TEAM X7UJ388FXK CACHE STRING "Amnezia VPN Development Team")
|
||||
endif()
|
||||
60
client/cmake/branding/common.cmake
Normal file
@@ -0,0 +1,60 @@
|
||||
if(NOT CLIENT_TARGET_NAME)
|
||||
set(CLIENT_TARGET_NAME "AmneziaVPN" CACHE STRING "Client executable target name")
|
||||
endif()
|
||||
if(NOT CLIENT_APPLICATION_NAME)
|
||||
set(CLIENT_APPLICATION_NAME "AmneziaVPN" CACHE STRING "Application display and executable name")
|
||||
endif()
|
||||
if(NOT CLIENT_SERVICE_NAME)
|
||||
set(CLIENT_SERVICE_NAME "AmneziaVPN-service" CACHE STRING "Service executable name")
|
||||
endif()
|
||||
if(NOT CLIENT_ORGANIZATION_NAME)
|
||||
set(CLIENT_ORGANIZATION_NAME "AmneziaVPN.ORG" CACHE STRING "QSettings organization name")
|
||||
endif()
|
||||
if(NOT CLIENT_APP_INSTANCE_NAME)
|
||||
set(CLIENT_APP_INSTANCE_NAME "AmneziaVPNInstance" CACHE STRING "Single-instance local server name")
|
||||
endif()
|
||||
if(NOT CLIENT_KEYCHAIN_NAME)
|
||||
set(CLIENT_KEYCHAIN_NAME "${CLIENT_APPLICATION_NAME}-Keychain" CACHE STRING "QtKeychain service name used for encrypted settings keys")
|
||||
endif()
|
||||
|
||||
# -- QML entry points and UI resources
|
||||
if(NOT CLIENT_QML_ENTRYPOINT)
|
||||
set(CLIENT_QML_ENTRYPOINT "qrc:/ui/qml/main2.qml" CACHE STRING "Main QML entrypoint URL")
|
||||
endif()
|
||||
if(NOT CLIENT_QML_IMPORT_PATH)
|
||||
set(CLIENT_QML_IMPORT_PATH "qrc:/ui/qml/Modules/" CACHE STRING "Additional QQmlEngine import path")
|
||||
endif()
|
||||
if(NOT CLIENT_QML_PAGES_PREFIX)
|
||||
set(CLIENT_QML_PAGES_PREFIX "qrc:/ui/qml/Pages2/" CACHE STRING "PageController QML pages prefix")
|
||||
endif()
|
||||
if(NOT CLIENT_UI_FONT_RESOURCE)
|
||||
set(CLIENT_UI_FONT_RESOURCE ":/fonts/pt-root-ui_vf.ttf" CACHE STRING "UI font resource path")
|
||||
endif()
|
||||
if(NOT CLIENT_QML_QRC_FILE)
|
||||
set(CLIENT_QML_QRC_FILE "${_CLIENT_SRC_DIR}/ui/qml/qml.qrc" CACHE FILEPATH "QML resources manifest")
|
||||
endif()
|
||||
if(NOT CLIENT_EXTRA_QRC)
|
||||
set(CLIENT_EXTRA_QRC "" CACHE STRING "Optional semicolon-separated extra QRC files")
|
||||
endif()
|
||||
|
||||
# -- translations
|
||||
if(NOT CLIENT_TS_PREFIX)
|
||||
set(CLIENT_TS_PREFIX "amneziavpn" CACHE STRING "Translation filename prefix")
|
||||
endif()
|
||||
if(NOT CLIENT_TS_FILES)
|
||||
set(CLIENT_TS_FILES "" CACHE STRING "Optional semicolon-separated absolute TS file paths")
|
||||
endif()
|
||||
|
||||
# -- brand-provided headers
|
||||
if(NOT CLIENT_BRANDING_INCLUDE_DIR)
|
||||
set(CLIENT_BRANDING_INCLUDE_DIR "" CACHE PATH "Optional include root for non-generated branding headers (e.g. pageEnum.h)")
|
||||
endif()
|
||||
if(CLIENT_BRANDING_INCLUDE_DIR AND EXISTS "${CLIENT_BRANDING_INCLUDE_DIR}/ui/utils/pageEnum.h")
|
||||
set(CLIENT_PAGE_ENUM_HEADER "${CLIENT_BRANDING_INCLUDE_DIR}/ui/utils/pageEnum.h")
|
||||
else()
|
||||
set(CLIENT_PAGE_ENUM_HEADER "${_CLIENT_SRC_DIR}/ui/utils/pageEnum.h")
|
||||
endif()
|
||||
|
||||
if(NOT CLIENT_NOTIFICATION_IDENTIFIER)
|
||||
set(CLIENT_NOTIFICATION_IDENTIFIER "${CLIENT_TS_PREFIX}" CACHE STRING "Local notification request identifier")
|
||||
endif()
|
||||
45
client/cmake/branding/ios.cmake
Normal file
@@ -0,0 +1,45 @@
|
||||
if(NOT CLIENT_IOS_NE_TARGET_NAME)
|
||||
set(CLIENT_IOS_NE_TARGET_NAME "networkextension" CACHE STRING "iOS network extension build target name")
|
||||
endif()
|
||||
if(NOT CLIENT_IOS_NE_ENTITLEMENTS_FILE)
|
||||
set(CLIENT_IOS_NE_ENTITLEMENTS_FILE "AmneziaVPNNetworkExtension.entitlements" CACHE STRING "iOS network extension entitlements filename")
|
||||
endif()
|
||||
if(NOT CLIENT_IOS_LAUNCHSCREEN_FILE)
|
||||
set(CLIENT_IOS_LAUNCHSCREEN_FILE "AmneziaVPNLaunchScreen.storyboard" CACHE STRING "iOS launch screen storyboard filename")
|
||||
endif()
|
||||
|
||||
get_filename_component(CLIENT_IOS_LAUNCHSCREEN_NAME "${CLIENT_IOS_LAUNCHSCREEN_FILE}" NAME_WE)
|
||||
|
||||
if(NOT CLIENT_IOS_APP_ENTITLEMENTS_PATH)
|
||||
set(CLIENT_IOS_APP_ENTITLEMENTS_PATH "${_CLIENT_SRC_DIR}/ios/app/main.entitlements" CACHE FILEPATH "iOS app entitlements file path")
|
||||
endif()
|
||||
if(NOT CLIENT_IOS_NE_ENTITLEMENTS_PATH)
|
||||
set(CLIENT_IOS_NE_ENTITLEMENTS_PATH "${_CLIENT_SRC_DIR}/ios/networkextension/${CLIENT_IOS_NE_ENTITLEMENTS_FILE}" CACHE FILEPATH "iOS network extension entitlements file path")
|
||||
endif()
|
||||
if(NOT CLIENT_IOS_LAUNCHSCREEN_PATH)
|
||||
set(CLIENT_IOS_LAUNCHSCREEN_PATH "${_CLIENT_SRC_DIR}/ios/app/${CLIENT_IOS_LAUNCHSCREEN_FILE}" CACHE FILEPATH "iOS launch screen storyboard path")
|
||||
endif()
|
||||
if(NOT CLIENT_IOS_MEDIA_ASSETS_PATH)
|
||||
set(CLIENT_IOS_MEDIA_ASSETS_PATH "${_CLIENT_SRC_DIR}/ios/app/Media.xcassets" CACHE FILEPATH "iOS app Media.xcassets path")
|
||||
endif()
|
||||
|
||||
if(NOT CLIENT_IOS_BUNDLE_ID)
|
||||
set(CLIENT_IOS_BUNDLE_ID "org.amnezia.AmneziaVPN" CACHE STRING "iOS bundle id for App Store version lookup")
|
||||
endif()
|
||||
if(NOT CLIENT_IOS_STORE_URL_FALLBACK)
|
||||
set(CLIENT_IOS_STORE_URL_FALLBACK "itms-apps://itunes.apple.com/app/id1600529900" CACHE STRING "Fallback App Store URL when lookup omits trackViewUrl")
|
||||
endif()
|
||||
|
||||
# -- signing
|
||||
if(NOT CLIENT_IOS_PROVISIONING_PROFILE_SPECIFIER)
|
||||
set(CLIENT_IOS_PROVISIONING_PROFILE_SPECIFIER "distr ios.org.amnezia.AmneziaVPN" CACHE STRING "iOS app provisioning profile specifier for release")
|
||||
endif()
|
||||
if(NOT CLIENT_IOS_PROVISIONING_PROFILE_SPECIFIER_DEBUG)
|
||||
set(CLIENT_IOS_PROVISIONING_PROFILE_SPECIFIER_DEBUG "dev ios.org.amnezia.AmneziaVPN" CACHE STRING "iOS app provisioning profile specifier for debug")
|
||||
endif()
|
||||
if(NOT CLIENT_IOS_NE_PROVISIONING_PROFILE_SPECIFIER)
|
||||
set(CLIENT_IOS_NE_PROVISIONING_PROFILE_SPECIFIER "distr ios.org.amnezia.AmneziaVPN" CACHE STRING "iOS network extension provisioning profile specifier for release")
|
||||
endif()
|
||||
if(NOT CLIENT_IOS_NE_PROVISIONING_PROFILE_SPECIFIER_DEBUG)
|
||||
set(CLIENT_IOS_NE_PROVISIONING_PROFILE_SPECIFIER_DEBUG "dev ios.org.amnezia.AmneziaVPN" CACHE STRING "iOS network extension provisioning profile specifier for debug")
|
||||
endif()
|
||||
37
client/cmake/branding/macos.cmake
Normal file
@@ -0,0 +1,37 @@
|
||||
if(NOT CLIENT_MACOS_NE_TARGET_NAME)
|
||||
set(CLIENT_MACOS_NE_TARGET_NAME "${CLIENT_NETWORK_EXTENSION_NAME}" CACHE STRING "macOS network extension build target name")
|
||||
endif()
|
||||
if(NOT CLIENT_MACOS_NE_ENTITLEMENTS_FILE)
|
||||
set(CLIENT_MACOS_NE_ENTITLEMENTS_FILE "AmneziaVPNNetworkExtension.entitlements" CACHE STRING "macOS network extension entitlements filename")
|
||||
endif()
|
||||
|
||||
if(NOT CLIENT_MACOS_APP_ENTITLEMENTS_PATH)
|
||||
set(CLIENT_MACOS_APP_ENTITLEMENTS_PATH "${_CLIENT_SRC_DIR}/macos/app/app.entitlements" CACHE FILEPATH "macOS app entitlements file path")
|
||||
endif()
|
||||
if(NOT CLIENT_MACOS_NE_ENTITLEMENTS_PATH)
|
||||
set(CLIENT_MACOS_NE_ENTITLEMENTS_PATH "${_CLIENT_SRC_DIR}/macos/networkextension/${CLIENT_MACOS_NE_ENTITLEMENTS_FILE}" CACHE FILEPATH "macOS network extension entitlements file path")
|
||||
endif()
|
||||
if(NOT CLIENT_MACOS_MEDIA_ASSETS_PATH)
|
||||
set(CLIENT_MACOS_MEDIA_ASSETS_PATH "${_CLIENT_SRC_DIR}/macos/app/Images.xcassets" CACHE FILEPATH "macOS app Images.xcassets path")
|
||||
endif()
|
||||
if(NOT CLIENT_MACOS_APP_ICNS_PATH)
|
||||
set(CLIENT_MACOS_APP_ICNS_PATH "${_CLIENT_SRC_DIR}/images/app.icns" CACHE FILEPATH "macOS app icon (.icns) used by non-App Store builds")
|
||||
endif()
|
||||
|
||||
if(NOT CLIENT_MACOS_EXTRA_PLIST_ENTRIES)
|
||||
set(CLIENT_MACOS_EXTRA_PLIST_ENTRIES "" CACHE STRING "Extra macOS Info.plist entries appended verbatim (e.g. appearance pinning)")
|
||||
endif()
|
||||
|
||||
# -- signing
|
||||
if(NOT CLIENT_MACOS_PROVISIONING_PROFILE_SPECIFIER)
|
||||
set(CLIENT_MACOS_PROVISIONING_PROFILE_SPECIFIER "distr macos.org.amnezia.AmneziaVPN" CACHE STRING "macOS app provisioning profile specifier for release")
|
||||
endif()
|
||||
if(NOT CLIENT_MACOS_PROVISIONING_PROFILE_SPECIFIER_DEBUG)
|
||||
set(CLIENT_MACOS_PROVISIONING_PROFILE_SPECIFIER_DEBUG "dev macos.org.amnezia.AmneziaVPN" CACHE STRING "macOS app provisioning profile specifier for debug")
|
||||
endif()
|
||||
if(NOT CLIENT_MACOS_NE_PROVISIONING_PROFILE_SPECIFIER)
|
||||
set(CLIENT_MACOS_NE_PROVISIONING_PROFILE_SPECIFIER "distr macos.org.amnezia.amneziaVPN.NE" CACHE STRING "macOS network extension provisioning profile specifier for release")
|
||||
endif()
|
||||
if(NOT CLIENT_MACOS_NE_PROVISIONING_PROFILE_SPECIFIER_DEBUG)
|
||||
set(CLIENT_MACOS_NE_PROVISIONING_PROFILE_SPECIFIER_DEBUG "dev macos.org.amnezia.amneziaVPN.NE" CACHE STRING "macOS network extension provisioning profile specifier for debug")
|
||||
endif()
|
||||
9
client/cmake/clientBrandingDefaults.cmake
Normal file
@@ -0,0 +1,9 @@
|
||||
get_filename_component(_CLIENT_SRC_DIR "${CMAKE_CURRENT_LIST_DIR}/.." ABSOLUTE)
|
||||
|
||||
include(${CMAKE_CURRENT_LIST_DIR}/branding/common.cmake)
|
||||
include(${CMAKE_CURRENT_LIST_DIR}/branding/apple.cmake)
|
||||
include(${CMAKE_CURRENT_LIST_DIR}/branding/ios.cmake)
|
||||
include(${CMAKE_CURRENT_LIST_DIR}/branding/macos.cmake)
|
||||
include(${CMAKE_CURRENT_LIST_DIR}/branding/android.cmake)
|
||||
|
||||
unset(_CLIENT_SRC_DIR)
|
||||
@@ -24,6 +24,17 @@ set(IOS_TARGET_COMPILED_TYPES
|
||||
EXECUTABLE
|
||||
)
|
||||
|
||||
## Simulator architecture: honor CMAKE_OSX_ARCHITECTURES when set, otherwise
|
||||
## match the host — arm64 Macs run arm64 simulators (Xcode 26 has no Rosetta
|
||||
## simulator destinations), Intel Macs need x86_64.
|
||||
if(CMAKE_OSX_ARCHITECTURES)
|
||||
string(REPLACE ";" " " IOS_SIMULATOR_ARCHS "${CMAKE_OSX_ARCHITECTURES}")
|
||||
elseif(CMAKE_HOST_SYSTEM_PROCESSOR STREQUAL "arm64")
|
||||
set(IOS_SIMULATOR_ARCHS "arm64")
|
||||
else()
|
||||
set(IOS_SIMULATOR_ARCHS "x86_64")
|
||||
endif()
|
||||
|
||||
## Inspect all the targets, and add extra properties if necessary.
|
||||
while(IOS_TARGETS)
|
||||
list(POP_FRONT IOS_TARGETS TARGET_NAME)
|
||||
@@ -38,6 +49,6 @@ while(IOS_TARGETS)
|
||||
message("Patching architectures for ${TARGET_NAME}")
|
||||
set_target_properties(${TARGET_NAME} PROPERTIES
|
||||
XCODE_ATTRIBUTE_ARCHS[sdk=iphoneos*] "arm64"
|
||||
XCODE_ATTRIBUTE_ARCHS[sdk=iphonesimulator*] "x86_64"
|
||||
XCODE_ATTRIBUTE_ARCHS[sdk=iphonesimulator*] "${IOS_SIMULATOR_ARCHS}"
|
||||
)
|
||||
endwhile()
|
||||
@@ -64,25 +64,25 @@ target_include_directories(${PROJECT} PRIVATE ${Qt6Gui_PRIVATE_INCLUDE_DIRS})
|
||||
set_target_properties(${PROJECT} PROPERTIES
|
||||
MACOSX_BUNDLE_INFO_PLIST ${CMAKE_CURRENT_SOURCE_DIR}/ios/app/Info.plist.in
|
||||
MACOSX_BUNDLE_ICON_FILE "AppIcon"
|
||||
MACOSX_BUNDLE_INFO_STRING "AmneziaVPN"
|
||||
MACOSX_BUNDLE_BUNDLE_NAME "AmneziaVPN"
|
||||
MACOSX_BUNDLE_INFO_STRING "${CLIENT_APPLICATION_NAME}"
|
||||
MACOSX_BUNDLE_BUNDLE_NAME "${CLIENT_APPLICATION_NAME}"
|
||||
MACOSX_BUNDLE_GUI_IDENTIFIER "${BUILD_IOS_APP_IDENTIFIER}"
|
||||
MACOSX_BUNDLE_BUNDLE_VERSION "${CMAKE_PROJECT_VERSION_TWEAK}"
|
||||
MACOSX_BUNDLE_LONG_VERSION_STRING "${APPLE_PROJECT_VERSION}-${CMAKE_PROJECT_VERSION_TWEAK}"
|
||||
MACOSX_BUNDLE_SHORT_VERSION_STRING "${APPLE_PROJECT_VERSION}"
|
||||
XCODE_ATTRIBUTE_PRODUCT_BUNDLE_IDENTIFIER "${BUILD_IOS_APP_IDENTIFIER}"
|
||||
XCODE_ATTRIBUTE_CODE_SIGN_ENTITLEMENTS "${CMAKE_CURRENT_SOURCE_DIR}/ios/app/main.entitlements"
|
||||
XCODE_ATTRIBUTE_CODE_SIGN_ENTITLEMENTS "${CLIENT_IOS_APP_ENTITLEMENTS_PATH}"
|
||||
XCODE_ATTRIBUTE_MARKETING_VERSION "${APPLE_PROJECT_VERSION}"
|
||||
XCODE_ATTRIBUTE_CURRENT_PROJECT_VERSION "${CMAKE_PROJECT_VERSION_TWEAK}"
|
||||
XCODE_ATTRIBUTE_PRODUCT_NAME "AmneziaVPN"
|
||||
XCODE_ATTRIBUTE_BUNDLE_INFO_STRING "AmneziaVPN"
|
||||
XCODE_ATTRIBUTE_PRODUCT_NAME "${CLIENT_APPLICATION_NAME}"
|
||||
XCODE_ATTRIBUTE_BUNDLE_INFO_STRING "${CLIENT_APPLICATION_NAME}"
|
||||
XCODE_GENERATE_SCHEME TRUE
|
||||
XCODE_ATTRIBUTE_ASSETCATALOG_COMPILER_APPICON_NAME "AppIcon"
|
||||
XCODE_ATTRIBUTE_TARGETED_DEVICE_FAMILY "1,2"
|
||||
XCODE_EMBED_FRAMEWORKS_CODE_SIGN_ON_COPY ON
|
||||
XCODE_LINK_BUILD_PHASE_MODE KNOWN_LOCATION
|
||||
XCODE_ATTRIBUTE_LD_RUNPATH_SEARCH_PATHS "@executable_path/Frameworks"
|
||||
XCODE_EMBED_APP_EXTENSIONS networkextension
|
||||
XCODE_EMBED_APP_EXTENSIONS ${CLIENT_IOS_NE_TARGET_NAME}
|
||||
)
|
||||
|
||||
if(DEPLOY)
|
||||
@@ -90,8 +90,8 @@ if(DEPLOY)
|
||||
XCODE_ATTRIBUTE_CODE_SIGN_IDENTITY "Apple Distribution"
|
||||
XCODE_ATTRIBUTE_CODE_SIGN_IDENTITY[variant=Debug] "Apple Development"
|
||||
XCODE_ATTRIBUTE_CODE_SIGN_STYLE Manual
|
||||
XCODE_ATTRIBUTE_PROVISIONING_PROFILE_SPECIFIER "distr ios.org.amnezia.AmneziaVPN"
|
||||
XCODE_ATTRIBUTE_PROVISIONING_PROFILE_SPECIFIER[variant=Debug] "dev ios.org.amnezia.AmneziaVPN"
|
||||
XCODE_ATTRIBUTE_PROVISIONING_PROFILE_SPECIFIER "${CLIENT_IOS_PROVISIONING_PROFILE_SPECIFIER}"
|
||||
XCODE_ATTRIBUTE_PROVISIONING_PROFILE_SPECIFIER[variant=Debug] "${CLIENT_IOS_PROVISIONING_PROFILE_SPECIFIER_DEBUG}"
|
||||
)
|
||||
else()
|
||||
set_target_properties(${PROJECT} PROPERTIES
|
||||
@@ -103,11 +103,11 @@ set_target_properties(${PROJECT} PROPERTIES
|
||||
XCODE_ATTRIBUTE_SWIFT_VERSION "5.0"
|
||||
XCODE_ATTRIBUTE_CLANG_ENABLE_MODULES "YES"
|
||||
XCODE_ATTRIBUTE_SWIFT_PRECOMPILE_BRIDGING_HEADER "NO"
|
||||
XCODE_ATTRIBUTE_SWIFT_OBJC_INTERFACE_HEADER_NAME "AmneziaVPN-Swift.h"
|
||||
XCODE_ATTRIBUTE_SWIFT_OBJC_INTERFACE_HEADER_NAME "${CLIENT_SWIFT_OBJC_HEADER_NAME}"
|
||||
XCODE_ATTRIBUTE_SWIFT_OBJC_INTEROP_MODE "objcxx"
|
||||
)
|
||||
set_target_properties(${PROJECT} PROPERTIES
|
||||
XCODE_ATTRIBUTE_DEVELOPMENT_TEAM "X7UJ388FXK"
|
||||
XCODE_ATTRIBUTE_DEVELOPMENT_TEAM "${BUILD_VPN_DEVELOPMENT_TEAM}"
|
||||
)
|
||||
target_include_directories(${PROJECT} PRIVATE ${CMAKE_CURRENT_LIST_DIR})
|
||||
target_compile_options(${PROJECT} PRIVATE
|
||||
@@ -122,6 +122,7 @@ target_sources(${PROJECT} PRIVATE
|
||||
${WG_APPLE_SOURCE_DIR}/WireGuardKitC/x25519.c
|
||||
${CLIENT_ROOT_DIR}/platforms/ios/LogController.swift
|
||||
${CLIENT_ROOT_DIR}/platforms/ios/Log.swift
|
||||
${CLIENT_GROUP_IDENTIFIER_SWIFT_FILE}
|
||||
${CLIENT_ROOT_DIR}/platforms/ios/LogRecord.swift
|
||||
${CLIENT_ROOT_DIR}/platforms/ios/ScreenProtection.swift
|
||||
${CLIENT_ROOT_DIR}/platforms/ios/VPNCController.swift
|
||||
@@ -129,20 +130,20 @@ target_sources(${PROJECT} PRIVATE
|
||||
)
|
||||
|
||||
set_source_files_properties(
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/ios/app/Media.xcassets
|
||||
${CLIENT_IOS_MEDIA_ASSETS_PATH}
|
||||
PROPERTIES MACOSX_PACKAGE_LOCATION Resources
|
||||
)
|
||||
|
||||
target_sources(${PROJECT} PRIVATE
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/ios/app/AmneziaVPNLaunchScreen.storyboard
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/ios/app/Media.xcassets
|
||||
${CLIENT_IOS_LAUNCHSCREEN_PATH}
|
||||
${CLIENT_IOS_MEDIA_ASSETS_PATH}
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/ios/app/PrivacyInfo.xcprivacy
|
||||
)
|
||||
|
||||
set_property(TARGET ${PROJECT} APPEND PROPERTY RESOURCE
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/ios/app/AmneziaVPNLaunchScreen.storyboard
|
||||
${CLIENT_IOS_LAUNCHSCREEN_PATH}
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/ios/app/PrivacyInfo.xcprivacy
|
||||
)
|
||||
|
||||
add_subdirectory(ios/networkextension)
|
||||
add_dependencies(${PROJECT} networkextension)
|
||||
add_dependencies(${PROJECT} ${CLIENT_IOS_NE_TARGET_NAME})
|
||||
|
||||
@@ -34,8 +34,8 @@ set(SOURCES ${SOURCES}
|
||||
|
||||
|
||||
|
||||
set(ICON_FILE ${CMAKE_CURRENT_SOURCE_DIR}/images/app.icns)
|
||||
set(MACOSX_BUNDLE_ICON_FILE app.icns)
|
||||
set(ICON_FILE ${CLIENT_MACOS_APP_ICNS_PATH})
|
||||
get_filename_component(MACOSX_BUNDLE_ICON_FILE "${CLIENT_MACOS_APP_ICNS_PATH}" NAME)
|
||||
set_source_files_properties(${ICON_FILE} PROPERTIES MACOSX_PACKAGE_LOCATION Resources)
|
||||
set(SOURCES ${SOURCES} ${ICON_FILE})
|
||||
|
||||
|
||||
@@ -60,25 +60,25 @@ set_target_properties(${PROJECT} PROPERTIES
|
||||
XCODE_LINK_BUILD_PHASE_MODE KNOWN_LOCATION
|
||||
MACOSX_BUNDLE_INFO_PLIST ${CMAKE_CURRENT_SOURCE_DIR}/macos/app/Info.plist.in
|
||||
MACOSX_BUNDLE_ICON_FILE "AppIcon"
|
||||
MACOSX_BUNDLE_INFO_STRING "AmneziaVPN"
|
||||
MACOSX_BUNDLE_BUNDLE_NAME "AmneziaVPN"
|
||||
MACOSX_BUNDLE_INFO_STRING "${CLIENT_APPLICATION_NAME}"
|
||||
MACOSX_BUNDLE_BUNDLE_NAME "${CLIENT_APPLICATION_NAME}"
|
||||
MACOSX_BUNDLE_GUI_IDENTIFIER "${BUILD_IOS_APP_IDENTIFIER}"
|
||||
MACOSX_BUNDLE_BUNDLE_VERSION "${CMAKE_PROJECT_VERSION_TWEAK}"
|
||||
MACOSX_BUNDLE_LONG_VERSION_STRING "${APPLE_PROJECT_VERSION}-${CMAKE_PROJECT_VERSION_TWEAK}"
|
||||
MACOSX_BUNDLE_SHORT_VERSION_STRING "${APPLE_PROJECT_VERSION}"
|
||||
XCODE_ATTRIBUTE_PRODUCT_BUNDLE_IDENTIFIER "${BUILD_IOS_APP_IDENTIFIER}"
|
||||
XCODE_ATTRIBUTE_CODE_SIGN_ENTITLEMENTS "${CMAKE_CURRENT_SOURCE_DIR}/macos/app/app.entitlements"
|
||||
XCODE_ATTRIBUTE_CODE_SIGN_ENTITLEMENTS "${CLIENT_MACOS_APP_ENTITLEMENTS_PATH}"
|
||||
XCODE_ATTRIBUTE_MARKETING_VERSION "${APPLE_PROJECT_VERSION}"
|
||||
XCODE_ATTRIBUTE_CURRENT_PROJECT_VERSION "${CMAKE_PROJECT_VERSION_TWEAK}"
|
||||
XCODE_ATTRIBUTE_PRODUCT_NAME "AmneziaVPN"
|
||||
XCODE_ATTRIBUTE_BUNDLE_INFO_STRING "AmneziaVPN"
|
||||
XCODE_ATTRIBUTE_PRODUCT_NAME "${CLIENT_APPLICATION_NAME}"
|
||||
XCODE_ATTRIBUTE_BUNDLE_INFO_STRING "${CLIENT_APPLICATION_NAME}"
|
||||
XCODE_GENERATE_SCHEME TRUE
|
||||
XCODE_ATTRIBUTE_ASSETCATALOG_COMPILER_APPICON_NAME "AppIcon"
|
||||
XCODE_EMBED_FRAMEWORKS_CODE_SIGN_ON_COPY "NO"
|
||||
XCODE_EMBED_FRAMEWORKS_REMOVE_HEADERS_ON_COPY "YES"
|
||||
|
||||
XCODE_ATTRIBUTE_LD_RUNPATH_SEARCH_PATHS "@executable_path/../Frameworks"
|
||||
XCODE_EMBED_APP_EXTENSIONS AmneziaVPNNetworkExtension
|
||||
XCODE_EMBED_APP_EXTENSIONS ${CLIENT_MACOS_NE_TARGET_NAME}
|
||||
)
|
||||
|
||||
if(DEPLOY)
|
||||
@@ -86,8 +86,8 @@ if(DEPLOY)
|
||||
XCODE_ATTRIBUTE_CODE_SIGN_IDENTITY "Apple Distribution"
|
||||
XCODE_ATTRIBUTE_CODE_SIGN_IDENTITY[variant=Debug] "Apple Development"
|
||||
XCODE_ATTRIBUTE_CODE_SIGN_STYLE Manual
|
||||
XCODE_ATTRIBUTE_PROVISIONING_PROFILE_SPECIFIER "distr macos.org.amnezia.AmneziaVPN"
|
||||
XCODE_ATTRIBUTE_PROVISIONING_PROFILE_SPECIFIER[variant=Debug] "dev macos.org.amnezia.AmneziaVPN"
|
||||
XCODE_ATTRIBUTE_PROVISIONING_PROFILE_SPECIFIER "${CLIENT_MACOS_PROVISIONING_PROFILE_SPECIFIER}"
|
||||
XCODE_ATTRIBUTE_PROVISIONING_PROFILE_SPECIFIER[variant=Debug] "${CLIENT_MACOS_PROVISIONING_PROFILE_SPECIFIER_DEBUG}"
|
||||
)
|
||||
else()
|
||||
set_target_properties(${PROJECT} PROPERTIES
|
||||
@@ -99,11 +99,11 @@ set_target_properties(${PROJECT} PROPERTIES
|
||||
XCODE_ATTRIBUTE_SWIFT_VERSION "5.0"
|
||||
XCODE_ATTRIBUTE_CLANG_ENABLE_MODULES "YES"
|
||||
XCODE_ATTRIBUTE_SWIFT_PRECOMPILE_BRIDGING_HEADER "NO"
|
||||
XCODE_ATTRIBUTE_SWIFT_OBJC_INTERFACE_HEADER_NAME "AmneziaVPN-Swift.h"
|
||||
XCODE_ATTRIBUTE_SWIFT_OBJC_INTERFACE_HEADER_NAME "${CLIENT_SWIFT_OBJC_HEADER_NAME}"
|
||||
XCODE_ATTRIBUTE_SWIFT_OBJC_INTEROP_MODE "objcxx"
|
||||
)
|
||||
set_target_properties(${PROJECT} PROPERTIES
|
||||
XCODE_ATTRIBUTE_DEVELOPMENT_TEAM "X7UJ388FXK"
|
||||
XCODE_ATTRIBUTE_DEVELOPMENT_TEAM "${BUILD_VPN_DEVELOPMENT_TEAM}"
|
||||
)
|
||||
target_include_directories(${PROJECT} PRIVATE ${CMAKE_CURRENT_LIST_DIR})
|
||||
target_compile_options(${PROJECT} PRIVATE
|
||||
@@ -117,6 +117,7 @@ target_sources(${PROJECT} PRIVATE
|
||||
${WG_APPLE_SOURCE_DIR}/WireGuardKitC/x25519.c
|
||||
${CLIENT_ROOT_DIR}/platforms/ios/LogController.swift
|
||||
${CLIENT_ROOT_DIR}/platforms/ios/Log.swift
|
||||
${CLIENT_GROUP_IDENTIFIER_SWIFT_FILE}
|
||||
${CLIENT_ROOT_DIR}/platforms/ios/LogRecord.swift
|
||||
${CLIENT_ROOT_DIR}/platforms/ios/ScreenProtection.swift
|
||||
${CLIENT_ROOT_DIR}/platforms/ios/VPNCController.swift
|
||||
@@ -124,12 +125,12 @@ target_sources(${PROJECT} PRIVATE
|
||||
)
|
||||
|
||||
set_source_files_properties(
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/macos/app/Images.xcassets
|
||||
${CLIENT_MACOS_MEDIA_ASSETS_PATH}
|
||||
PROPERTIES MACOSX_PACKAGE_LOCATION Resources
|
||||
)
|
||||
|
||||
target_sources(${PROJECT} PRIVATE
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/macos/app/Images.xcassets
|
||||
${CLIENT_MACOS_MEDIA_ASSETS_PATH}
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/ios/app/PrivacyInfo.xcprivacy
|
||||
)
|
||||
|
||||
@@ -138,7 +139,7 @@ set_property(TARGET ${PROJECT} APPEND PROPERTY RESOURCE
|
||||
)
|
||||
|
||||
add_subdirectory(macos/networkextension)
|
||||
add_dependencies(${PROJECT} AmneziaVPNNetworkExtension)
|
||||
add_dependencies(${PROJECT} ${CLIENT_MACOS_NE_TARGET_NAME})
|
||||
|
||||
get_target_property(QtCore_location Qt6::Core LOCATION)
|
||||
message("QtCore_location")
|
||||
@@ -147,5 +148,5 @@ message(${QtCore_location})
|
||||
get_filename_component(QT_BIN_DIR_DETECTED "${QtCore_location}/../../../../../bin" ABSOLUTE)
|
||||
|
||||
add_custom_command(TARGET ${PROJECT} POST_BUILD
|
||||
COMMAND ${QT_BIN_DIR_DETECTED}/macdeployqt $<TARGET_BUNDLE_DIR:AmneziaVPN> -appstore-compliant -qmldir=${CMAKE_CURRENT_SOURCE_DIR} -no-codesign
|
||||
COMMAND ${QT_BIN_DIR_DETECTED}/macdeployqt $<TARGET_BUNDLE_DIR:${PROJECT}> -appstore-compliant -qmldir=${CMAKE_CURRENT_SOURCE_DIR} -no-codesign
|
||||
)
|
||||
|
||||
@@ -51,6 +51,7 @@ set(HEADERS ${HEADERS}
|
||||
${CLIENT_ROOT_DIR}/core/repositories/secureAppSettingsRepository.h
|
||||
${CLIENT_ROOT_DIR}/core/protocols/qmlRegisterProtocols.h
|
||||
${CLIENT_ROOT_DIR}/ui/utils/pages.h
|
||||
${CLIENT_PAGE_ENUM_HEADER}
|
||||
${CLIENT_ROOT_DIR}/ui/utils/qAutoStart.h
|
||||
${CLIENT_ROOT_DIR}/ui/utils/mtProxyPublicHostInput.h
|
||||
${CLIENT_ROOT_DIR}/core/protocols/vpnProtocol.h
|
||||
@@ -64,7 +65,9 @@ set(HEADERS ${HEADERS}
|
||||
${CLIENT_ROOT_DIR}/../common/crypto/cryptoUtils.h
|
||||
${CLIENT_ROOT_DIR}/ui/utils/qmlUtils.h
|
||||
${CLIENT_ROOT_DIR}/core/utils/api/apiUtils.h
|
||||
${CLIENT_ROOT_DIR}/core/utils/api/gatewayPayloadBuilder.h
|
||||
${CLIENT_ROOT_DIR}/core/utils/osSignalHandler.h
|
||||
${CLIENT_ROOT_DIR}/core/utils/swiftBridge.h
|
||||
${CLIENT_ROOT_DIR}/core/utils/utilities.h
|
||||
${CLIENT_ROOT_DIR}/core/utils/managementServer.h
|
||||
${CLIENT_ROOT_DIR}/core/utils/constants.h
|
||||
@@ -147,6 +150,7 @@ set(SOURCES ${SOURCES}
|
||||
${CLIENT_ROOT_DIR}/../common/crypto/cryptoUtils.cpp
|
||||
${CLIENT_ROOT_DIR}/ui/utils/qmlUtils.cpp
|
||||
${CLIENT_ROOT_DIR}/core/utils/api/apiUtils.cpp
|
||||
${CLIENT_ROOT_DIR}/core/utils/api/gatewayPayloadBuilder.cpp
|
||||
${CLIENT_ROOT_DIR}/core/utils/serverConfigUtils.cpp
|
||||
${CLIENT_ROOT_DIR}/core/utils/osSignalHandler.cpp
|
||||
${CLIENT_ROOT_DIR}/core/utils/utilities.cpp
|
||||
|
||||
@@ -106,6 +106,8 @@ ProtocolConfig AwgConfigurator::createConfig(const ServerCredentials &credential
|
||||
newClientConfig.rejectAfterTime = configMap.value(configKey::rejectAfterTime);
|
||||
newClientConfig.keepaliveTimeout = configMap.value(configKey::keepaliveTimeout);
|
||||
newClientConfig.maxHandshakeAttempts = configMap.value(configKey::maxHandshakeAttempts);
|
||||
newClientConfig.randomTrailers = configMap.value(configKey::randomTrailers);
|
||||
newClientConfig.disableCookies = configMap.value(configKey::disableCookies);
|
||||
|
||||
protocolConfig.setClientConfig(newClientConfig);
|
||||
|
||||
|
||||
@@ -228,8 +228,6 @@ ProtocolConfig WireguardConfigurator::createConfig(const ServerCredentials &cred
|
||||
}
|
||||
}
|
||||
|
||||
const bool isAwg3 = awgServerConfig && awgServerConfig->protocolVersion == protocols::awg::awgV3;
|
||||
|
||||
amnezia::ScriptVars vars = amnezia::genBaseVars(credentials, container, dnsSettings.primaryDns, dnsSettings.secondaryDns);
|
||||
vars.append(amnezia::genProtocolVarsForContainer(container, containerConfig));
|
||||
QString scriptData = amnezia::scriptData(m_configTemplate, container);
|
||||
@@ -275,8 +273,9 @@ ProtocolConfig WireguardConfigurator::createConfig(const ServerCredentials &cred
|
||||
clientConfig.presharedKey = connData.pskKey;
|
||||
clientConfig.clientId = connData.clientPubKey;
|
||||
clientConfig.allowedIps = QStringList { "0.0.0.0/0", "::/0" };
|
||||
clientConfig.persistentKeepAlive = isAwg3 ? protocols::awg::defaultPersistentKeepAlive
|
||||
: protocols::wireguard::defaultPersistentKeepAlive;
|
||||
const bool useKeepAliveRange = awgServerConfig && awgServerConfig->hasAwg3Params();
|
||||
clientConfig.persistentKeepAlive = useKeepAliveRange ? protocols::awg::defaultPersistentKeepAlive
|
||||
: protocols::wireguard::defaultPersistentKeepAlive;
|
||||
clientConfig.mtu = mtu;
|
||||
clientConfig.isObfuscationEnabled = false;
|
||||
|
||||
|
||||
@@ -211,33 +211,6 @@ ErrorCode XrayConfigurator::readRealityKeyFiles(const DockerContainer container,
|
||||
return readKeyFile(QString::fromLatin1(amnezia::protocols::xray::shortidPath), outShortId);
|
||||
}
|
||||
|
||||
QJsonObject XrayConfigurator::mergeStreamSettingsForServerInbound(const XrayServerConfig &srv,
|
||||
const QJsonObject &existingStreamSettings) const
|
||||
{
|
||||
QJsonObject streamSettings = buildStreamSettings(srv, QString());
|
||||
|
||||
if (effectiveSecurity(srv) != QLatin1String("reality")) {
|
||||
return streamSettings;
|
||||
}
|
||||
|
||||
const QJsonObject newRs = streamSettings[amnezia::protocols::xray::realitySettings].toObject();
|
||||
QJsonObject oldRs = existingStreamSettings[amnezia::protocols::xray::realitySettings].toObject();
|
||||
QJsonObject merged = oldRs.isEmpty() ? newRs : oldRs;
|
||||
|
||||
const QString siteEff = srv.site.isEmpty() ? QString::fromLatin1(amnezia::protocols::xray::defaultSite) : srv.site;
|
||||
const QString sniEff = srv.sni.isEmpty() ? siteEff : srv.sni;
|
||||
|
||||
if (newRs.contains(amnezia::protocols::xray::fingerprint)) {
|
||||
merged[amnezia::protocols::xray::fingerprint] = newRs[amnezia::protocols::xray::fingerprint];
|
||||
}
|
||||
merged[amnezia::protocols::xray::serverNames] = QJsonArray { sniEff };
|
||||
if (!merged.contains(QStringLiteral("dest"))) {
|
||||
merged[QStringLiteral("dest")] = siteEff + QStringLiteral(":443");
|
||||
}
|
||||
|
||||
streamSettings[amnezia::protocols::xray::realitySettings] = merged;
|
||||
return streamSettings;
|
||||
}
|
||||
|
||||
ErrorCode XrayConfigurator::applyServerSettingsToRemote(const ServerCredentials &credentials, DockerContainer container,
|
||||
ContainerConfig &containerConfig, const DnsSettings &dnsSettings,
|
||||
@@ -308,13 +281,6 @@ ErrorCode XrayConfigurator::applyServerSettingsToRemote(const ServerCredentials
|
||||
return ErrorCode::XrayServerConfigInvalid;
|
||||
}
|
||||
|
||||
const QJsonObject existingStream = inbound[amnezia::protocols::xray::streamSettings].toObject();
|
||||
inbound[amnezia::protocols::xray::streamSettings] = mergeStreamSettingsForServerInbound(srv, existingStream);
|
||||
|
||||
if (!srv.port.isEmpty()) {
|
||||
inbound[amnezia::protocols::xray::port] = srv.port.toInt();
|
||||
}
|
||||
|
||||
QJsonObject settings = inbound[amnezia::protocols::xray::settings].toObject();
|
||||
if (!settings.contains(amnezia::protocols::xray::clients)) {
|
||||
settings[amnezia::protocols::xray::clients] = QJsonArray {};
|
||||
|
||||
@@ -60,9 +60,6 @@ private:
|
||||
QString &outPublicKey,
|
||||
QString &outShortId) const;
|
||||
|
||||
QJsonObject mergeStreamSettingsForServerInbound(const amnezia::XrayServerConfig &srv,
|
||||
const QJsonObject &existingStreamSettings) const;
|
||||
|
||||
QJsonObject buildStreamSettings(const amnezia::XrayServerConfig &srv,
|
||||
const QString &clientId) const;
|
||||
};
|
||||
|
||||
@@ -2,6 +2,8 @@
|
||||
|
||||
#include "core/controllers/gatewayController.h"
|
||||
#include "core/repositories/secureServersRepository.h"
|
||||
#include "core/utils/api/apiUtils.h"
|
||||
#include "core/utils/api/gatewayPayloadBuilder.h"
|
||||
#include "core/utils/constants/apiKeys.h"
|
||||
#include "core/utils/constants/apiConstants.h"
|
||||
#include <QtConcurrent/QtConcurrent>
|
||||
@@ -81,15 +83,12 @@ QFuture<QPair<ErrorCode, QJsonArray>> NewsController::fetchNews()
|
||||
m_appSettingsRepository->isStrictKillSwitchEnabled(),
|
||||
m_appSettingsRepository);
|
||||
|
||||
QJsonObject payload;
|
||||
payload.insert("locale", m_appSettingsRepository->getAppLanguage().name().split("_").first());
|
||||
|
||||
if (services.contains(apiDefs::key::userCountryCode)) {
|
||||
payload.insert(apiDefs::key::userCountryCode, services.value(apiDefs::key::userCountryCode));
|
||||
}
|
||||
if (services.contains(apiDefs::key::serviceType)) {
|
||||
payload.insert(apiDefs::key::serviceType, services.value(apiDefs::key::serviceType));
|
||||
}
|
||||
// both country codes and service types are arrays here, one entry per gateway stack the user has
|
||||
const QJsonObject payload = GatewayPayloadBuilder(m_appSettingsRepository)
|
||||
.addField(apiDefs::key::locale, apiUtils::getAppLanguageCode(m_appSettingsRepository))
|
||||
.addField(apiDefs::key::userCountryCode, services.value(apiDefs::key::userCountryCode))
|
||||
.addField(apiDefs::key::serviceType, services.value(apiDefs::key::serviceType))
|
||||
.build();
|
||||
|
||||
auto future = gatewayController->postAsync(QString("%1v1/news"), payload);
|
||||
return future.then([gatewayController](QPair<ErrorCode, QByteArray> result) -> QPair<ErrorCode, QJsonArray> {
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
#include "servicesCatalogController.h"
|
||||
|
||||
#include <QJsonDocument>
|
||||
#include <QSysInfo>
|
||||
#include <QJsonArray>
|
||||
#include <QEventLoop>
|
||||
#include <QDebug>
|
||||
@@ -11,6 +10,7 @@
|
||||
#include <limits>
|
||||
|
||||
#include "core/controllers/gatewayController.h"
|
||||
#include "core/utils/api/gatewayPayloadBuilder.h"
|
||||
#include "core/utils/serverConfigUtils.h"
|
||||
#include "core/utils/constants/apiKeys.h"
|
||||
#include "core/utils/constants/apiConstants.h"
|
||||
@@ -212,11 +212,7 @@ ServicesCatalogController::ServicesCatalogController(SecureAppSettingsRepository
|
||||
|
||||
ErrorCode ServicesCatalogController::fillAvailableServices(QJsonObject &servicesData)
|
||||
{
|
||||
QJsonObject apiPayload;
|
||||
apiPayload[apiDefs::key::osVersion] = QSysInfo::productType();
|
||||
apiPayload[apiDefs::key::appVersion] = QString(APP_VERSION);
|
||||
apiPayload[apiDefs::key::cliName] = QString(APPLICATION_NAME);
|
||||
apiPayload[apiDefs::key::appLanguage] = m_appSettingsRepository->getAppLanguage().name().split("_").first();
|
||||
QJsonObject apiPayload = GatewayPayloadBuilder(m_appSettingsRepository).build();
|
||||
|
||||
QByteArray responseBody;
|
||||
ErrorCode errorCode = executeRequest(QString("%1v1/services"), apiPayload, responseBody);
|
||||
|
||||
@@ -8,7 +8,6 @@
|
||||
#include <QJsonObject>
|
||||
#include <QPromise>
|
||||
#include <QSet>
|
||||
#include <QSysInfo>
|
||||
#include <QUuid>
|
||||
#include <QVariantMap>
|
||||
|
||||
@@ -21,6 +20,7 @@
|
||||
#include "core/utils/constants/apiKeys.h"
|
||||
#include "core/utils/constants/apiConstants.h"
|
||||
#include "core/utils/api/apiUtils.h"
|
||||
#include "core/utils/api/gatewayPayloadBuilder.h"
|
||||
#include "core/controllers/gatewayController.h"
|
||||
#include "core/utils/protocolEnum.h"
|
||||
#include "core/protocols/protocolUtils.h"
|
||||
@@ -32,7 +32,7 @@
|
||||
|
||||
#if defined(Q_OS_IOS) || defined(MACOS_NE)
|
||||
#include "platforms/ios/ios_controller.h"
|
||||
#include <AmneziaVPN-Swift.h>
|
||||
#include "core/utils/swiftBridge.h"
|
||||
#endif
|
||||
|
||||
using namespace amnezia;
|
||||
@@ -97,39 +97,6 @@ SubscriptionController::SubscriptionController(SecureServersRepository* serversR
|
||||
{
|
||||
}
|
||||
|
||||
QJsonObject SubscriptionController::GatewayRequestData::toJsonObject() const
|
||||
{
|
||||
QJsonObject obj;
|
||||
if (!osVersion.isEmpty()) {
|
||||
obj[apiDefs::key::osVersion] = osVersion;
|
||||
}
|
||||
if (!appVersion.isEmpty()) {
|
||||
obj[apiDefs::key::appVersion] = appVersion;
|
||||
}
|
||||
if (!appLanguage.isEmpty()) {
|
||||
obj[apiDefs::key::appLanguage] = appLanguage;
|
||||
}
|
||||
if (!installationUuid.isEmpty()) {
|
||||
obj[apiDefs::key::uuid] = installationUuid;
|
||||
}
|
||||
if (!userCountryCode.isEmpty()) {
|
||||
obj[apiDefs::key::userCountryCode] = userCountryCode;
|
||||
}
|
||||
if (!serverCountryCode.isEmpty()) {
|
||||
obj[apiDefs::key::serverCountryCode] = serverCountryCode;
|
||||
}
|
||||
if (!serviceType.isEmpty()) {
|
||||
obj[apiDefs::key::serviceType] = serviceType;
|
||||
}
|
||||
if (!serviceProtocol.isEmpty()) {
|
||||
obj[apiDefs::key::serviceProtocol] = serviceProtocol;
|
||||
}
|
||||
if (!authData.isEmpty()) {
|
||||
obj[apiDefs::key::authData] = authData;
|
||||
}
|
||||
return obj;
|
||||
}
|
||||
|
||||
SubscriptionController::ProtocolData SubscriptionController::generateProtocolData(const QString &protocol)
|
||||
{
|
||||
ProtocolData protocolData;
|
||||
@@ -144,13 +111,15 @@ SubscriptionController::ProtocolData SubscriptionController::generateProtocolDat
|
||||
return protocolData;
|
||||
}
|
||||
|
||||
void SubscriptionController::appendProtocolDataToApiPayload(const QString &protocol, const ProtocolData &protocolData, QJsonObject &apiPayload)
|
||||
QString SubscriptionController::publicKeyForProtocol(const QString &protocol, const ProtocolData &protocolData)
|
||||
{
|
||||
if (protocol == configKey::awg) {
|
||||
apiPayload[apiDefs::key::publicKey] = protocolData.wireGuardClientPubKey;
|
||||
} else if (protocol == configKey::vless) {
|
||||
apiPayload[apiDefs::key::publicKey] = protocolData.xrayUuid;
|
||||
return protocolData.wireGuardClientPubKey;
|
||||
}
|
||||
if (protocol == configKey::vless) {
|
||||
return protocolData.xrayUuid;
|
||||
}
|
||||
return {};
|
||||
}
|
||||
|
||||
ErrorCode SubscriptionController::extractServerConfigJsonFromResponse(const QByteArray &apiResponseBody, const QString &protocol,
|
||||
@@ -240,18 +209,12 @@ ErrorCode SubscriptionController::importServiceFromGateway(const QString &userCo
|
||||
const QString &serviceProtocol, const ProtocolData &protocolData,
|
||||
CaptchaInfo &captchaInfo)
|
||||
{
|
||||
GatewayRequestData gatewayRequestData { QSysInfo::productType(),
|
||||
QString(APP_VERSION),
|
||||
m_appSettingsRepository->getAppLanguage().name().split("_").first(),
|
||||
m_appSettingsRepository->getInstallationUuid(true),
|
||||
userCountryCode,
|
||||
"",
|
||||
serviceType,
|
||||
serviceProtocol,
|
||||
QJsonObject() };
|
||||
|
||||
QJsonObject apiPayload = gatewayRequestData.toJsonObject();
|
||||
appendProtocolDataToApiPayload(serviceProtocol, protocolData, apiPayload);
|
||||
QJsonObject apiPayload = GatewayPayloadBuilder(m_appSettingsRepository)
|
||||
.addField(apiDefs::key::userCountryCode, userCountryCode)
|
||||
.addField(apiDefs::key::serviceType, serviceType)
|
||||
.addField(apiDefs::key::serviceProtocol, serviceProtocol)
|
||||
.addField(apiDefs::key::publicKey, publicKeyForProtocol(serviceProtocol, protocolData))
|
||||
.build();
|
||||
|
||||
QByteArray responseBody;
|
||||
ErrorCode errorCode = executeRequest(QString("%1v1/config"), apiPayload, responseBody);
|
||||
@@ -291,20 +254,15 @@ ErrorCode SubscriptionController::importTrialFromGateway(const QString &userCoun
|
||||
return ErrorCode::ApiConfigEmptyError;
|
||||
}
|
||||
|
||||
GatewayRequestData gatewayRequestData { QSysInfo::productType(),
|
||||
QString(APP_VERSION),
|
||||
m_appSettingsRepository->getAppLanguage().name().split("_").first(),
|
||||
m_appSettingsRepository->getInstallationUuid(true),
|
||||
userCountryCode,
|
||||
"",
|
||||
serviceType,
|
||||
serviceProtocol,
|
||||
QJsonObject() };
|
||||
|
||||
ProtocolData protocolData = generateProtocolData(serviceProtocol);
|
||||
QJsonObject apiPayload = gatewayRequestData.toJsonObject();
|
||||
appendProtocolDataToApiPayload(serviceProtocol, protocolData, apiPayload);
|
||||
apiPayload.insert(apiDefs::key::email, trimmedEmail);
|
||||
|
||||
QJsonObject apiPayload = GatewayPayloadBuilder(m_appSettingsRepository)
|
||||
.addField(apiDefs::key::userCountryCode, userCountryCode)
|
||||
.addField(apiDefs::key::serviceType, serviceType)
|
||||
.addField(apiDefs::key::serviceProtocol, serviceProtocol)
|
||||
.addField(apiDefs::key::publicKey, publicKeyForProtocol(serviceProtocol, protocolData))
|
||||
.addField(apiDefs::key::email, trimmedEmail)
|
||||
.build();
|
||||
|
||||
QByteArray responseBody;
|
||||
ErrorCode errorCode = executeRequest(QString("%1v1/trial"), apiPayload, responseBody);
|
||||
@@ -345,19 +303,13 @@ ErrorCode SubscriptionController::importServiceFromAppStore(const QString &userC
|
||||
const QString &transactionId, bool isTestPurchase,
|
||||
int *duplicateServerIndex)
|
||||
{
|
||||
GatewayRequestData gatewayRequestData { QSysInfo::productType(),
|
||||
QString(APP_VERSION),
|
||||
m_appSettingsRepository->getAppLanguage().name().split("_").first(),
|
||||
m_appSettingsRepository->getInstallationUuid(true),
|
||||
userCountryCode,
|
||||
"",
|
||||
serviceType,
|
||||
serviceProtocol,
|
||||
QJsonObject() };
|
||||
|
||||
QJsonObject apiPayload = gatewayRequestData.toJsonObject();
|
||||
appendProtocolDataToApiPayload(serviceProtocol, protocolData, apiPayload);
|
||||
apiPayload[apiDefs::key::transactionId] = transactionId;
|
||||
QJsonObject apiPayload = GatewayPayloadBuilder(m_appSettingsRepository)
|
||||
.addField(apiDefs::key::userCountryCode, userCountryCode)
|
||||
.addField(apiDefs::key::serviceType, serviceType)
|
||||
.addField(apiDefs::key::serviceProtocol, serviceProtocol)
|
||||
.addField(apiDefs::key::publicKey, publicKeyForProtocol(serviceProtocol, protocolData))
|
||||
.addField(apiDefs::key::transactionId, transactionId)
|
||||
.build();
|
||||
|
||||
QByteArray responseBody;
|
||||
ErrorCode errorCode = executeRequest(QString("%1v1/subscriptions"), apiPayload, responseBody, isTestPurchase);
|
||||
@@ -412,8 +364,6 @@ ErrorCode SubscriptionController::importServiceFromAppStore(const QString &userC
|
||||
ApiV2ServerConfig apiV2ServerConfig = ApiV2ServerConfig::fromJson(configObject);
|
||||
ApiV2ServerConfig* apiV2 = &apiV2ServerConfig;
|
||||
apiV2->apiConfig.vpnKey = normalizedKey;
|
||||
apiV2->apiConfig.isTestPurchase = isTestPurchase;
|
||||
apiV2->apiConfig.isInAppPurchase = true;
|
||||
apiV2->apiConfig.subscriptionExpiredByServer = false;
|
||||
apiV2->crc = crc;
|
||||
|
||||
@@ -451,23 +401,15 @@ ErrorCode SubscriptionController::updateServiceFromGateway(const QString &server
|
||||
|
||||
ProtocolData protocolData = generateProtocolData(serviceProtocol);
|
||||
|
||||
QJsonObject authDataJson = apiV2->authData.toJson();
|
||||
GatewayRequestData gatewayRequestData { QSysInfo::productType(),
|
||||
QString(APP_VERSION),
|
||||
m_appSettingsRepository->getAppLanguage().name().split("_").first(),
|
||||
m_appSettingsRepository->getInstallationUuid(true),
|
||||
apiV2->apiConfig.userCountryCode,
|
||||
newCountryCode,
|
||||
apiV2->serviceType(),
|
||||
serviceProtocol,
|
||||
authDataJson };
|
||||
|
||||
QJsonObject apiPayload = gatewayRequestData.toJsonObject();
|
||||
appendProtocolDataToApiPayload(serviceProtocol, protocolData, apiPayload);
|
||||
|
||||
if (isConnectEvent) {
|
||||
apiPayload[apiDefs::key::isConnectEvent] = true;
|
||||
}
|
||||
QJsonObject apiPayload = GatewayPayloadBuilder(m_appSettingsRepository)
|
||||
.addField(apiDefs::key::userCountryCode, apiV2->apiConfig.userCountryCode)
|
||||
.addField(apiDefs::key::serverCountryCode, newCountryCode)
|
||||
.addField(apiDefs::key::serviceType, apiV2->serviceType())
|
||||
.addField(apiDefs::key::serviceProtocol, serviceProtocol)
|
||||
.addField(apiDefs::key::publicKey, publicKeyForProtocol(serviceProtocol, protocolData))
|
||||
.addField(apiDefs::key::authData, apiV2->authData.toJson())
|
||||
.addField(apiDefs::key::isConnectEvent, isConnectEvent ? QJsonValue(true) : QJsonValue())
|
||||
.build();
|
||||
|
||||
QByteArray responseBody;
|
||||
ErrorCode errorCode = executeRequest(QString("%1v1/config"), apiPayload, responseBody, isTestPurchase);
|
||||
@@ -513,8 +455,6 @@ ErrorCode SubscriptionController::applyUpdatedServiceConfig(const QString &serve
|
||||
ApiV2ServerConfig* newApiV2 = &newApiV2Config;
|
||||
|
||||
newApiV2->apiConfig.vpnKey = apiV2->apiConfig.vpnKey;
|
||||
newApiV2->apiConfig.isTestPurchase = apiV2->apiConfig.isTestPurchase;
|
||||
newApiV2->apiConfig.isInAppPurchase = apiV2->apiConfig.isInAppPurchase;
|
||||
newApiV2->apiConfig.subscriptionExpiredByServer = false;
|
||||
|
||||
newApiV2->authData = apiV2->authData;
|
||||
@@ -543,26 +483,17 @@ ErrorCode SubscriptionController::resolveUpdateServiceCaptcha(const QString &ser
|
||||
const bool isTestPurchase = apiV2->apiConfig.isTestPurchase;
|
||||
QString serviceProtocol = apiV2->serviceProtocol();
|
||||
|
||||
QJsonObject authDataJson = apiV2->authData.toJson();
|
||||
GatewayRequestData gatewayRequestData { QSysInfo::productType(),
|
||||
QString(APP_VERSION),
|
||||
m_appSettingsRepository->getAppLanguage().name().split("_").first(),
|
||||
m_appSettingsRepository->getInstallationUuid(true),
|
||||
apiV2->apiConfig.userCountryCode,
|
||||
newCountryCode,
|
||||
apiV2->serviceType(),
|
||||
serviceProtocol,
|
||||
authDataJson };
|
||||
|
||||
QJsonObject apiPayload = gatewayRequestData.toJsonObject();
|
||||
appendProtocolDataToApiPayload(serviceProtocol, protocolData, apiPayload);
|
||||
|
||||
if (isConnectEvent) {
|
||||
apiPayload[apiDefs::key::isConnectEvent] = true;
|
||||
}
|
||||
|
||||
apiPayload["captcha_id"] = captchaId;
|
||||
apiPayload["captcha_solution"] = normalizeCaptchaSolution(captchaSolution);
|
||||
QJsonObject apiPayload = GatewayPayloadBuilder(m_appSettingsRepository)
|
||||
.addField(apiDefs::key::userCountryCode, apiV2->apiConfig.userCountryCode)
|
||||
.addField(apiDefs::key::serverCountryCode, newCountryCode)
|
||||
.addField(apiDefs::key::serviceType, apiV2->serviceType())
|
||||
.addField(apiDefs::key::serviceProtocol, serviceProtocol)
|
||||
.addField(apiDefs::key::publicKey, publicKeyForProtocol(serviceProtocol, protocolData))
|
||||
.addField(apiDefs::key::authData, apiV2->authData.toJson())
|
||||
.addField(apiDefs::key::captchaId, captchaId)
|
||||
.addField(apiDefs::key::captchaSolution, normalizeCaptchaSolution(captchaSolution))
|
||||
.addField(apiDefs::key::isConnectEvent, isConnectEvent ? QJsonValue(true) : QJsonValue())
|
||||
.build();
|
||||
|
||||
QByteArray responseBody;
|
||||
ErrorCode errorCode = executeRequest(QString("%1v1/config"), apiPayload, responseBody, isTestPurchase);
|
||||
@@ -595,18 +526,12 @@ ErrorCode SubscriptionController::deactivateDevice(const QString &serverId)
|
||||
return ErrorCode::NoError;
|
||||
}
|
||||
|
||||
QJsonObject authDataJson = apiV2->authData.toJson();
|
||||
GatewayRequestData gatewayRequestData { QSysInfo::productType(),
|
||||
QString(APP_VERSION),
|
||||
m_appSettingsRepository->getAppLanguage().name().split("_").first(),
|
||||
m_appSettingsRepository->getInstallationUuid(true),
|
||||
apiV2->apiConfig.userCountryCode,
|
||||
apiV2->apiConfig.serverCountryCode,
|
||||
apiV2->serviceType(),
|
||||
"",
|
||||
authDataJson };
|
||||
|
||||
QJsonObject apiPayload = gatewayRequestData.toJsonObject();
|
||||
QJsonObject apiPayload = GatewayPayloadBuilder(m_appSettingsRepository)
|
||||
.addField(apiDefs::key::userCountryCode, apiV2->apiConfig.userCountryCode)
|
||||
.addField(apiDefs::key::serverCountryCode, apiV2->apiConfig.serverCountryCode)
|
||||
.addField(apiDefs::key::serviceType, apiV2->serviceType())
|
||||
.addField(apiDefs::key::authData, apiV2->authData.toJson())
|
||||
.build();
|
||||
|
||||
const bool isTestPurchase = apiV2->apiConfig.isTestPurchase;
|
||||
QByteArray responseBody;
|
||||
@@ -632,18 +557,13 @@ ErrorCode SubscriptionController::deactivateExternalDevice(const QString &server
|
||||
return ErrorCode::NoError;
|
||||
}
|
||||
|
||||
QJsonObject authDataJson = apiV2->authData.toJson();
|
||||
GatewayRequestData gatewayRequestData { QSysInfo::productType(),
|
||||
QString(APP_VERSION),
|
||||
m_appSettingsRepository->getAppLanguage().name().split("_").first(),
|
||||
uuid,
|
||||
apiV2->apiConfig.userCountryCode,
|
||||
serverCountryCode,
|
||||
apiV2->serviceType(),
|
||||
"",
|
||||
authDataJson };
|
||||
|
||||
QJsonObject apiPayload = gatewayRequestData.toJsonObject();
|
||||
QJsonObject apiPayload = GatewayPayloadBuilder(m_appSettingsRepository)
|
||||
.addField(apiDefs::key::installationUuid, uuid)
|
||||
.addField(apiDefs::key::userCountryCode, apiV2->apiConfig.userCountryCode)
|
||||
.addField(apiDefs::key::serverCountryCode, serverCountryCode)
|
||||
.addField(apiDefs::key::serviceType, apiV2->serviceType())
|
||||
.addField(apiDefs::key::authData, apiV2->authData.toJson())
|
||||
.build();
|
||||
|
||||
const bool isTestPurchase = apiV2->apiConfig.isTestPurchase;
|
||||
QByteArray responseBody;
|
||||
@@ -671,19 +591,14 @@ ErrorCode SubscriptionController::exportNativeConfig(const QString &serverId, co
|
||||
QString protocol = configKey::awg;
|
||||
ProtocolData protocolData = generateProtocolData(protocol);
|
||||
|
||||
QJsonObject authDataJson = apiV2->authData.toJson();
|
||||
GatewayRequestData gatewayRequestData { QSysInfo::productType(),
|
||||
QString(APP_VERSION),
|
||||
m_appSettingsRepository->getAppLanguage().name().split("_").first(),
|
||||
m_appSettingsRepository->getInstallationUuid(true),
|
||||
apiV2->apiConfig.userCountryCode,
|
||||
serverCountryCode,
|
||||
apiV2->serviceType(),
|
||||
protocol,
|
||||
authDataJson };
|
||||
|
||||
QJsonObject apiPayload = gatewayRequestData.toJsonObject();
|
||||
appendProtocolDataToApiPayload(protocol, protocolData, apiPayload);
|
||||
QJsonObject apiPayload = GatewayPayloadBuilder(m_appSettingsRepository)
|
||||
.addField(apiDefs::key::userCountryCode, apiV2->apiConfig.userCountryCode)
|
||||
.addField(apiDefs::key::serverCountryCode, serverCountryCode)
|
||||
.addField(apiDefs::key::serviceType, apiV2->serviceType())
|
||||
.addField(apiDefs::key::serviceProtocol, protocol)
|
||||
.addField(apiDefs::key::publicKey, publicKeyForProtocol(protocol, protocolData))
|
||||
.addField(apiDefs::key::authData, apiV2->authData.toJson())
|
||||
.build();
|
||||
|
||||
QByteArray responseBody;
|
||||
ErrorCode errorCode = executeRequest(QString("%1v1/native_config"), apiPayload, responseBody, isTestPurchase);
|
||||
@@ -706,18 +621,13 @@ ErrorCode SubscriptionController::revokeNativeConfig(const QString &serverId, co
|
||||
const bool isTestPurchase = apiV2->apiConfig.isTestPurchase;
|
||||
QString protocol = configKey::awg;
|
||||
|
||||
QJsonObject authDataJson = apiV2->authData.toJson();
|
||||
GatewayRequestData gatewayRequestData { QSysInfo::productType(),
|
||||
QString(APP_VERSION),
|
||||
m_appSettingsRepository->getAppLanguage().name().split("_").first(),
|
||||
m_appSettingsRepository->getInstallationUuid(true),
|
||||
apiV2->apiConfig.userCountryCode,
|
||||
serverCountryCode,
|
||||
apiV2->serviceType(),
|
||||
protocol,
|
||||
authDataJson };
|
||||
|
||||
QJsonObject apiPayload = gatewayRequestData.toJsonObject();
|
||||
QJsonObject apiPayload = GatewayPayloadBuilder(m_appSettingsRepository)
|
||||
.addField(apiDefs::key::userCountryCode, apiV2->apiConfig.userCountryCode)
|
||||
.addField(apiDefs::key::serverCountryCode, serverCountryCode)
|
||||
.addField(apiDefs::key::serviceType, apiV2->serviceType())
|
||||
.addField(apiDefs::key::serviceProtocol, protocol)
|
||||
.addField(apiDefs::key::authData, apiV2->authData.toJson())
|
||||
.build();
|
||||
|
||||
QByteArray responseBody;
|
||||
ErrorCode errorCode = executeRequest(QString("%1v1/revoke_native_config"), apiPayload, responseBody, isTestPurchase);
|
||||
@@ -782,7 +692,7 @@ void SubscriptionController::removeApiConfig(const QString &serverId)
|
||||
.arg(hostName)
|
||||
.arg("");
|
||||
|
||||
AmneziaVPN::removeVPNC(vpncName.toStdString());
|
||||
SWIFT_BRIDGE_NAMESPACE::removeVPNC(vpncName.toStdString());
|
||||
#endif
|
||||
|
||||
apiV2->dns1.clear();
|
||||
@@ -1024,20 +934,13 @@ ErrorCode SubscriptionController::getAccountInfo(const QString &serverId, QJsonO
|
||||
}
|
||||
bool isTestPurchase = apiV2->apiConfig.isTestPurchase;
|
||||
|
||||
QJsonObject authDataJson = apiV2->authData.toJson();
|
||||
GatewayRequestData gatewayRequestData { QSysInfo::productType(),
|
||||
QString(APP_VERSION),
|
||||
m_appSettingsRepository->getAppLanguage().name().split("_").first(),
|
||||
m_appSettingsRepository->getInstallationUuid(true),
|
||||
apiV2->apiConfig.userCountryCode,
|
||||
"",
|
||||
apiV2->serviceType(),
|
||||
"",
|
||||
authDataJson };
|
||||
|
||||
QJsonObject apiPayload = gatewayRequestData.toJsonObject();
|
||||
apiPayload[apiDefs::key::cliVersion] = QString(APP_VERSION);
|
||||
apiPayload[apiDefs::key::subscriptionStatus] = getSubscriptionStatusForRenewal(apiV2->apiConfig);
|
||||
QJsonObject apiPayload = GatewayPayloadBuilder(m_appSettingsRepository)
|
||||
.addField(apiDefs::key::userCountryCode, apiV2->apiConfig.userCountryCode)
|
||||
.addField(apiDefs::key::serviceType, apiV2->serviceType())
|
||||
.addField(apiDefs::key::authData, apiV2->authData.toJson())
|
||||
.addField(apiDefs::key::cliVersion, QString(APP_VERSION))
|
||||
.addField(apiDefs::key::subscriptionStatus, getSubscriptionStatusForRenewal(apiV2->apiConfig))
|
||||
.build();
|
||||
|
||||
QByteArray responseBody;
|
||||
ErrorCode errorCode = executeRequest(QString("%1v1/account_info"), apiPayload, responseBody, isTestPurchase);
|
||||
@@ -1045,7 +948,8 @@ ErrorCode SubscriptionController::getAccountInfo(const QString &serverId, QJsonO
|
||||
return errorCode;
|
||||
}
|
||||
|
||||
accountInfo = QJsonDocument::fromJson(responseBody).object();
|
||||
accountInfo = QJsonDocument::fromJson(responseBody).object();
|
||||
|
||||
return ErrorCode::NoError;
|
||||
}
|
||||
|
||||
@@ -1062,20 +966,13 @@ QFuture<QPair<ErrorCode, QString>> SubscriptionController::getRenewalLink(const
|
||||
}
|
||||
|
||||
bool isTestPurchase = apiV2->apiConfig.isTestPurchase;
|
||||
QJsonObject authDataJson = apiV2->authData.toJson();
|
||||
GatewayRequestData gatewayRequestData { QSysInfo::productType(),
|
||||
QString(APP_VERSION),
|
||||
m_appSettingsRepository->getAppLanguage().name().split("_").first(),
|
||||
m_appSettingsRepository->getInstallationUuid(true),
|
||||
apiV2->apiConfig.userCountryCode,
|
||||
"",
|
||||
apiV2->serviceType(),
|
||||
"",
|
||||
authDataJson };
|
||||
|
||||
QJsonObject apiPayload = gatewayRequestData.toJsonObject();
|
||||
apiPayload[apiDefs::key::cliVersion] = QString(APP_VERSION);
|
||||
apiPayload[apiDefs::key::subscriptionStatus] = getSubscriptionStatusForRenewal(apiV2->apiConfig);
|
||||
QJsonObject apiPayload = GatewayPayloadBuilder(m_appSettingsRepository)
|
||||
.addField(apiDefs::key::userCountryCode, apiV2->apiConfig.userCountryCode)
|
||||
.addField(apiDefs::key::serviceType, apiV2->serviceType())
|
||||
.addField(apiDefs::key::authData, apiV2->authData.toJson())
|
||||
.addField(apiDefs::key::cliVersion, QString(APP_VERSION))
|
||||
.addField(apiDefs::key::subscriptionStatus, getSubscriptionStatusForRenewal(apiV2->apiConfig))
|
||||
.build();
|
||||
|
||||
auto gatewayController = QSharedPointer<GatewayController>::create(m_appSettingsRepository->getGatewayEndpoint(isTestPurchase),
|
||||
m_appSettingsRepository->isDevGatewayEnv(isTestPurchase),
|
||||
@@ -1111,21 +1008,14 @@ ErrorCode SubscriptionController::resolveImportServiceCaptcha(const QString &use
|
||||
const QString &captchaSolution,
|
||||
CaptchaInfo *retryCaptchaOut)
|
||||
{
|
||||
GatewayRequestData gatewayRequestData{QSysInfo::productType(),
|
||||
QString(APP_VERSION),
|
||||
m_appSettingsRepository->getAppLanguage().name().split("_").first(),
|
||||
m_appSettingsRepository->getInstallationUuid(true),
|
||||
userCountryCode,
|
||||
"",
|
||||
serviceType,
|
||||
serviceProtocol,
|
||||
QJsonObject()};
|
||||
|
||||
QJsonObject apiPayload = gatewayRequestData.toJsonObject();
|
||||
appendProtocolDataToApiPayload(serviceProtocol, protocolData, apiPayload);
|
||||
|
||||
apiPayload["captcha_id"] = captchaId;
|
||||
apiPayload["captcha_solution"] = normalizeCaptchaSolution(captchaSolution);
|
||||
QJsonObject apiPayload = GatewayPayloadBuilder(m_appSettingsRepository)
|
||||
.addField(apiDefs::key::userCountryCode, userCountryCode)
|
||||
.addField(apiDefs::key::serviceType, serviceType)
|
||||
.addField(apiDefs::key::serviceProtocol, serviceProtocol)
|
||||
.addField(apiDefs::key::publicKey, publicKeyForProtocol(serviceProtocol, protocolData))
|
||||
.addField(apiDefs::key::captchaId, captchaId)
|
||||
.addField(apiDefs::key::captchaSolution, normalizeCaptchaSolution(captchaSolution))
|
||||
.build();
|
||||
|
||||
QByteArray responseBody;
|
||||
ErrorCode errorCode = executeRequest(QString("%1v1/config"), apiPayload, responseBody);
|
||||
|
||||
@@ -27,21 +27,6 @@ public:
|
||||
QString xrayUuid;
|
||||
};
|
||||
|
||||
struct GatewayRequestData
|
||||
{
|
||||
QString osVersion;
|
||||
QString appVersion;
|
||||
QString appLanguage;
|
||||
QString installationUuid;
|
||||
QString userCountryCode;
|
||||
QString serverCountryCode;
|
||||
QString serviceType;
|
||||
QString serviceProtocol;
|
||||
QJsonObject authData;
|
||||
|
||||
QJsonObject toJsonObject() const;
|
||||
};
|
||||
|
||||
struct CaptchaInfo {
|
||||
QString captchaId;
|
||||
QString captchaImageBase64;
|
||||
@@ -53,7 +38,8 @@ public:
|
||||
SecureAppSettingsRepository* appSettingsRepository);
|
||||
|
||||
ProtocolData generateProtocolData(const QString &protocol);
|
||||
void appendProtocolDataToApiPayload(const QString &protocol, const ProtocolData &protocolData, QJsonObject &apiPayload);
|
||||
|
||||
static QString publicKeyForProtocol(const QString &protocol, const ProtocolData &protocolData);
|
||||
|
||||
ErrorCode importServiceFromGateway(const QString &userCountryCode, const QString &serviceType,
|
||||
const QString &serviceProtocol, const ProtocolData &protocolData,
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
#include "core/controllers/coreSignalHandlers.h"
|
||||
#include "logger.h"
|
||||
#include "secureQSettings.h"
|
||||
#include "core/utils/appUiConfig.h"
|
||||
|
||||
#if defined(Q_OS_ANDROID)
|
||||
#include "core/utils/installedAppsImageProvider.h"
|
||||
@@ -18,7 +19,7 @@
|
||||
|
||||
#if defined(Q_OS_IOS)
|
||||
#include "platforms/ios/ios_controller.h"
|
||||
#include <AmneziaVPN-Swift.h>
|
||||
#include "core/utils/swiftBridge.h"
|
||||
#endif
|
||||
|
||||
CoreController::CoreController(const QSharedPointer<VpnConnection> &vpnConnection, SecureQSettings* settings,
|
||||
@@ -258,7 +259,7 @@ void CoreController::initAppleController()
|
||||
{
|
||||
#ifdef Q_OS_IOS
|
||||
IosController::Instance()->initialize();
|
||||
QTimer::singleShot(0, this, [this]() { AmneziaVPN::toggleScreenshots(m_appSettingsRepository->isScreenshotsEnabled()); });
|
||||
QTimer::singleShot(0, this, [this]() { SWIFT_BRIDGE_NAMESPACE::toggleScreenshots(m_appSettingsRepository->isScreenshotsEnabled()); });
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -298,15 +299,15 @@ void CoreController::updateTranslator(const QLocale &locale)
|
||||
}
|
||||
|
||||
QStringList availableTranslations;
|
||||
QDirIterator it(":/translations", QStringList("amneziavpn_*.qm"), QDir::Files);
|
||||
QDirIterator it(":/translations", QStringList(APP_TS_PREFIX "_*.qm"), QDir::Files);
|
||||
while (it.hasNext()) {
|
||||
availableTranslations << it.next();
|
||||
}
|
||||
|
||||
// This code allow to load translation for the language only, without country code
|
||||
const QString lang = locale.name().split("_").first();
|
||||
const QString translationFilePrefix = QString(":/translations/amneziavpn_") + lang;
|
||||
QString strFileName = QString(":/translations/amneziavpn_%1.qm").arg(locale.name());
|
||||
const QString translationFilePrefix = QString(":/translations/" APP_TS_PREFIX "_") + lang;
|
||||
QString strFileName = QString(":/translations/" APP_TS_PREFIX "_%1.qm").arg(locale.name());
|
||||
for (const QString &translation : availableTranslations) {
|
||||
if (translation.contains(translationFilePrefix)) {
|
||||
strFileName = translation;
|
||||
@@ -317,7 +318,7 @@ void CoreController::updateTranslator(const QLocale &locale)
|
||||
if (m_translator->load(strFileName)) {
|
||||
QCoreApplication::installTranslator(m_translator);
|
||||
} else {
|
||||
if (m_translator->load(QString(":/translations/amneziavpn_en.qm"))) {
|
||||
if (m_translator->load(QString(":/translations/" APP_TS_PREFIX "_en.qm"))) {
|
||||
QCoreApplication::installTranslator(m_translator);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -48,7 +48,7 @@
|
||||
|
||||
#ifdef Q_OS_IOS
|
||||
#include "platforms/ios/ios_controller.h"
|
||||
#include <AmneziaVPN-Swift.h>
|
||||
#include "core/utils/swiftBridge.h"
|
||||
#endif
|
||||
|
||||
CoreSignalHandlers::CoreSignalHandlers(CoreController* coreController, QObject* parent)
|
||||
@@ -413,7 +413,7 @@ void CoreSignalHandlers::initIosImportHandler()
|
||||
void CoreSignalHandlers::initIosSettingsHandler()
|
||||
{
|
||||
#ifdef Q_OS_IOS
|
||||
connect(m_coreController->m_appSettingsRepository, &SecureAppSettingsRepository::screenshotsEnabledChanged, [](bool enabled) { AmneziaVPN::toggleScreenshots(enabled); });
|
||||
connect(m_coreController->m_appSettingsRepository, &SecureAppSettingsRepository::screenshotsEnabledChanged, [](bool enabled) { SWIFT_BRIDGE_NAMESPACE::toggleScreenshots(enabled); });
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
@@ -154,8 +154,13 @@ QString IpSplitTunnelingController::normalizeHostname(const QString &hostname) c
|
||||
normalized.replace("https://", "");
|
||||
normalized.replace("http://", "");
|
||||
normalized.replace("ftp://", "");
|
||||
normalized = normalized.split("/", Qt::SkipEmptyParts).first();
|
||||
return normalized;
|
||||
|
||||
if (NetworkUtilities::ipAddressWithSubnetRegExp().exactMatch(normalized)) {
|
||||
return normalized;
|
||||
}
|
||||
|
||||
const QStringList parts = normalized.split("/", Qt::SkipEmptyParts);
|
||||
return parts.isEmpty() ? QString() : parts.first();
|
||||
}
|
||||
|
||||
bool IpSplitTunnelingController::validateHostname(const QString &hostname) const
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
#include "core/models/selfhosted/selfHostedAdminServerConfig.h"
|
||||
#include "core/models/containerConfig.h"
|
||||
#include "core/models/protocolConfig.h"
|
||||
#include "version.h"
|
||||
|
||||
using namespace amnezia;
|
||||
|
||||
@@ -220,7 +221,10 @@ ExportController::ExportResult ExportController::generateWireGuardConfig(const Q
|
||||
result.config.append(line + "\n");
|
||||
}
|
||||
|
||||
result.qrCodes << generateSingleQrCode(result.config.toUtf8());
|
||||
const QString qr = qrCodeUtils::generatePlainQrCodeImage(result.config.toUtf8());
|
||||
if (!qr.isEmpty()) {
|
||||
result.qrCodes << qr;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -251,7 +255,10 @@ ExportController::ExportResult ExportController::generateAwgConfig(const QString
|
||||
result.config.append(line + "\n");
|
||||
}
|
||||
|
||||
result.qrCodes << generateSingleQrCode(result.config.toUtf8());
|
||||
const QString qr = qrCodeUtils::generatePlainQrCodeImage(result.config.toUtf8());
|
||||
if (!qr.isEmpty()) {
|
||||
result.qrCodes << qr;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -337,7 +344,7 @@ ExportController::ExportResult ExportController::generateXrayConfig(const QStrin
|
||||
// VlessServerObject doesn't have alpn field, so we embed in serverName if needed
|
||||
}
|
||||
|
||||
result.nativeConfigString = amnezia::serialization::vless::Serialize(vlessServer, "AmneziaVPN");
|
||||
result.nativeConfigString = amnezia::serialization::vless::Serialize(vlessServer, APPLICATION_NAME);
|
||||
|
||||
return result;
|
||||
}
|
||||
@@ -369,9 +376,3 @@ QList<QString> ExportController::generateQrCodesFromConfig(const QByteArray &dat
|
||||
{
|
||||
return qrCodeUtils::generateQrCodeImageSeries(data);
|
||||
}
|
||||
|
||||
QString ExportController::generateSingleQrCode(const QByteArray &data)
|
||||
{
|
||||
auto qr = qrCodeUtils::generateQrCode(data);
|
||||
return qrCodeUtils::svgToBase64(QString::fromStdString(toSvgString(qr, 1)));
|
||||
}
|
||||
|
||||
@@ -69,7 +69,6 @@ private:
|
||||
|
||||
QString generateVpnUrl(const QByteArray &compressedConfig);
|
||||
QList<QString> generateQrCodesFromConfig(const QByteArray &data);
|
||||
QString generateSingleQrCode(const QByteArray &data);
|
||||
|
||||
SecureServersRepository* m_serversRepository;
|
||||
SecureAppSettingsRepository* m_appSettingsRepository;
|
||||
|
||||
@@ -511,9 +511,10 @@ QJsonObject ImportController::extractWireGuardConfig(const QString &data, Config
|
||||
if (trimmedLine.startsWith("[") && trimmedLine.endsWith("]")) {
|
||||
continue;
|
||||
} else {
|
||||
QStringList parts = trimmedLine.split(" = ");
|
||||
if (parts.count() == 2) {
|
||||
configMap[parts.at(0).trimmed()] = parts.at(1).trimmed();
|
||||
const qsizetype separatorIndex = trimmedLine.indexOf('=');
|
||||
if (separatorIndex > 0) {
|
||||
configMap[trimmedLine.left(separatorIndex).trimmed()] =
|
||||
trimmedLine.mid(separatorIndex + 1).trimmed();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -566,8 +567,9 @@ QJsonObject ImportController::extractWireGuardConfig(const QString &data, Config
|
||||
lastConfig[configKey::persistentKeepAlive] = configMap.value(protocols::wireguard::PersistentKeepalive);
|
||||
}
|
||||
|
||||
QJsonArray allowedIpsJsonArray = QJsonArray::fromStringList(
|
||||
configMap.value(protocols::wireguard::AllowedIPs).split(", "));
|
||||
const QStringList allowedIps = configMap.value(protocols::wireguard::AllowedIPs).split(
|
||||
QRegularExpression("\\s*,\\s*"), Qt::SkipEmptyParts);
|
||||
QJsonArray allowedIpsJsonArray = QJsonArray::fromStringList(allowedIps);
|
||||
|
||||
lastConfig[configKey::allowedIps] = allowedIpsJsonArray;
|
||||
|
||||
@@ -635,11 +637,24 @@ QJsonObject ImportController::extractXrayConfig(const QString &data, ConfigTypes
|
||||
{
|
||||
QJsonParseError parserErr;
|
||||
QJsonDocument jsonConf = QJsonDocument::fromJson(data.toLocal8Bit(), &parserErr);
|
||||
if (parserErr.error != QJsonParseError::NoError || !jsonConf.isObject()) {
|
||||
qDebug() << "Xray config JSON parse failed:" << parserErr.errorString();
|
||||
return QJsonObject();
|
||||
}
|
||||
|
||||
const QJsonObject parsedConfig = jsonConf.object();
|
||||
if (!parsedConfig.value(protocols::xray::inbounds).isArray()
|
||||
|| !parsedConfig.value(protocols::xray::outbounds).isArray()) {
|
||||
qDebug() << "Xray config is missing inbounds or outbounds";
|
||||
return QJsonObject();
|
||||
}
|
||||
|
||||
const QString serializedConfig = QString::fromUtf8(jsonConf.toJson());
|
||||
|
||||
QJsonObject xrayVpnConfig;
|
||||
xrayVpnConfig[configKey::config] = jsonConf.toJson().constData();
|
||||
xrayVpnConfig[configKey::config] = serializedConfig;
|
||||
QJsonObject lastConfig;
|
||||
lastConfig[configKey::lastConfig] = jsonConf.toJson().constData();
|
||||
lastConfig[configKey::lastConfig] = serializedConfig;
|
||||
lastConfig[configKey::isThirdPartyConfig] = true;
|
||||
|
||||
QJsonObject containers;
|
||||
|
||||
@@ -201,9 +201,6 @@ ErrorCode InstallController::updateServerConfig(const QString &serverId, DockerC
|
||||
SshSession sshSession;
|
||||
|
||||
bool reinstallRequired = isReinstallContainerRequired(container, oldConfig, newConfig);
|
||||
if (container == DockerContainer::Xray || container == DockerContainer::SSXray) {
|
||||
reinstallRequired = true;
|
||||
}
|
||||
qDebug() << "InstallController::updateServerConfig for container" << container << "reinstall required is" << reinstallRequired;
|
||||
|
||||
ErrorCode errorCode = ErrorCode::NoError;
|
||||
@@ -216,7 +213,7 @@ ErrorCode InstallController::updateServerConfig(const QString &serverId, DockerC
|
||||
awgConfig->serverConfig.protocolVersion = protocols::awg::awgV3;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
} else if (container != DockerContainer::Xray && container != DockerContainer::SSXray) {
|
||||
errorCode = configureContainerWorker(credentials, container, newConfig, sshSession);
|
||||
if (errorCode == ErrorCode::NoError) {
|
||||
errorCode = startupContainerWorker(credentials, container, newConfig, sshSession);
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
#include "core/models/serverDescription.h"
|
||||
|
||||
#if defined(Q_OS_IOS) || defined(MACOS_NE)
|
||||
#include <AmneziaVPN-Swift.h>
|
||||
#include "core/utils/swiftBridge.h"
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
@@ -351,16 +351,6 @@ void SettingsController::setAppLanguage(const QLocale &locale)
|
||||
m_appSettingsRepository->setAppLanguage(locale);
|
||||
}
|
||||
|
||||
bool SettingsController::isPremV1MigrationReminderActive() const
|
||||
{
|
||||
return m_appSettingsRepository->isPremV1MigrationReminderActive();
|
||||
}
|
||||
|
||||
void SettingsController::disablePremV1MigrationReminder()
|
||||
{
|
||||
m_appSettingsRepository->disablePremV1MigrationReminder();
|
||||
}
|
||||
|
||||
QString SettingsController::nextAvailableServerName() const
|
||||
{
|
||||
return m_serversRepository->nextAvailableServerName();
|
||||
|
||||
@@ -69,9 +69,6 @@ public:
|
||||
|
||||
void enableDevMode();
|
||||
|
||||
bool isPremV1MigrationReminderActive() const;
|
||||
void disablePremV1MigrationReminder();
|
||||
|
||||
QString nextAvailableServerName() const;
|
||||
bool isDevModeEnabled() const;
|
||||
|
||||
|
||||
@@ -5,13 +5,13 @@
|
||||
#include <QUrl>
|
||||
#include <QJsonDocument>
|
||||
#include <QJsonObject>
|
||||
#include <QSysInfo>
|
||||
#include <QTimer>
|
||||
|
||||
#include "amneziaApplication.h"
|
||||
#include "logger.h"
|
||||
#include "version.h"
|
||||
#include "core/controllers/gatewayController.h"
|
||||
#include "core/utils/api/gatewayPayloadBuilder.h"
|
||||
#include "core/utils/constants/apiKeys.h"
|
||||
#include "core/utils/selfhosted/scriptsRegistry.h"
|
||||
|
||||
@@ -98,10 +98,9 @@ void UpdateController::fetchGatewayUrl()
|
||||
m_appSettingsRepository->isStrictKillSwitchEnabled(),
|
||||
m_appSettingsRepository);
|
||||
|
||||
QJsonObject apiPayload;
|
||||
apiPayload[apiDefs::key::cliVersion] = QString(APP_VERSION);
|
||||
apiPayload[apiDefs::key::osVersion] = QSysInfo::productType();
|
||||
apiPayload[apiDefs::key::installationUuid] = m_appSettingsRepository->getInstallationUuid(true);
|
||||
QJsonObject apiPayload = GatewayPayloadBuilder(m_appSettingsRepository)
|
||||
.addField(apiDefs::key::cliVersion, QString(APP_VERSION))
|
||||
.build();
|
||||
|
||||
// Workaround: wait before contacting gateway to avoid rate limit triggered by other requests (news etc.)
|
||||
QTimer::singleShot(1000, this, [this, gatewayController, apiPayload]() {
|
||||
|
||||
@@ -78,6 +78,8 @@ void AwgInstaller::generateAwgParameters(AwgServerConfig &serverConfig)
|
||||
serverConfig.rejectAfterTime = protocols::awg::defaultRejectAfterTime;
|
||||
serverConfig.keepaliveTimeout = protocols::awg::defaultKeepaliveTimeout;
|
||||
serverConfig.maxHandshakeAttempts = protocols::awg::defaultMaxHandshakeAttempts;
|
||||
serverConfig.randomTrailers = protocols::awg::defaultRandomTrailers;
|
||||
serverConfig.disableCookies = protocols::awg::defaultDisableCookies;
|
||||
}
|
||||
|
||||
ErrorCode AwgInstaller::extractConfigFromContainer(DockerContainer container, const ServerCredentials &credentials,
|
||||
@@ -144,6 +146,8 @@ ErrorCode AwgInstaller::extractConfigFromContainer(DockerContainer container, co
|
||||
awgConfig->serverConfig.rejectAfterTime = serverConfigMap.value(configKey::rejectAfterTime);
|
||||
awgConfig->serverConfig.keepaliveTimeout = serverConfigMap.value(configKey::keepaliveTimeout);
|
||||
awgConfig->serverConfig.maxHandshakeAttempts = serverConfigMap.value(configKey::maxHandshakeAttempts);
|
||||
awgConfig->serverConfig.randomTrailers = serverConfigMap.value(configKey::randomTrailers);
|
||||
awgConfig->serverConfig.disableCookies = serverConfigMap.value(configKey::disableCookies);
|
||||
|
||||
awgConfig->serverConfig.protocolVersion = awgConfig->serverProtocolVersion();
|
||||
}
|
||||
|
||||
@@ -20,7 +20,7 @@ namespace amnezia
|
||||
namespace
|
||||
{
|
||||
template <typename T>
|
||||
QString awgVersionOf(const T &config)
|
||||
bool hasAwg3Markers(const T &config)
|
||||
{
|
||||
auto hasValue = [](const QString &value) { return !value.trimmed().isEmpty(); };
|
||||
|
||||
@@ -29,6 +29,19 @@ namespace
|
||||
config.rejectAfterTime, config.keepaliveTimeout,
|
||||
config.maxHandshakeAttempts };
|
||||
if (std::any_of(awg3Params.begin(), awg3Params.end(), hasValue)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return AwgProtocolConfig::isToggleEnabled(config.randomTrailers)
|
||||
|| AwgProtocolConfig::isToggleEnabled(config.disableCookies);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
QString awgVersionOf(const T &config)
|
||||
{
|
||||
auto hasValue = [](const QString &value) { return !value.trimmed().isEmpty(); };
|
||||
|
||||
if (hasAwg3Markers(config)) {
|
||||
return protocols::awg::awgV3;
|
||||
}
|
||||
|
||||
@@ -134,6 +147,12 @@ QJsonObject AwgServerConfig::toJson() const
|
||||
if (!maxHandshakeAttempts.isEmpty()) {
|
||||
obj[configKey::maxHandshakeAttempts] = maxHandshakeAttempts;
|
||||
}
|
||||
if (!randomTrailers.isEmpty()) {
|
||||
obj[configKey::randomTrailers] = randomTrailers;
|
||||
}
|
||||
if (!disableCookies.isEmpty()) {
|
||||
obj[configKey::disableCookies] = disableCookies;
|
||||
}
|
||||
|
||||
if (isThirdPartyConfig) {
|
||||
obj[configKey::isThirdPartyConfig] = isThirdPartyConfig;
|
||||
@@ -178,6 +197,8 @@ AwgServerConfig AwgServerConfig::fromJson(const QJsonObject& json)
|
||||
config.rejectAfterTime = json.value(configKey::rejectAfterTime).toString();
|
||||
config.keepaliveTimeout = json.value(configKey::keepaliveTimeout).toString();
|
||||
config.maxHandshakeAttempts = json.value(configKey::maxHandshakeAttempts).toString();
|
||||
config.randomTrailers = json.value(configKey::randomTrailers).toString();
|
||||
config.disableCookies = json.value(configKey::disableCookies).toString();
|
||||
|
||||
config.isThirdPartyConfig = json.value(configKey::isThirdPartyConfig).toBool(false);
|
||||
|
||||
@@ -302,6 +323,12 @@ QJsonObject AwgClientConfig::toJson() const
|
||||
if (!maxHandshakeAttempts.isEmpty()) {
|
||||
obj[configKey::maxHandshakeAttempts] = maxHandshakeAttempts;
|
||||
}
|
||||
if (!randomTrailers.isEmpty()) {
|
||||
obj[configKey::randomTrailers] = randomTrailers;
|
||||
}
|
||||
if (!disableCookies.isEmpty()) {
|
||||
obj[configKey::disableCookies] = disableCookies;
|
||||
}
|
||||
|
||||
return obj;
|
||||
}
|
||||
@@ -353,6 +380,8 @@ AwgClientConfig AwgClientConfig::fromJson(const QJsonObject& json)
|
||||
config.rejectAfterTime = json.value(configKey::rejectAfterTime).toString();
|
||||
config.keepaliveTimeout = json.value(configKey::keepaliveTimeout).toString();
|
||||
config.maxHandshakeAttempts = json.value(configKey::maxHandshakeAttempts).toString();
|
||||
config.randomTrailers = json.value(configKey::randomTrailers).toString();
|
||||
config.disableCookies = json.value(configKey::disableCookies).toString();
|
||||
return config;
|
||||
}
|
||||
|
||||
@@ -395,9 +424,16 @@ QString AwgProtocolConfig::clientProtocolVersion() const
|
||||
return clientConfig.has_value() ? awgVersionOf(clientConfig.value()) : QString();
|
||||
}
|
||||
|
||||
bool AwgProtocolConfig::isToggleEnabled(const QString &value)
|
||||
{
|
||||
const QString trimmedValue = value.trimmed();
|
||||
return !trimmedValue.isEmpty()
|
||||
&& trimmedValue.compare(QLatin1String(protocols::awg::awgBoolOff), Qt::CaseInsensitive) != 0;
|
||||
}
|
||||
|
||||
QString AwgProtocolConfig::protocolVersionString(const QString &version)
|
||||
{
|
||||
if (version == protocols::awg::awgV3) return QObject::tr(" (version 3)");
|
||||
if (version == protocols::awg::awgV3) return QObject::tr(" (version 3.1)");
|
||||
if (version == protocols::awg::awgV2) return QObject::tr(" (version 2)");
|
||||
if (version == protocols::awg::awgV1_5) return QObject::tr(" (version 1.5)");
|
||||
return "";
|
||||
@@ -437,13 +473,19 @@ bool AwgServerConfig::hasEqualServerSettings(const AwgServerConfig& other) const
|
||||
contentPaddingAddition != other.contentPaddingAddition ||
|
||||
rekeyAfterTime != other.rekeyAfterTime || rekeyTimeout != other.rekeyTimeout ||
|
||||
rejectAfterTime != other.rejectAfterTime || keepaliveTimeout != other.keepaliveTimeout ||
|
||||
maxHandshakeAttempts != other.maxHandshakeAttempts) {
|
||||
maxHandshakeAttempts != other.maxHandshakeAttempts ||
|
||||
randomTrailers != other.randomTrailers || disableCookies != other.disableCookies) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool AwgServerConfig::hasAwg3Params() const
|
||||
{
|
||||
return hasAwg3Markers(*this);
|
||||
}
|
||||
|
||||
bool AwgProtocolConfig::isHeadersEqual(const QString &h1, const QString &h2, const QString &h3, const QString &h4)
|
||||
{
|
||||
QSet<QString> uniqueHeaders;
|
||||
|
||||
@@ -46,12 +46,15 @@ struct AwgServerConfig {
|
||||
QString rejectAfterTime;
|
||||
QString keepaliveTimeout;
|
||||
QString maxHandshakeAttempts;
|
||||
QString randomTrailers;
|
||||
QString disableCookies;
|
||||
bool isThirdPartyConfig = false;
|
||||
|
||||
QJsonObject toJson() const;
|
||||
static AwgServerConfig fromJson(const QJsonObject& json);
|
||||
|
||||
|
||||
bool hasEqualServerSettings(const AwgServerConfig& other) const;
|
||||
bool hasAwg3Params() const;
|
||||
};
|
||||
|
||||
struct AwgClientConfig {
|
||||
@@ -90,6 +93,8 @@ struct AwgClientConfig {
|
||||
QString rejectAfterTime;
|
||||
QString keepaliveTimeout;
|
||||
QString maxHandshakeAttempts;
|
||||
QString randomTrailers;
|
||||
QString disableCookies;
|
||||
QJsonObject toJson() const;
|
||||
static AwgClientConfig fromJson(const QJsonObject& json);
|
||||
};
|
||||
@@ -104,6 +109,7 @@ struct AwgProtocolConfig {
|
||||
QString serverProtocolVersion() const;
|
||||
QString clientProtocolVersion() const;
|
||||
static QString protocolVersionString(const QString &version);
|
||||
static bool isToggleEnabled(const QString &value);
|
||||
|
||||
bool hasClientConfig() const;
|
||||
void setClientConfig(const AwgClientConfig& config);
|
||||
|
||||
@@ -19,6 +19,7 @@ VpnProtocol::VpnProtocol(const QJsonObject &configuration, QObject *parent)
|
||||
m_connectionState(Vpn::ConnectionState::Unknown),
|
||||
m_rawConfig(configuration),
|
||||
m_timeoutTimer(new QTimer(this)),
|
||||
m_lastError(ErrorCode::NoError),
|
||||
m_receivedBytes(0),
|
||||
m_sentBytes(0)
|
||||
{
|
||||
|
||||
@@ -442,16 +442,6 @@ void SecureAppSettingsRepository::disableHomeAdLabel()
|
||||
setValue("Conf/homeAdLabelVisible", false);
|
||||
}
|
||||
|
||||
bool SecureAppSettingsRepository::isPremV1MigrationReminderActive() const
|
||||
{
|
||||
return value("Conf/premV1MigrationReminderActive", true).toBool();
|
||||
}
|
||||
|
||||
void SecureAppSettingsRepository::disablePremV1MigrationReminder()
|
||||
{
|
||||
setValue("Conf/premV1MigrationReminderActive", false);
|
||||
}
|
||||
|
||||
QByteArray SecureAppSettingsRepository::backupAppConfig() const
|
||||
{
|
||||
return m_settings->backupAppConfig();
|
||||
|
||||
@@ -90,8 +90,6 @@ public:
|
||||
|
||||
bool isHomeAdLabelVisible() const;
|
||||
void disableHomeAdLabel();
|
||||
bool isPremV1MigrationReminderActive() const;
|
||||
void disablePremV1MigrationReminder();
|
||||
QByteArray backupAppConfig() const;
|
||||
bool restoreAppConfig(const QByteArray &cfg);
|
||||
void clearSettings();
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
#include "apiUtils.h"
|
||||
|
||||
#include "core/repositories/secureAppSettingsRepository.h"
|
||||
#include "core/utils/serverConfigUtils.h"
|
||||
#include "core/utils/constants/configKeys.h"
|
||||
#include <QDateTime>
|
||||
@@ -48,6 +49,30 @@ namespace
|
||||
}
|
||||
}
|
||||
|
||||
QString apiUtils::getAppLanguageCode(const SecureAppSettingsRepository *appSettingsRepository)
|
||||
{
|
||||
if (appSettingsRepository == nullptr) {
|
||||
return {};
|
||||
}
|
||||
return appSettingsRepository->getAppLanguage().name().split("_").first();
|
||||
}
|
||||
|
||||
QString apiUtils::getDistributionChannel()
|
||||
{
|
||||
#if defined(Q_OS_ANDROID)
|
||||
return {};
|
||||
#elif defined(Q_OS_IOS) || defined(MACOS_NE)
|
||||
return QStringLiteral("appstore");
|
||||
#else
|
||||
return QStringLiteral("github");
|
||||
#endif
|
||||
}
|
||||
|
||||
QString apiUtils::getCountryFlagCode(const QString &serverCountryCode)
|
||||
{
|
||||
return serverCountryCode.section('-', 0, 0).toUpper();
|
||||
}
|
||||
|
||||
bool apiUtils::isSubscriptionExpired(const QString &subscriptionEndDate)
|
||||
{
|
||||
if (subscriptionEndDate.isEmpty()) {
|
||||
@@ -167,44 +192,6 @@ bool apiUtils::isPremiumServer(const QJsonObject &serverConfigObject)
|
||||
return premiumTypes.contains(serverConfigUtils::configTypeFromJson(serverConfigObject));
|
||||
}
|
||||
|
||||
QString apiUtils::getPremiumV1VpnKey(const QJsonObject &serverConfigObject)
|
||||
{
|
||||
if (serverConfigUtils::configTypeFromJson(serverConfigObject) != serverConfigUtils::ConfigType::AmneziaPremiumV1) {
|
||||
return {};
|
||||
}
|
||||
|
||||
QList<QPair<QString, QVariant>> orderedFields;
|
||||
orderedFields.append(qMakePair(configKey::name, serverConfigObject[configKey::name].toString()));
|
||||
orderedFields.append(qMakePair(configKey::description, serverConfigObject[configKey::description].toString()));
|
||||
orderedFields.append(qMakePair(configKey::configVersion, serverConfigObject[configKey::configVersion].toDouble()));
|
||||
orderedFields.append(qMakePair(apiDefs::key::protocol, serverConfigObject[apiDefs::key::protocol].toString()));
|
||||
orderedFields.append(qMakePair(apiDefs::key::apiEndpoint, serverConfigObject[apiDefs::key::apiEndpoint].toString()));
|
||||
orderedFields.append(qMakePair(apiDefs::key::apiKey, serverConfigObject[apiDefs::key::apiKey].toString()));
|
||||
|
||||
QString vpnKeyStr = "{";
|
||||
for (int i = 0; i < orderedFields.size(); ++i) {
|
||||
const auto &pair = orderedFields[i];
|
||||
if (pair.second.typeId() == QMetaType::Type::QString) {
|
||||
vpnKeyStr += "\"" + pair.first + "\": \"" + pair.second.toString() + "\"";
|
||||
} else if (pair.second.typeId() == QMetaType::Type::Double || pair.second.typeId() == QMetaType::Type::Int) {
|
||||
vpnKeyStr += "\"" + pair.first + "\": " + QString::number(pair.second.toDouble(), 'f', 1);
|
||||
}
|
||||
|
||||
if (i < orderedFields.size() - 1) {
|
||||
vpnKeyStr += ", ";
|
||||
}
|
||||
}
|
||||
vpnKeyStr += "}";
|
||||
|
||||
QByteArray vpnKeyCompressed = escapeUnicode(vpnKeyStr).toUtf8();
|
||||
vpnKeyCompressed = qCompress(vpnKeyCompressed, 6);
|
||||
vpnKeyCompressed = vpnKeyCompressed.mid(4);
|
||||
|
||||
QByteArray signedData = AMNEZIA_CONFIG_SIGNATURE + vpnKeyCompressed;
|
||||
|
||||
return QString("vpn://%1").arg(QString(signedData.toBase64(QByteArray::Base64UrlEncoding)));
|
||||
}
|
||||
|
||||
QString apiUtils::getPremiumV2VpnKey(const QJsonObject &serverConfigObject)
|
||||
{
|
||||
auto configType = serverConfigUtils::configTypeFromJson(serverConfigObject);
|
||||
|
||||
@@ -11,8 +11,18 @@
|
||||
#include "core/utils/routeModes.h"
|
||||
#include "core/utils/commonStructs.h"
|
||||
|
||||
class SecureAppSettingsRepository;
|
||||
|
||||
namespace apiUtils
|
||||
{
|
||||
QString getAppLanguageCode(const SecureAppSettingsRepository *appSettingsRepository);
|
||||
QString getDistributionChannel();
|
||||
|
||||
// The gateway may report a country code with a region suffix, e.g. "us-west", while flag
|
||||
// resources are named after the ISO 3166-1 alpha-2 code alone. Returns the part before the dash
|
||||
// in upper case.
|
||||
QString getCountryFlagCode(const QString &serverCountryCode);
|
||||
|
||||
bool isSubscriptionExpired(const QString &subscriptionEndDate);
|
||||
|
||||
bool isSubscriptionExpiringSoon(const QString &subscriptionEndDate, int withinDays = 30);
|
||||
@@ -23,7 +33,6 @@ namespace apiUtils
|
||||
const QNetworkReply::NetworkError &replyError, const int httpStatusCode,
|
||||
const QByteArray &responseBody);
|
||||
|
||||
QString getPremiumV1VpnKey(const QJsonObject &serverConfigObject);
|
||||
QString getPremiumV2VpnKey(const QJsonObject &serverConfigObject);
|
||||
}
|
||||
|
||||
|
||||
62
client/core/utils/api/gatewayPayloadBuilder.cpp
Normal file
@@ -0,0 +1,62 @@
|
||||
#include "gatewayPayloadBuilder.h"
|
||||
|
||||
#include <QJsonArray>
|
||||
#include <QSysInfo>
|
||||
|
||||
#include "core/repositories/secureAppSettingsRepository.h"
|
||||
#include "core/utils/api/apiUtils.h"
|
||||
#include "core/utils/constants/apiKeys.h"
|
||||
#include "version.h"
|
||||
|
||||
namespace
|
||||
{
|
||||
bool isEmptyValue(const QJsonValue &value)
|
||||
{
|
||||
switch (value.type()) {
|
||||
case QJsonValue::Null:
|
||||
case QJsonValue::Undefined:
|
||||
return true;
|
||||
case QJsonValue::String:
|
||||
return value.toString().isEmpty();
|
||||
case QJsonValue::Object:
|
||||
return value.toObject().isEmpty();
|
||||
case QJsonValue::Array:
|
||||
return value.toArray().isEmpty();
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
GatewayPayloadBuilder::GatewayPayloadBuilder(const SecureAppSettingsRepository *appSettingsRepository)
|
||||
{
|
||||
m_payload[apiDefs::key::osVersion] = QSysInfo::productType();
|
||||
m_payload[apiDefs::key::appVersion] = QString(APP_VERSION);
|
||||
m_payload[apiDefs::key::cliName] = QString(APPLICATION_NAME);
|
||||
|
||||
const QString distributionChannel = apiUtils::getDistributionChannel();
|
||||
if (!distributionChannel.isEmpty()) {
|
||||
m_payload[apiDefs::key::distribution] = distributionChannel;
|
||||
}
|
||||
|
||||
if (appSettingsRepository == nullptr) {
|
||||
qWarning() << "SecureAppSettingsRepository is null, skip app language and installation uuid";
|
||||
return;
|
||||
}
|
||||
|
||||
m_payload[apiDefs::key::appLanguage] = apiUtils::getAppLanguageCode(appSettingsRepository);
|
||||
m_payload[apiDefs::key::installationUuid] = appSettingsRepository->getInstallationUuid(true);
|
||||
}
|
||||
|
||||
GatewayPayloadBuilder &GatewayPayloadBuilder::addField(QLatin1String key, const QJsonValue &value)
|
||||
{
|
||||
if (!isEmptyValue(value)) {
|
||||
m_payload[key] = value;
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
QJsonObject GatewayPayloadBuilder::build() const
|
||||
{
|
||||
return m_payload;
|
||||
}
|
||||
22
client/core/utils/api/gatewayPayloadBuilder.h
Normal file
@@ -0,0 +1,22 @@
|
||||
#ifndef GATEWAYPAYLOADBUILDER_H
|
||||
#define GATEWAYPAYLOADBUILDER_H
|
||||
|
||||
#include <QJsonObject>
|
||||
#include <QJsonValue>
|
||||
#include <QLatin1String>
|
||||
|
||||
class SecureAppSettingsRepository;
|
||||
|
||||
class GatewayPayloadBuilder
|
||||
{
|
||||
public:
|
||||
explicit GatewayPayloadBuilder(const SecureAppSettingsRepository *appSettingsRepository);
|
||||
|
||||
GatewayPayloadBuilder &addField(QLatin1String key, const QJsonValue &value);
|
||||
QJsonObject build() const;
|
||||
|
||||
private:
|
||||
QJsonObject m_payload;
|
||||
};
|
||||
|
||||
#endif // GATEWAYPAYLOADBUILDER_H
|
||||
15
client/core/utils/appUiConfig.h.in
Normal file
@@ -0,0 +1,15 @@
|
||||
#ifndef APP_UI_CONFIG_H
|
||||
#define APP_UI_CONFIG_H
|
||||
|
||||
#define APP_INSTANCE_NAME "@CLIENT_APP_INSTANCE_NAME@"
|
||||
#define APP_QML_ENTRYPOINT "@CLIENT_QML_ENTRYPOINT@"
|
||||
#define APP_QML_IMPORT_PATH "@CLIENT_QML_IMPORT_PATH@"
|
||||
#define APP_QML_PAGES_PREFIX "@CLIENT_QML_PAGES_PREFIX@"
|
||||
#define APP_UI_FONT_RESOURCE "@CLIENT_UI_FONT_RESOURCE@"
|
||||
#define APP_TS_PREFIX "@CLIENT_TS_PREFIX@"
|
||||
#define APP_NOTIFICATION_IDENTIFIER "@CLIENT_NOTIFICATION_IDENTIFIER@"
|
||||
#define APP_IOS_BUNDLE_ID "@CLIENT_IOS_BUNDLE_ID@"
|
||||
#define APP_IOS_STORE_URL_FALLBACK "@CLIENT_IOS_STORE_URL_FALLBACK@"
|
||||
#define APP_ANDROID_PACKAGE "@CLIENT_ANDROID_PACKAGE@"
|
||||
|
||||
#endif
|
||||
@@ -23,6 +23,7 @@ namespace apiDefs
|
||||
constexpr QLatin1String installationUuid("installation_uuid");
|
||||
constexpr QLatin1String uuid("installation_uuid");
|
||||
constexpr QLatin1String osVersion("os_version");
|
||||
constexpr QLatin1String distribution("distribution");
|
||||
constexpr QLatin1String userCountryCode("user_country_code");
|
||||
constexpr QLatin1String serverCountryCode("server_country_code");
|
||||
constexpr QLatin1String serverCountryName("server_country_name");
|
||||
@@ -40,6 +41,10 @@ namespace apiDefs
|
||||
constexpr QLatin1String lastDownloaded("last_downloaded");
|
||||
constexpr QLatin1String sourceType("source_type");
|
||||
constexpr QLatin1String appLanguage("app_language");
|
||||
constexpr QLatin1String locale("locale");
|
||||
|
||||
constexpr QLatin1String captchaId("captcha_id");
|
||||
constexpr QLatin1String captchaSolution("captcha_solution");
|
||||
|
||||
constexpr QLatin1String activeDeviceCount("active_device_count");
|
||||
constexpr QLatin1String maxDeviceCount("max_device_count");
|
||||
@@ -62,7 +67,6 @@ namespace apiDefs
|
||||
|
||||
constexpr QLatin1String id("id");
|
||||
constexpr QLatin1String orderId("order_id");
|
||||
constexpr QLatin1String migrationCode("migration_code");
|
||||
constexpr QLatin1String transactionId("transaction_id");
|
||||
constexpr QLatin1String isTestPurchase("is_test_purchase");
|
||||
constexpr QLatin1String isInAppPurchase("is_in_app_purchase");
|
||||
|
||||
@@ -100,6 +100,8 @@ namespace amnezia
|
||||
constexpr QLatin1String rejectAfterTime("RejectAfterTime");
|
||||
constexpr QLatin1String keepaliveTimeout("KeepaliveTimeout");
|
||||
constexpr QLatin1String maxHandshakeAttempts("MaxHandshakeAttempts");
|
||||
constexpr QLatin1String randomTrailers("RandomTrailers");
|
||||
constexpr QLatin1String disableCookies("DisableCookies");
|
||||
|
||||
inline QStringList awgProtocolKeys()
|
||||
{
|
||||
@@ -125,7 +127,9 @@ namespace amnezia
|
||||
rekeyTimeout,
|
||||
rejectAfterTime,
|
||||
keepaliveTimeout,
|
||||
maxHandshakeAttempts };
|
||||
maxHandshakeAttempts,
|
||||
randomTrailers,
|
||||
disableCookies };
|
||||
}
|
||||
|
||||
constexpr QLatin1String openvpn("openvpn");
|
||||
|
||||
@@ -204,7 +204,7 @@ namespace amnezia
|
||||
|
||||
constexpr char awgV1_5[] = "1.5";
|
||||
constexpr char awgV2[] = "2";
|
||||
constexpr char awgV3[] = "3";
|
||||
constexpr char awgV3[] = "3.1";
|
||||
|
||||
constexpr char defaultContentPaddingAddition[] = "10-100";
|
||||
constexpr char defaultRekeyAfterTime[] = "100-120";
|
||||
@@ -213,6 +213,10 @@ namespace amnezia
|
||||
constexpr char defaultKeepaliveTimeout[] = "5-15";
|
||||
constexpr char defaultMaxHandshakeAttempts[] = "15-20";
|
||||
constexpr char defaultPersistentKeepAlive[] = "25-35";
|
||||
constexpr char defaultRandomTrailers[] = "on";
|
||||
constexpr char defaultDisableCookies[] = "on";
|
||||
constexpr char awgBoolOn[] = "on";
|
||||
constexpr char awgBoolOff[] = "off";
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -112,8 +112,7 @@ QMap<DockerContainer, QString> ContainerUtils::containerDescriptions()
|
||||
QObject::tr("Replace the current DNS server with your own. This will increase your privacy level.") },
|
||||
{ DockerContainer::Sftp,
|
||||
QObject::tr("Create a file vault on your server to securely store and transfer files.") },
|
||||
{ DockerContainer::Socks5Proxy,
|
||||
QObject::tr("") },
|
||||
{ DockerContainer::Socks5Proxy, ("") },
|
||||
{ DockerContainer::MtProxy,
|
||||
QObject::tr("Telegram MTProto proxy server") },
|
||||
{ DockerContainer::Telemt,
|
||||
|
||||
@@ -97,7 +97,6 @@ namespace amnezia
|
||||
ApiServicesMissingError = 1107,
|
||||
ApiConfigLimitError = 1108,
|
||||
ApiNotFoundError = 1109,
|
||||
ApiMigrationError = 1110,
|
||||
ApiUpdateRequestError = 1111,
|
||||
ApiSubscriptionExpiredError = 1112,
|
||||
ApiPurchaseError = 1113,
|
||||
|
||||
@@ -89,7 +89,6 @@ QString errorString(ErrorCode code) {
|
||||
case (ErrorCode::ApiServicesMissingError): errorMessage = QObject::tr("Missing list of available services"); break;
|
||||
case (ErrorCode::ApiConfigLimitError): errorMessage = QObject::tr("The limit of allowed configurations per subscription has been exceeded"); break;
|
||||
case (ErrorCode::ApiNotFoundError): errorMessage = QObject::tr("Error when retrieving configuration from API"); break;
|
||||
case (ErrorCode::ApiMigrationError): errorMessage = QObject::tr("A migration error has occurred. Please contact our technical support"); break;
|
||||
case (ErrorCode::ApiUpdateRequestError): errorMessage = QObject::tr("Please update the application to use this feature"); break;
|
||||
case (ErrorCode::ApiSubscriptionExpiredError): errorMessage = QObject::tr("Your Amnezia Premium subscription has expired.\n Please check your email for renewal instructions.\n If you haven't received an email, please contact our support."); break;
|
||||
case (ErrorCode::ApiPurchaseError): errorMessage = QObject::tr("Unable to process purchase"); break;
|
||||
|
||||
@@ -53,7 +53,8 @@ QRegularExpression NetworkUtilities::ipAddressRegExp()
|
||||
QRegExp NetworkUtilities::ipAddressWithSubnetRegExp()
|
||||
{
|
||||
return QRegExp("(?:(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])\\.){3}"
|
||||
"(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])(\\/[0-9]{1,2}){0,1}");
|
||||
"(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])"
|
||||
"(\\/(?:[0-9]|[1-2][0-9]|3[0-2])){0,1}");
|
||||
}
|
||||
|
||||
QRegExp NetworkUtilities::ipNetwork24RegExp()
|
||||
@@ -78,12 +79,16 @@ QString NetworkUtilities::netMaskFromIpWithSubnet(const QString ip)
|
||||
if (!ip.contains("/"))
|
||||
return "255.255.255.255";
|
||||
|
||||
bool ok;
|
||||
int prefix = ip.split("/").at(1).toInt(&ok);
|
||||
if (!ok)
|
||||
const QStringList parts = ip.split("/");
|
||||
if (parts.size() < 2)
|
||||
return "255.255.255.255";
|
||||
|
||||
unsigned long mask = (0xFFFFFFFF << (32 - prefix)) & 0xFFFFFFFF;
|
||||
bool ok;
|
||||
int prefix = parts.at(1).toInt(&ok);
|
||||
if (!ok || prefix < 0 || prefix > 32)
|
||||
return "255.255.255.255";
|
||||
|
||||
const quint32 mask = prefix == 0 ? 0 : 0xFFFFFFFFu << (32 - prefix);
|
||||
|
||||
return QString("%1.%2.%3.%4").arg(mask >> 24).arg((mask >> 16) & 0xFF).arg((mask >> 8) & 0xFF).arg(mask & 0xFF);
|
||||
}
|
||||
|
||||
@@ -1,5 +1,8 @@
|
||||
#include "qrCodeUtils.h"
|
||||
|
||||
#include <cmath>
|
||||
|
||||
#include <QDataStream>
|
||||
#include <QIODevice>
|
||||
#include <QList>
|
||||
|
||||
@@ -16,7 +19,7 @@ QList<QString> qrCodeUtils::generateQrCodeImageSeries(const QByteArray &data)
|
||||
|
||||
QByteArray ba = chunk.toBase64(QByteArray::Base64UrlEncoding | QByteArray::OmitTrailingEquals);
|
||||
|
||||
qrcodegen::QrCode qr = qrcodegen::QrCode::encodeText(ba, qrcodegen::QrCode::Ecc::LOW);
|
||||
qrcodegen::QrCode qr = qrcodegen::QrCode::encodeText(ba.constData(), qrcodegen::QrCode::Ecc::LOW);
|
||||
QString svg = QString::fromStdString(toSvgString(qr, 1));
|
||||
chunks.append(svgToBase64(svg));
|
||||
}
|
||||
@@ -26,9 +29,13 @@ QList<QString> qrCodeUtils::generateQrCodeImageSeries(const QByteArray &data)
|
||||
|
||||
QString qrCodeUtils::generatePlainQrCodeImage(const QByteArray &data)
|
||||
{
|
||||
qrcodegen::QrCode qr = qrcodegen::QrCode::encodeText(data, qrcodegen::QrCode::Ecc::LOW);
|
||||
QString svg = QString::fromStdString(toSvgString(qr, 1));
|
||||
return svgToBase64(svg);
|
||||
try {
|
||||
qrcodegen::QrCode qr = qrcodegen::QrCode::encodeText(data.constData(), qrcodegen::QrCode::Ecc::LOW);
|
||||
QString svg = QString::fromStdString(toSvgString(qr, 1));
|
||||
return svgToBase64(svg);
|
||||
} catch (const qrcodegen::data_too_long &) {
|
||||
return {};
|
||||
}
|
||||
}
|
||||
|
||||
QString qrCodeUtils::svgToBase64(const QString &image)
|
||||
@@ -38,5 +45,5 @@ QString qrCodeUtils::svgToBase64(const QString &image)
|
||||
|
||||
qrcodegen::QrCode qrCodeUtils::generateQrCode(const QByteArray &data)
|
||||
{
|
||||
return qrcodegen::QrCode::encodeText(data, qrcodegen::QrCode::Ecc::LOW);
|
||||
return qrcodegen::QrCode::encodeText(data.constData(), qrcodegen::QrCode::Ecc::LOW);
|
||||
}
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
#ifndef QRCODEUTILS_H
|
||||
#define QRCODEUTILS_H
|
||||
|
||||
#include <QByteArray>
|
||||
#include <QList>
|
||||
#include <QString>
|
||||
|
||||
#include "qrcodegen.hpp"
|
||||
|
||||
@@ -255,9 +255,8 @@ amnezia::ScriptVars amnezia::genAwgVars(const ContainerConfig &containerConfig)
|
||||
vars.append({ { "$SPECIAL_JUNK_4", config.specialJunk4 } });
|
||||
vars.append({ { "$SPECIAL_JUNK_5", config.specialJunk5 } });
|
||||
|
||||
const bool isAwg3 = config.protocolVersion == protocols::awg::awgV3;
|
||||
vars.append({ { "$PERSISTENT_KEEPALIVE", isAwg3 ? QString(protocols::awg::defaultPersistentKeepAlive)
|
||||
: QString(protocols::wireguard::defaultPersistentKeepAlive) } });
|
||||
vars.append({ { "$PERSISTENT_KEEPALIVE", config.hasAwg3Params() ? QString(protocols::awg::defaultPersistentKeepAlive)
|
||||
: QString(protocols::wireguard::defaultPersistentKeepAlive) } });
|
||||
|
||||
vars.append({ { "$HEADER_PROTECTION_KEY", config.headerProtectionKey } });
|
||||
vars.append({ { "$CONTENT_PADDING_ADDITION", config.contentPaddingAddition } });
|
||||
@@ -266,6 +265,10 @@ amnezia::ScriptVars amnezia::genAwgVars(const ContainerConfig &containerConfig)
|
||||
vars.append({ { "$REJECT_AFTER_TIME", config.rejectAfterTime } });
|
||||
vars.append({ { "$KEEPALIVE_TIMEOUT", config.keepaliveTimeout } });
|
||||
vars.append({ { "$MAX_HANDSHAKE_ATTEMPTS", config.maxHandshakeAttempts } });
|
||||
vars.append({ { "$RANDOM_TRAILERS", AwgProtocolConfig::isToggleEnabled(config.randomTrailers)
|
||||
? config.randomTrailers : QString() } });
|
||||
vars.append({ { "$DISABLE_COOKIES", AwgProtocolConfig::isToggleEnabled(config.disableCookies)
|
||||
? config.disableCookies : QString() } });
|
||||
}
|
||||
|
||||
return vars;
|
||||
|
||||
25
client/core/utils/swiftBridge.h
Normal file
@@ -0,0 +1,25 @@
|
||||
#ifndef SWIFTBRIDGE_H
|
||||
#define SWIFTBRIDGE_H
|
||||
|
||||
#if defined(Q_OS_IOS) || defined(MACOS_NE)
|
||||
#include "core/utils/swiftBridgeConfig.h"
|
||||
|
||||
#ifndef SWIFT_BRIDGE_OBJC_HEADER
|
||||
#ifdef AMNEZIA_SWIFT_OBJC_HEADER
|
||||
#define SWIFT_BRIDGE_OBJC_HEADER AMNEZIA_SWIFT_OBJC_HEADER
|
||||
#else
|
||||
#define SWIFT_BRIDGE_OBJC_HEADER "AmneziaVPN-Swift.h"
|
||||
#endif
|
||||
#endif
|
||||
#ifndef SWIFT_BRIDGE_NAMESPACE
|
||||
#ifdef AMNEZIA_SWIFT_NAMESPACE
|
||||
#define SWIFT_BRIDGE_NAMESPACE AMNEZIA_SWIFT_NAMESPACE
|
||||
#else
|
||||
#define SWIFT_BRIDGE_NAMESPACE AmneziaVPN
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#include SWIFT_BRIDGE_OBJC_HEADER
|
||||
#endif
|
||||
|
||||
#endif
|
||||
7
client/core/utils/swiftBridgeConfig.h.in
Normal file
@@ -0,0 +1,7 @@
|
||||
#ifndef SWIFT_BRIDGE_CONFIG_H
|
||||
#define SWIFT_BRIDGE_CONFIG_H
|
||||
|
||||
#define SWIFT_BRIDGE_OBJC_HEADER "@CLIENT_SWIFT_OBJC_HEADER_NAME@"
|
||||
#define SWIFT_BRIDGE_NAMESPACE @CLIENT_SWIFT_MODULE_NAME@
|
||||
|
||||
#endif
|
||||
@@ -464,6 +464,12 @@ bool Daemon::parseConfig(const QJsonObject& obj, InterfaceConfig& config) {
|
||||
if (const auto maxHandshakeAttempts = obj.value("MaxHandshakeAttempts"); !maxHandshakeAttempts.isUndefined()) {
|
||||
config.m_maxHandshakeAttempts = maxHandshakeAttempts.toString();
|
||||
}
|
||||
if (const auto randomTrailers = obj.value("RandomTrailers"); !randomTrailers.isUndefined()) {
|
||||
config.m_randomTrailers = randomTrailers.toString();
|
||||
}
|
||||
if (const auto disableCookies = obj.value("DisableCookies"); !disableCookies.isUndefined()) {
|
||||
config.m_disableCookies = disableCookies.toString();
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -179,6 +179,12 @@ QString InterfaceConfig::toWgConf(const QMap<QString, QString>& extra) const {
|
||||
if (!m_maxHandshakeAttempts.isEmpty()) {
|
||||
out << "MaxHandshakeAttempts = " << m_maxHandshakeAttempts << "\n";
|
||||
}
|
||||
if (!m_randomTrailers.isEmpty()) {
|
||||
out << "RandomTrailers = " << m_randomTrailers << "\n";
|
||||
}
|
||||
if (!m_disableCookies.isEmpty()) {
|
||||
out << "DisableCookies = " << m_disableCookies << "\n";
|
||||
}
|
||||
|
||||
// If any extra config was provided, append it now.
|
||||
for (const QString& key : extra.keys()) {
|
||||
@@ -206,3 +212,13 @@ QString InterfaceConfig::toWgConf(const QMap<QString, QString>& extra) const {
|
||||
|
||||
return content;
|
||||
}
|
||||
|
||||
QString InterfaceConfig::awgBoolToUapi(const QString& value) {
|
||||
const QString v = value.trimmed().toLower();
|
||||
if (v == QLatin1String("on") || v == QLatin1String("1") ||
|
||||
v == QLatin1String("true") || v == QLatin1String("t") ||
|
||||
v == QLatin1String("yes")) {
|
||||
return QStringLiteral("1");
|
||||
}
|
||||
return QStringLiteral("0");
|
||||
}
|
||||
|
||||
@@ -66,10 +66,16 @@ class InterfaceConfig {
|
||||
QString m_rejectAfterTime;
|
||||
QString m_keepaliveTimeout;
|
||||
QString m_maxHandshakeAttempts;
|
||||
QString m_randomTrailers;
|
||||
QString m_disableCookies;
|
||||
|
||||
QJsonObject toJson() const;
|
||||
QString toWgConf(
|
||||
const QMap<QString, QString>& extra = QMap<QString, QString>()) const;
|
||||
|
||||
// Converts awg-quick on/off (and 0/1/true/false) to UAPI 1/0.
|
||||
// amneziawg-go uses strconv.ParseBool and rejects "on"/"off".
|
||||
static QString awgBoolToUapi(const QString& value);
|
||||
};
|
||||
|
||||
#endif // INTERFACECONFIG_H
|
||||
|
||||
@@ -31,7 +31,7 @@
|
||||
<key>LSSupportsOpeningDocumentsInPlace</key>
|
||||
<false/>
|
||||
<key>UILaunchStoryboardName</key>
|
||||
<string>AmneziaVPNLaunchScreen</string>
|
||||
<string>${CLIENT_IOS_LAUNCHSCREEN_NAME}</string>
|
||||
<key>UIApplicationSceneManifest</key>
|
||||
<dict>
|
||||
<key>UIApplicationSupportsMultipleScenes</key>
|
||||
@@ -70,11 +70,11 @@
|
||||
<key>UIUserInterfaceStyle</key>
|
||||
<string>Light</string>
|
||||
<key>com.wireguard.ios.app_group_id</key>
|
||||
<string>group.org.amnezia.AmneziaVPN</string>
|
||||
<string>${BUILD_IOS_GROUP_IDENTIFIER}</string>
|
||||
<key>UIViewControllerBasedStatusBarAppearance</key>
|
||||
<true/>
|
||||
<key>NSCameraUsageDescription</key>
|
||||
<string>Amnezia VPN needs access to the camera for reading QR-codes.</string>
|
||||
<string>${CLIENT_APPLICATION_NAME} needs access to the camera for reading QR-codes.</string>
|
||||
<key>NSAppTransportSecurity</key>
|
||||
<dict>
|
||||
<key>NSAllowsArbitraryLoads</key>
|
||||
@@ -116,11 +116,11 @@
|
||||
<string>public.data</string>
|
||||
</array>
|
||||
<key>UTTypeDescription</key>
|
||||
<string>Amnezia VPN config</string>
|
||||
<string>${CLIENT_APPLICATION_NAME} config</string>
|
||||
<key>UTTypeIconFiles</key>
|
||||
<array/>
|
||||
<key>UTTypeIdentifier</key>
|
||||
<string>org.amnezia.AmneziaVPN.amnezia-config</string>
|
||||
<string>${BUILD_IOS_APP_IDENTIFIER}.amnezia-config</string>
|
||||
<key>UTTypeTagSpecification</key>
|
||||
<dict>
|
||||
<key>public.filename-extension</key>
|
||||
@@ -143,7 +143,7 @@
|
||||
<key>UTTypeIconFiles</key>
|
||||
<array/>
|
||||
<key>UTTypeIdentifier</key>
|
||||
<string>org.amnezia.AmneziaVPN.wireguard-config</string>
|
||||
<string>${BUILD_IOS_APP_IDENTIFIER}.wireguard-config</string>
|
||||
<key>UTTypeTagSpecification</key>
|
||||
<dict>
|
||||
<key>public.filename-extension</key>
|
||||
@@ -167,7 +167,7 @@
|
||||
<key>UTTypeIconFiles</key>
|
||||
<array/>
|
||||
<key>UTTypeIdentifier</key>
|
||||
<string>org.amnezia.AmneziaVPN.openvpn-config</string>
|
||||
<string>${BUILD_IOS_APP_IDENTIFIER}.openvpn-config</string>
|
||||
<key>UTTypeTagSpecification</key>
|
||||
<dict>
|
||||
<key>public.filename-extension</key>
|
||||
@@ -186,11 +186,11 @@
|
||||
<string>public.data</string>
|
||||
</array>
|
||||
<key>UTTypeDescription</key>
|
||||
<string>AmneziaVPN backup file</string>
|
||||
<string>${CLIENT_APPLICATION_NAME} backup file</string>
|
||||
<key>UTTypeIconFiles</key>
|
||||
<array/>
|
||||
<key>UTTypeIdentifier</key>
|
||||
<string>org.amnezia.AmneziaVPN.backup-config</string>
|
||||
<string>${BUILD_IOS_APP_IDENTIFIER}.backup-config</string>
|
||||
<key>UTTypeTagSpecification</key>
|
||||
<dict>
|
||||
<key>public.filename-extension</key>
|
||||
@@ -208,15 +208,15 @@
|
||||
<array>
|
||||
<dict>
|
||||
<key>CFBundleTypeName</key>
|
||||
<string>Amnezia VPN config</string>
|
||||
<string>${CLIENT_APPLICATION_NAME} config</string>
|
||||
<key>LSHandlerRank</key>
|
||||
<string>Alternate</string>
|
||||
<key>LSItemContentTypes</key>
|
||||
<array>
|
||||
<string>org.amnezia.AmneziaVPN.amnezia-config</string>
|
||||
<string>org.amnezia.AmneziaVPN.wireguard-config</string>
|
||||
<string>org.amnezia.AmneziaVPN.openvpn-config</string>
|
||||
<string>org.amnezia.AmneziaVPN.backup-config</string>
|
||||
<string>${BUILD_IOS_APP_IDENTIFIER}.amnezia-config</string>
|
||||
<string>${BUILD_IOS_APP_IDENTIFIER}.wireguard-config</string>
|
||||
<string>${BUILD_IOS_APP_IDENTIFIER}.openvpn-config</string>
|
||||
<string>${BUILD_IOS_APP_IDENTIFIER}.backup-config</string>
|
||||
</array>
|
||||
</dict>
|
||||
</array>
|
||||
|
||||
@@ -2,24 +2,24 @@ enable_language(Swift)
|
||||
|
||||
set(CLIENT_ROOT_DIR ${CMAKE_CURRENT_LIST_DIR}/../..)
|
||||
|
||||
add_executable(networkextension)
|
||||
set_target_properties(networkextension PROPERTIES
|
||||
add_executable(${CLIENT_IOS_NE_TARGET_NAME})
|
||||
set_target_properties(${CLIENT_IOS_NE_TARGET_NAME} PROPERTIES
|
||||
XCODE_PRODUCT_TYPE com.apple.product-type.app-extension
|
||||
BUNDLE_EXTENSION appex
|
||||
|
||||
MACOSX_BUNDLE_INFO_PLIST ${CMAKE_CURRENT_SOURCE_DIR}/Info.plist.in
|
||||
MACOSX_BUNDLE_INFO_STRING "AmneziaVPNNetworkExtension"
|
||||
MACOSX_BUNDLE_BUNDLE_NAME "AmneziaVPNNetworkExtension"
|
||||
MACOSX_BUNDLE_INFO_STRING "${CLIENT_NETWORK_EXTENSION_NAME}"
|
||||
MACOSX_BUNDLE_BUNDLE_NAME "${CLIENT_NETWORK_EXTENSION_NAME}"
|
||||
MACOSX_BUNDLE_GUI_IDENTIFIER "${BUILD_IOS_APP_IDENTIFIER}.network-extension"
|
||||
MACOSX_BUNDLE_BUNDLE_VERSION "${CMAKE_PROJECT_VERSION_TWEAK}"
|
||||
MACOSX_BUNDLE_LONG_VERSION_STRING "${APPLE_PROJECT_VERSION}-${CMAKE_PROJECT_VERSION_TWEAK}"
|
||||
MACOSX_BUNDLE_SHORT_VERSION_STRING "${APPLE_PROJECT_VERSION}"
|
||||
|
||||
XCODE_ATTRIBUTE_PRODUCT_BUNDLE_IDENTIFIER "${BUILD_IOS_APP_IDENTIFIER}.network-extension"
|
||||
XCODE_ATTRIBUTE_CODE_SIGN_ENTITLEMENTS ${CMAKE_CURRENT_SOURCE_DIR}/AmneziaVPNNetworkExtension.entitlements
|
||||
XCODE_ATTRIBUTE_CODE_SIGN_ENTITLEMENTS ${CLIENT_IOS_NE_ENTITLEMENTS_PATH}
|
||||
XCODE_ATTRIBUTE_MARKETING_VERSION "${APP_MAJOR_VERSION}"
|
||||
XCODE_ATTRIBUTE_CURRENT_PROJECT_VERSION "${CMAKE_PROJECT_VERSION_TWEAK}"
|
||||
XCODE_ATTRIBUTE_PRODUCT_NAME "AmneziaVPNNetworkExtension"
|
||||
XCODE_ATTRIBUTE_PRODUCT_NAME "${CLIENT_NETWORK_EXTENSION_NAME}"
|
||||
|
||||
XCODE_ATTRIBUTE_APPLICATION_EXTENSION_API_ONLY "YES"
|
||||
XCODE_ATTRIBUTE_TARGETED_DEVICE_FAMILY "1,2"
|
||||
@@ -30,20 +30,20 @@ set_target_properties(networkextension PROPERTIES
|
||||
)
|
||||
|
||||
if(DEPLOY)
|
||||
set_target_properties(networkextension PROPERTIES
|
||||
set_target_properties(${CLIENT_IOS_NE_TARGET_NAME} PROPERTIES
|
||||
XCODE_ATTRIBUTE_CODE_SIGN_IDENTITY "Apple Distribution"
|
||||
XCODE_ATTRIBUTE_CODE_SIGN_IDENTITY[variant=Debug] "Apple Development"
|
||||
XCODE_ATTRIBUTE_CODE_SIGN_STYLE Manual
|
||||
XCODE_ATTRIBUTE_PROVISIONING_PROFILE_SPECIFIER "distr ios.org.amnezia.AmneziaVPN"
|
||||
XCODE_ATTRIBUTE_PROVISIONING_PROFILE_SPECIFIER[variant=Debug] "dev ios.org.amnezia.AmneziaVPN"
|
||||
XCODE_ATTRIBUTE_PROVISIONING_PROFILE_SPECIFIER "${CLIENT_IOS_NE_PROVISIONING_PROFILE_SPECIFIER}"
|
||||
XCODE_ATTRIBUTE_PROVISIONING_PROFILE_SPECIFIER[variant=Debug] "${CLIENT_IOS_NE_PROVISIONING_PROFILE_SPECIFIER_DEBUG}"
|
||||
)
|
||||
else()
|
||||
set_target_properties(networkextension PROPERTIES
|
||||
set_target_properties(${CLIENT_IOS_NE_TARGET_NAME} PROPERTIES
|
||||
XCODE_ATTRIBUTE_CODE_SIGN_STYLE Automatic
|
||||
)
|
||||
endif()
|
||||
|
||||
set_target_properties(networkextension PROPERTIES
|
||||
set_target_properties(${CLIENT_IOS_NE_TARGET_NAME} PROPERTIES
|
||||
XCODE_ATTRIBUTE_SWIFT_VERSION "5.0"
|
||||
XCODE_ATTRIBUTE_CLANG_ENABLE_MODULES "YES"
|
||||
XCODE_ATTRIBUTE_SWIFT_OBJC_BRIDGING_HEADER "${CMAKE_CURRENT_SOURCE_DIR}/WireGuardNetworkExtension-Bridging-Header.h"
|
||||
@@ -51,8 +51,8 @@ set_target_properties(networkextension PROPERTIES
|
||||
XCODE_ATTRIBUTE_SWIFT_PRECOMPILE_BRIDGING_HEADER "NO"
|
||||
)
|
||||
|
||||
set_target_properties("networkextension" PROPERTIES
|
||||
XCODE_ATTRIBUTE_DEVELOPMENT_TEAM "X7UJ388FXK"
|
||||
set_target_properties("${CLIENT_IOS_NE_TARGET_NAME}" PROPERTIES
|
||||
XCODE_ATTRIBUTE_DEVELOPMENT_TEAM "${BUILD_VPN_DEVELOPMENT_TEAM}"
|
||||
)
|
||||
|
||||
find_library(FW_ASSETS_LIBRARY AssetsLibrary)
|
||||
@@ -60,17 +60,17 @@ find_library(FW_MOBILE_CORE MobileCoreServices)
|
||||
find_library(FW_UI_KIT UIKit)
|
||||
find_library(FW_LIBRESOLV libresolv.9.tbd)
|
||||
|
||||
target_link_libraries(networkextension PRIVATE ${FW_ASSETS_LIBRARY})
|
||||
target_link_libraries(networkextension PRIVATE ${FW_MOBILE_CORE})
|
||||
target_link_libraries(networkextension PRIVATE ${FW_UI_KIT})
|
||||
target_link_libraries(networkextension PRIVATE ${FW_LIBRESOLV})
|
||||
target_link_libraries(${CLIENT_IOS_NE_TARGET_NAME} PRIVATE ${FW_ASSETS_LIBRARY})
|
||||
target_link_libraries(${CLIENT_IOS_NE_TARGET_NAME} PRIVATE ${FW_MOBILE_CORE})
|
||||
target_link_libraries(${CLIENT_IOS_NE_TARGET_NAME} PRIVATE ${FW_UI_KIT})
|
||||
target_link_libraries(${CLIENT_IOS_NE_TARGET_NAME} PRIVATE ${FW_LIBRESOLV})
|
||||
|
||||
target_compile_options(networkextension PRIVATE -DGROUP_ID=\"${BUILD_IOS_GROUP_IDENTIFIER}\")
|
||||
target_compile_options(networkextension PRIVATE -DNETWORK_EXTENSION=1)
|
||||
target_compile_options(${CLIENT_IOS_NE_TARGET_NAME} PRIVATE -DGROUP_ID=\"${BUILD_IOS_GROUP_IDENTIFIER}\")
|
||||
target_compile_options(${CLIENT_IOS_NE_TARGET_NAME} PRIVATE -DNETWORK_EXTENSION=1)
|
||||
|
||||
set(WG_APPLE_SOURCE_DIR ${CLIENT_ROOT_DIR}/3rd/amneziawg-apple/Sources)
|
||||
|
||||
target_sources(networkextension PRIVATE
|
||||
target_sources(${CLIENT_IOS_NE_TARGET_NAME} PRIVATE
|
||||
${WG_APPLE_SOURCE_DIR}/WireGuardKit/WireGuardAdapter.swift
|
||||
${WG_APPLE_SOURCE_DIR}/WireGuardKit/PacketTunnelSettingsGenerator.swift
|
||||
${WG_APPLE_SOURCE_DIR}/WireGuardKit/DNSResolver.swift
|
||||
@@ -93,6 +93,7 @@ target_sources(networkextension PRIVATE
|
||||
${CLIENT_ROOT_DIR}/platforms/ios/HevSocksTunnel.swift
|
||||
${CLIENT_ROOT_DIR}/platforms/ios/NELogController.swift
|
||||
${CLIENT_ROOT_DIR}/platforms/ios/Log.swift
|
||||
${CLIENT_GROUP_IDENTIFIER_SWIFT_FILE}
|
||||
${CLIENT_ROOT_DIR}/platforms/ios/LogRecord.swift
|
||||
${CLIENT_ROOT_DIR}/platforms/ios/PacketTunnelProvider.swift
|
||||
${CLIENT_ROOT_DIR}/platforms/ios/PacketTunnelProvider+WireGuard.swift
|
||||
@@ -103,16 +104,16 @@ target_sources(networkextension PRIVATE
|
||||
${CLIENT_ROOT_DIR}/platforms/ios/iosglue.mm
|
||||
)
|
||||
|
||||
target_sources(networkextension PRIVATE
|
||||
target_sources(${CLIENT_IOS_NE_TARGET_NAME} PRIVATE
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/PrivacyInfo.xcprivacy
|
||||
)
|
||||
|
||||
set_property(TARGET networkextension APPEND PROPERTY RESOURCE
|
||||
set_property(TARGET ${CLIENT_IOS_NE_TARGET_NAME} APPEND PROPERTY RESOURCE
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/PrivacyInfo.xcprivacy
|
||||
)
|
||||
|
||||
target_include_directories(networkextension PRIVATE ${CLIENT_ROOT_DIR})
|
||||
target_include_directories(networkextension PRIVATE ${CMAKE_CURRENT_BINARY_DIR})
|
||||
target_include_directories(${CLIENT_IOS_NE_TARGET_NAME} PRIVATE ${CLIENT_ROOT_DIR})
|
||||
target_include_directories(${CLIENT_IOS_NE_TARGET_NAME} PRIVATE ${CMAKE_CURRENT_BINARY_DIR})
|
||||
|
||||
find_package(openvpnadapter REQUIRED)
|
||||
# FIXME(ygurov): https://github.com/conan-io/conan/issues/20034
|
||||
@@ -120,10 +121,10 @@ set_property(TARGET amnezia::openvpnadapter APPEND PROPERTY IMPORTED_CONFIGURATI
|
||||
set_property(TARGET amnezia::openvpnadapter APPEND PROPERTY IMPORTED_CONFIGURATIONS MINSIZEREL)
|
||||
set_property(TARGET amnezia::openvpnadapter APPEND PROPERTY IMPORTED_CONFIGURATIONS RELEASE)
|
||||
set_property(TARGET amnezia::openvpnadapter APPEND PROPERTY IMPORTED_CONFIGURATIONS RELWITHDEBINFO)
|
||||
target_link_libraries(networkextension PRIVATE amnezia::openvpnadapter)
|
||||
target_link_libraries(${CLIENT_IOS_NE_TARGET_NAME} PRIVATE amnezia::openvpnadapter)
|
||||
|
||||
find_package(awg-apple REQUIRED)
|
||||
target_link_libraries(networkextension PRIVATE amnezia::awg-apple)
|
||||
target_link_libraries(${CLIENT_IOS_NE_TARGET_NAME} PRIVATE amnezia::awg-apple)
|
||||
|
||||
find_package(hev-socks5-tunnel REQUIRED)
|
||||
# FIXME(ygurov): https://github.com/conan-io/conan/issues/20034
|
||||
@@ -131,4 +132,4 @@ set_property(TARGET heiher::hev-socks5-tunnel APPEND PROPERTY IMPORTED_CONFIGURA
|
||||
set_property(TARGET heiher::hev-socks5-tunnel APPEND PROPERTY IMPORTED_CONFIGURATIONS MINSIZEREL)
|
||||
set_property(TARGET heiher::hev-socks5-tunnel APPEND PROPERTY IMPORTED_CONFIGURATIONS RELEASE)
|
||||
set_property(TARGET heiher::hev-socks5-tunnel APPEND PROPERTY IMPORTED_CONFIGURATIONS RELWITHDEBINFO)
|
||||
target_link_libraries(networkextension PRIVATE heiher::hev-socks5-tunnel)
|
||||
target_link_libraries(${CLIENT_IOS_NE_TARGET_NAME} PRIVATE heiher::hev-socks5-tunnel)
|
||||
|
||||
@@ -38,9 +38,9 @@
|
||||
</dict>
|
||||
|
||||
<key>com.wireguard.ios.app_group_id</key>
|
||||
<string>group.${BUILD_IOS_APP_IDENTIFIER}</string>
|
||||
<string>${BUILD_IOS_GROUP_IDENTIFIER}</string>
|
||||
|
||||
<key>com.wireguard.macos.app_group_id</key>
|
||||
<string>${BUILD_VPN_DEVELOPMENT_TEAM}.group.${BUILD_OSX_APP_IDENTIFIER}</string>
|
||||
<string>${BUILD_VPN_DEVELOPMENT_TEAM}.${BUILD_IOS_GROUP_IDENTIFIER}</string>
|
||||
</dict>
|
||||
</plist>
|
||||
@@ -34,9 +34,9 @@
|
||||
<key>LSSupportsOpeningDocumentsInPlace</key>
|
||||
<true/>
|
||||
<key>com.wireguard.ios.app_group_id</key>
|
||||
<string>group.org.amnezia.AmneziaVPN</string>
|
||||
<string>${BUILD_IOS_GROUP_IDENTIFIER}</string>
|
||||
<key>NSCameraUsageDescription</key>
|
||||
<string>Amnezia VPN needs access to the camera for reading QR-codes.</string>
|
||||
<string>${CLIENT_APPLICATION_NAME} needs access to the camera for reading QR-codes.</string>
|
||||
<key>NSAppTransportSecurity</key>
|
||||
<dict>
|
||||
<key>NSAllowsArbitraryLoads</key>
|
||||
@@ -66,11 +66,11 @@
|
||||
<string>public.data</string>
|
||||
</array>
|
||||
<key>UTTypeDescription</key>
|
||||
<string>Amnezia VPN config</string>
|
||||
<string>${CLIENT_APPLICATION_NAME} config</string>
|
||||
<key>UTTypeIconFiles</key>
|
||||
<array/>
|
||||
<key>UTTypeIdentifier</key>
|
||||
<string>org.amnezia.AmneziaVPN.amnezia-config</string>
|
||||
<string>${BUILD_OSX_APP_IDENTIFIER}.amnezia-config</string>
|
||||
<key>UTTypeTagSpecification</key>
|
||||
<dict>
|
||||
<key>public.filename-extension</key>
|
||||
@@ -93,7 +93,7 @@
|
||||
<key>UTTypeIconFiles</key>
|
||||
<array/>
|
||||
<key>UTTypeIdentifier</key>
|
||||
<string>org.amnezia.AmneziaVPN.wireguard-config</string>
|
||||
<string>${BUILD_OSX_APP_IDENTIFIER}.wireguard-config</string>
|
||||
<key>UTTypeTagSpecification</key>
|
||||
<dict>
|
||||
<key>public.filename-extension</key>
|
||||
@@ -117,7 +117,7 @@
|
||||
<key>UTTypeIconFiles</key>
|
||||
<array/>
|
||||
<key>UTTypeIdentifier</key>
|
||||
<string>org.amnezia.AmneziaVPN.openvpn-config</string>
|
||||
<string>${BUILD_OSX_APP_IDENTIFIER}.openvpn-config</string>
|
||||
<key>UTTypeTagSpecification</key>
|
||||
<dict>
|
||||
<key>public.filename-extension</key>
|
||||
@@ -136,11 +136,11 @@
|
||||
<string>public.data</string>
|
||||
</array>
|
||||
<key>UTTypeDescription</key>
|
||||
<string>AmneziaVPN backup file</string>
|
||||
<string>${CLIENT_APPLICATION_NAME} backup file</string>
|
||||
<key>UTTypeIconFiles</key>
|
||||
<array/>
|
||||
<key>UTTypeIdentifier</key>
|
||||
<string>org.amnezia.AmneziaVPN.backup-config</string>
|
||||
<string>${BUILD_OSX_APP_IDENTIFIER}.backup-config</string>
|
||||
<key>UTTypeTagSpecification</key>
|
||||
<dict>
|
||||
<key>public.filename-extension</key>
|
||||
@@ -158,15 +158,15 @@
|
||||
<array>
|
||||
<dict>
|
||||
<key>CFBundleTypeName</key>
|
||||
<string>Amnezia VPN config</string>
|
||||
<string>${CLIENT_APPLICATION_NAME} config</string>
|
||||
<key>LSHandlerRank</key>
|
||||
<string>Alternate</string>
|
||||
<key>LSItemContentTypes</key>
|
||||
<array>
|
||||
<string>org.amnezia.AmneziaVPN.amnezia-config</string>
|
||||
<string>org.amnezia.AmneziaVPN.wireguard-config</string>
|
||||
<string>org.amnezia.AmneziaVPN.openvpn-config</string>
|
||||
<string>org.amnezia.AmneziaVPN.backup-config</string>
|
||||
<string>${BUILD_OSX_APP_IDENTIFIER}.amnezia-config</string>
|
||||
<string>${BUILD_OSX_APP_IDENTIFIER}.wireguard-config</string>
|
||||
<string>${BUILD_OSX_APP_IDENTIFIER}.openvpn-config</string>
|
||||
<string>${BUILD_OSX_APP_IDENTIFIER}.backup-config</string>
|
||||
</array>
|
||||
</dict>
|
||||
</array>
|
||||
@@ -180,5 +180,6 @@
|
||||
</dict>
|
||||
</array>
|
||||
|
||||
${CLIENT_MACOS_EXTRA_PLIST_ENTRIES}
|
||||
</dict>
|
||||
</plist>
|
||||
|
||||
@@ -1,22 +1,27 @@
|
||||
enable_language(Swift)
|
||||
message("Client message >> macos build >> AmneziaVPNNetworkExtension")
|
||||
message("Client message >> macos build >> ${CLIENT_MACOS_NE_TARGET_NAME}")
|
||||
set(CLIENT_ROOT_DIR ${CMAKE_CURRENT_LIST_DIR}/../..)
|
||||
|
||||
add_executable(AmneziaVPNNetworkExtension)
|
||||
add_executable(${CLIENT_MACOS_NE_TARGET_NAME})
|
||||
|
||||
message("executable_path is: @executable_path/../../Frameworks")
|
||||
set_target_properties(AmneziaVPNNetworkExtension PROPERTIES
|
||||
|
||||
# The plist is consumed by Xcode directly, so branding variables have to be
|
||||
# substituted by CMake beforehand
|
||||
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/Info.plist.in ${CMAKE_CURRENT_BINARY_DIR}/Info.plist)
|
||||
|
||||
set_target_properties(${CLIENT_MACOS_NE_TARGET_NAME} PROPERTIES
|
||||
XCODE_PRODUCT_TYPE com.apple.product-type.app-extension
|
||||
BUNDLE_EXTENSION appex
|
||||
XCODE_ATTRIBUTE_PRODUCT_BUNDLE_IDENTIFIER "${BUILD_IOS_APP_IDENTIFIER}.network-extension"
|
||||
XCODE_ATTRIBUTE_CODE_SIGN_ENTITLEMENTS ${CMAKE_CURRENT_SOURCE_DIR}/AmneziaVPNNetworkExtension.entitlements
|
||||
XCODE_ATTRIBUTE_CODE_SIGN_ENTITLEMENTS ${CLIENT_MACOS_NE_ENTITLEMENTS_PATH}
|
||||
XCODE_ATTRIBUTE_MARKETING_VERSION "${APP_MAJOR_VERSION}"
|
||||
XCODE_ATTRIBUTE_CURRENT_PROJECT_VERSION "${CMAKE_PROJECT_VERSION_TWEAK}"
|
||||
XCODE_ATTRIBUTE_PRODUCT_NAME "AmneziaVPNNetworkExtension"
|
||||
XCODE_ATTRIBUTE_PRODUCT_NAME "${CLIENT_NETWORK_EXTENSION_NAME}"
|
||||
|
||||
XCODE_ATTRIBUTE_APPLICATION_EXTENSION_API_ONLY "YES"
|
||||
|
||||
XCODE_ATTRIBUTE_INFOPLIST_FILE ${CMAKE_CURRENT_SOURCE_DIR}/Info.plist.in
|
||||
XCODE_ATTRIBUTE_INFOPLIST_FILE ${CMAKE_CURRENT_BINARY_DIR}/Info.plist
|
||||
XCODE_ATTRIBUTE_LD_RUNPATH_SEARCH_PATHS "@executable_path/../../../../Frameworks @loader_path/../../../../Frameworks"
|
||||
|
||||
XCODE_LINK_BUILD_PHASE_MODE KNOWN_LOCATION
|
||||
@@ -24,20 +29,20 @@ set_target_properties(AmneziaVPNNetworkExtension PROPERTIES
|
||||
|
||||
if(DEPLOY)
|
||||
message("DEPLOY is ON")
|
||||
set_target_properties(AmneziaVPNNetworkExtension PROPERTIES
|
||||
set_target_properties(${CLIENT_MACOS_NE_TARGET_NAME} PROPERTIES
|
||||
XCODE_ATTRIBUTE_CODE_SIGN_IDENTITY "Apple Distribution"
|
||||
XCODE_ATTRIBUTE_CODE_SIGN_IDENTITY[variant=Debug] "Apple Development"
|
||||
XCODE_ATTRIBUTE_CODE_SIGN_STYLE Manual
|
||||
XCODE_ATTRIBUTE_PROVISIONING_PROFILE_SPECIFIER "distr macos.org.amnezia.amneziaVPN.NE"
|
||||
XCODE_ATTRIBUTE_PROVISIONING_PROFILE_SPECIFIER[variant=Debug] "dev macos.org.amnezia.amneziaVPN.NE"
|
||||
XCODE_ATTRIBUTE_PROVISIONING_PROFILE_SPECIFIER "${CLIENT_MACOS_NE_PROVISIONING_PROFILE_SPECIFIER}"
|
||||
XCODE_ATTRIBUTE_PROVISIONING_PROFILE_SPECIFIER[variant=Debug] "${CLIENT_MACOS_NE_PROVISIONING_PROFILE_SPECIFIER_DEBUG}"
|
||||
)
|
||||
else()
|
||||
set_target_properties(AmneziaVPNNetworkExtension PROPERTIES
|
||||
set_target_properties(${CLIENT_MACOS_NE_TARGET_NAME} PROPERTIES
|
||||
XCODE_ATTRIBUTE_CODE_SIGN_STYLE Automatic
|
||||
)
|
||||
endif()
|
||||
|
||||
set_target_properties(AmneziaVPNNetworkExtension PROPERTIES
|
||||
set_target_properties(${CLIENT_MACOS_NE_TARGET_NAME} PROPERTIES
|
||||
XCODE_ATTRIBUTE_SWIFT_VERSION "5.0"
|
||||
XCODE_ATTRIBUTE_CLANG_ENABLE_MODULES "YES"
|
||||
XCODE_ATTRIBUTE_SWIFT_OBJC_BRIDGING_HEADER "${CMAKE_CURRENT_SOURCE_DIR}/WireGuardNetworkExtension-Bridging-Header.h"
|
||||
@@ -45,8 +50,8 @@ set_target_properties(AmneziaVPNNetworkExtension PROPERTIES
|
||||
XCODE_ATTRIBUTE_SWIFT_PRECOMPILE_BRIDGING_HEADER "NO"
|
||||
)
|
||||
|
||||
set_target_properties("AmneziaVPNNetworkExtension" PROPERTIES
|
||||
XCODE_ATTRIBUTE_DEVELOPMENT_TEAM "X7UJ388FXK"
|
||||
set_target_properties("${CLIENT_MACOS_NE_TARGET_NAME}" PROPERTIES
|
||||
XCODE_ATTRIBUTE_DEVELOPMENT_TEAM "${BUILD_VPN_DEVELOPMENT_TEAM}"
|
||||
)
|
||||
|
||||
find_library(FW_ASSETS_LIBRARY AssetsLibrary)
|
||||
@@ -58,17 +63,17 @@ find_library(FW_LIBRESOLV libresolv.9.tbd)
|
||||
# Set the root directory
|
||||
set(CLIENT_ROOT_DIR ${CMAKE_CURRENT_LIST_DIR}/../..)
|
||||
|
||||
target_link_libraries(AmneziaVPNNetworkExtension PRIVATE ${FW_LIBRESOLV})
|
||||
target_link_libraries(${CLIENT_MACOS_NE_TARGET_NAME} PRIVATE ${FW_LIBRESOLV})
|
||||
|
||||
target_compile_options(AmneziaVPNNetworkExtension PRIVATE -DGROUP_ID=\"${BUILD_IOS_GROUP_IDENTIFIER}\")
|
||||
target_compile_options(AmneziaVPNNetworkExtension PRIVATE -DNETWORK_EXTENSION=1)
|
||||
target_compile_options(${CLIENT_MACOS_NE_TARGET_NAME} PRIVATE -DGROUP_ID=\"${BUILD_IOS_GROUP_IDENTIFIER}\")
|
||||
target_compile_options(${CLIENT_MACOS_NE_TARGET_NAME} PRIVATE -DNETWORK_EXTENSION=1)
|
||||
|
||||
set(WG_APPLE_SOURCE_DIR ${CLIENT_ROOT_DIR}/3rd/amneziawg-apple/Sources)
|
||||
|
||||
message("WG_APPLE_SOURCE_DIR is: ${WG_APPLE_SOURCE_DIR}")
|
||||
message("CLIENT_ROOT_DIR is: ${CLIENT_ROOT_DIR}")
|
||||
|
||||
target_sources(AmneziaVPNNetworkExtension PRIVATE
|
||||
target_sources(${CLIENT_MACOS_NE_TARGET_NAME} PRIVATE
|
||||
${WG_APPLE_SOURCE_DIR}/WireGuardKit/WireGuardAdapter.swift
|
||||
${WG_APPLE_SOURCE_DIR}/WireGuardKit/PacketTunnelSettingsGenerator.swift
|
||||
${WG_APPLE_SOURCE_DIR}/WireGuardKit/DNSResolver.swift
|
||||
@@ -91,6 +96,7 @@ target_sources(AmneziaVPNNetworkExtension PRIVATE
|
||||
${CLIENT_ROOT_DIR}/platforms/ios/HevSocksTunnel.swift
|
||||
${CLIENT_ROOT_DIR}/platforms/ios/NELogController.swift
|
||||
${CLIENT_ROOT_DIR}/platforms/ios/Log.swift
|
||||
${CLIENT_GROUP_IDENTIFIER_SWIFT_FILE}
|
||||
${CLIENT_ROOT_DIR}/platforms/ios/LogRecord.swift
|
||||
${CLIENT_ROOT_DIR}/platforms/ios/PacketTunnelProvider.swift
|
||||
${CLIENT_ROOT_DIR}/platforms/ios/PacketTunnelProvider+WireGuard.swift
|
||||
@@ -101,16 +107,16 @@ target_sources(AmneziaVPNNetworkExtension PRIVATE
|
||||
${CLIENT_ROOT_DIR}/platforms/ios/XrayConfig.swift
|
||||
)
|
||||
|
||||
target_sources(AmneziaVPNNetworkExtension PRIVATE
|
||||
target_sources(${CLIENT_MACOS_NE_TARGET_NAME} PRIVATE
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/PrivacyInfo.xcprivacy
|
||||
)
|
||||
|
||||
set_property(TARGET AmneziaVPNNetworkExtension APPEND PROPERTY RESOURCE
|
||||
set_property(TARGET ${CLIENT_MACOS_NE_TARGET_NAME} APPEND PROPERTY RESOURCE
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/PrivacyInfo.xcprivacy
|
||||
)
|
||||
|
||||
target_include_directories(AmneziaVPNNetworkExtension PRIVATE ${CLIENT_ROOT_DIR})
|
||||
target_include_directories(AmneziaVPNNetworkExtension PRIVATE ${CMAKE_CURRENT_BINARY_DIR})
|
||||
target_include_directories(${CLIENT_MACOS_NE_TARGET_NAME} PRIVATE ${CLIENT_ROOT_DIR})
|
||||
target_include_directories(${CLIENT_MACOS_NE_TARGET_NAME} PRIVATE ${CMAKE_CURRENT_BINARY_DIR})
|
||||
|
||||
find_package(openvpnadapter REQUIRED)
|
||||
# FIXME(ygurov): https://github.com/conan-io/conan/issues/20034
|
||||
@@ -118,10 +124,10 @@ set_property(TARGET amnezia::openvpnadapter APPEND PROPERTY IMPORTED_CONFIGURATI
|
||||
set_property(TARGET amnezia::openvpnadapter APPEND PROPERTY IMPORTED_CONFIGURATIONS MINSIZEREL)
|
||||
set_property(TARGET amnezia::openvpnadapter APPEND PROPERTY IMPORTED_CONFIGURATIONS RELEASE)
|
||||
set_property(TARGET amnezia::openvpnadapter APPEND PROPERTY IMPORTED_CONFIGURATIONS RELWITHDEBINFO)
|
||||
target_link_libraries(AmneziaVPNNetworkExtension PRIVATE amnezia::openvpnadapter)
|
||||
target_link_libraries(${CLIENT_MACOS_NE_TARGET_NAME} PRIVATE amnezia::openvpnadapter)
|
||||
|
||||
find_package(awg-apple REQUIRED)
|
||||
target_link_libraries(AmneziaVPNNetworkExtension PRIVATE amnezia::awg-apple)
|
||||
target_link_libraries(${CLIENT_MACOS_NE_TARGET_NAME} PRIVATE amnezia::awg-apple)
|
||||
|
||||
find_package(hev-socks5-tunnel REQUIRED)
|
||||
# FIXME(ygurov): https://github.com/conan-io/conan/issues/20034
|
||||
@@ -129,4 +135,4 @@ set_property(TARGET heiher::hev-socks5-tunnel APPEND PROPERTY IMPORTED_CONFIGURA
|
||||
set_property(TARGET heiher::hev-socks5-tunnel APPEND PROPERTY IMPORTED_CONFIGURATIONS MINSIZEREL)
|
||||
set_property(TARGET heiher::hev-socks5-tunnel APPEND PROPERTY IMPORTED_CONFIGURATIONS RELEASE)
|
||||
set_property(TARGET heiher::hev-socks5-tunnel APPEND PROPERTY IMPORTED_CONFIGURATIONS RELWITHDEBINFO)
|
||||
target_link_libraries(AmneziaVPNNetworkExtension PRIVATE heiher::hev-socks5-tunnel)
|
||||
target_link_libraries(${CLIENT_MACOS_NE_TARGET_NAME} PRIVATE heiher::hev-socks5-tunnel)
|
||||
|
||||
@@ -5,14 +5,14 @@
|
||||
<key>CFBundleDevelopmentRegion</key>
|
||||
<string>en</string>
|
||||
<key>CFBundleExecutable</key>
|
||||
<string>AmneziaVPNNetworkExtension</string>
|
||||
<string>${CLIENT_NETWORK_EXTENSION_NAME}</string>
|
||||
|
||||
<key>CFBundleIdentifier</key>
|
||||
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
|
||||
<key>CFBundleInfoDictionaryVersion</key>
|
||||
<string>6.0</string>
|
||||
<key>CFBundleName</key>
|
||||
<string>AmneziaVPNNetworkExtension</string>
|
||||
<string>${CLIENT_NETWORK_EXTENSION_NAME}</string>
|
||||
<key>CFBundlePackageType</key>
|
||||
<string>$(PRODUCT_BUNDLE_PACKAGE_TYPE)</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
@@ -27,7 +27,7 @@
|
||||
<string>$(MACOSX_DEPLOYMENT_TARGET)</string>
|
||||
|
||||
<key>CFBundleDisplayName</key>
|
||||
<string>AmneziaVPNNetworkExtension</string>
|
||||
<string>${CLIENT_NETWORK_EXTENSION_NAME}</string>
|
||||
|
||||
<key>NSExtension</key>
|
||||
<dict>
|
||||
@@ -38,9 +38,9 @@
|
||||
</dict>
|
||||
|
||||
<key>com.wireguard.ios.app_group_id</key>
|
||||
<string>group.org.amnezia.AmneziaVPN</string>
|
||||
<string>${BUILD_IOS_GROUP_IDENTIFIER}</string>
|
||||
|
||||
<key>com.wireguard.macos.app_group_id</key>
|
||||
<string>$(DEVELOPMENT_TEAM).group.org.amnezia.AmneziaVPN</string>
|
||||
<string>$(DEVELOPMENT_TEAM).${BUILD_IOS_GROUP_IDENTIFIER}</string>
|
||||
</dict>
|
||||
</plist>
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
#include "amneziaApplication.h"
|
||||
#include "core/utils/osSignalHandler.h"
|
||||
#include "core/utils/migrations.h"
|
||||
#include "core/utils/appUiConfig.h"
|
||||
#include "version.h"
|
||||
|
||||
|
||||
@@ -26,9 +27,9 @@ void anchorOpenSSL() {
|
||||
bool isAnotherInstanceRunning()
|
||||
{
|
||||
QLocalSocket socket;
|
||||
socket.connectToServer("AmneziaVPNInstance");
|
||||
socket.connectToServer(APP_INSTANCE_NAME);
|
||||
if (socket.waitForConnected(500)) {
|
||||
qWarning() << "AmneziaVPN is already running";
|
||||
qWarning() << APPLICATION_NAME << "is already running";
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
|
||||
3
client/platforms/ios/GroupIdentifier.swift.in
Normal file
@@ -0,0 +1,3 @@
|
||||
enum BuildConfig {
|
||||
static let appGroupIdentifier = "@BUILD_IOS_GROUP_IDENTIFIER@"
|
||||
}
|
||||
@@ -15,7 +15,7 @@ struct Log {
|
||||
}
|
||||
}
|
||||
|
||||
private static let appGroupID = "group.org.amnezia.AmneziaVPN"
|
||||
private static let appGroupID = BuildConfig.appGroupIdentifier
|
||||
|
||||
static let appLogURL = {
|
||||
let sharedContainerURL = FileManager.default.containerURL(forSecurityApplicationGroupIdentifier: appGroupID)!
|
||||
|
||||
@@ -92,7 +92,7 @@ extension PacketTunnelProvider {
|
||||
}
|
||||
}
|
||||
} catch {
|
||||
wg_log(.error, message: "Can't parse WG config: \(error.localizedDescription)")
|
||||
wg_log(.error, message: "Can't parse WG config: \(String(describing: error))")
|
||||
errorNotifier.notify(PacketTunnelProviderError.savedProtocolConfigurationIsInvalid)
|
||||
completionHandler(PacketTunnelProviderError.savedProtocolConfigurationIsInvalid)
|
||||
return
|
||||
|
||||
@@ -4,7 +4,8 @@
|
||||
|
||||
#import "StoreKitController.h"
|
||||
#import <StoreKit/StoreKit.h>
|
||||
#import <AmneziaVPN-Swift.h>
|
||||
#include <QtCore/qglobal.h>
|
||||
#import "core/utils/swiftBridge.h"
|
||||
|
||||
#include <QtCore/QDebug>
|
||||
#include <QtCore/QString>
|
||||
|
||||
@@ -8,6 +8,7 @@ struct WGConfig: Decodable {
|
||||
let specialJunk1, specialJunk2, specialJunk3, specialJunk4, specialJunk5: String?
|
||||
let headerProtectionKey: String?
|
||||
let contentPaddingAddition, rekeyAfterTime, rekeyTimeout, rejectAfterTime, keepaliveTimeout, maxHandshakeAttempts: String?
|
||||
let randomTrailers, disableCookies: String?
|
||||
let dns1: String
|
||||
let dns2: String
|
||||
let mtu: String
|
||||
@@ -33,6 +34,7 @@ struct WGConfig: Decodable {
|
||||
case rekeyAfterTime = "RekeyAfterTime", rekeyTimeout = "RekeyTimeout"
|
||||
case rejectAfterTime = "RejectAfterTime", keepaliveTimeout = "KeepaliveTimeout"
|
||||
case maxHandshakeAttempts = "MaxHandshakeAttempts"
|
||||
case randomTrailers = "RandomTrailers", disableCookies = "DisableCookies"
|
||||
case dns1
|
||||
case dns2
|
||||
case mtu
|
||||
@@ -128,6 +130,12 @@ struct WGConfig: Decodable {
|
||||
if let maxHandshakeAttempts = trimmed(maxHandshakeAttempts) {
|
||||
settingsLines.append("MaxHandshakeAttempts = \(maxHandshakeAttempts)")
|
||||
}
|
||||
if let randomTrailers = trimmed(randomTrailers) {
|
||||
settingsLines.append("RandomTrailers = \(randomTrailers)")
|
||||
}
|
||||
if let disableCookies = trimmed(disableCookies) {
|
||||
settingsLines.append("DisableCookies = \(disableCookies)")
|
||||
}
|
||||
|
||||
return settingsLines.joined(separator: "\n")
|
||||
}
|
||||
|
||||
@@ -4,6 +4,8 @@
|
||||
|
||||
#include "platforms/ios/iosnotificationhandler.h"
|
||||
|
||||
#include "core/utils/appUiConfig.h"
|
||||
|
||||
#import <UserNotifications/UserNotifications.h>
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
@@ -75,7 +77,8 @@ void IOSNotificationHandler::notify(NotificationHandler::Message type, const QSt
|
||||
UNTimeIntervalNotificationTrigger* trigger =
|
||||
[UNTimeIntervalNotificationTrigger triggerWithTimeInterval:timerSec repeats:NO];
|
||||
|
||||
UNNotificationRequest* request = [UNNotificationRequest requestWithIdentifier:@"amneziavpn"
|
||||
UNNotificationRequest* request =
|
||||
[UNNotificationRequest requestWithIdentifier:[NSString stringWithUTF8String:APP_NOTIFICATION_IDENTIFIER]
|
||||
content:content
|
||||
trigger:trigger];
|
||||
|
||||
@@ -157,7 +160,8 @@ void IOSNotificationHandler::notify(NotificationHandler::Message type, const QSt
|
||||
UNTimeIntervalNotificationTrigger* trigger =
|
||||
[UNTimeIntervalNotificationTrigger triggerWithTimeInterval:timerSec repeats:NO];
|
||||
|
||||
UNNotificationRequest* request = [UNNotificationRequest requestWithIdentifier:@"amneziavpn"
|
||||
UNNotificationRequest* request =
|
||||
[UNNotificationRequest requestWithIdentifier:[NSString stringWithUTF8String:APP_NOTIFICATION_IDENTIFIER]
|
||||
content:content
|
||||
trigger:trigger];
|
||||
|
||||
|
||||
@@ -33,6 +33,7 @@
|
||||
#include "linuxfirewall.h"
|
||||
#include "logger.h"
|
||||
#include "xray_defs.h"
|
||||
#include <QFileInfo>
|
||||
#include <QProcess>
|
||||
|
||||
#define BRAND_CODE "amn"
|
||||
@@ -109,7 +110,7 @@ int LinuxFirewall::linkChain(LinuxFirewall::IPVersion ip, const QString& chain,
|
||||
// (we can't safely delete all rules at once since rule numbers change)
|
||||
// TODO: occasionally this script results in warnings in logs "Bad rule (does a matching rule exist in the chain?)" - this happens when
|
||||
// the e.g OUTPUT chain is empty but this script attempts to delete things from it anyway. It doesn't cause any problems, but we should still fix at some point..
|
||||
return execute(QStringLiteral("if ! %1 -L %2 -n --line-numbers -t %4 2> /dev/null | awk 'int($1) == 1 && $2 == \"%3\" { found=1 } END { if(found==1) { exit 0 } else { exit 1 } }' ; then %1 -I %2 -j %3 -t %4 && %1 -L %2 -n --line-numbers -t %4 2> /dev/null | awk 'int($1) > 1 && $2 == \"%3\" { print $1; exit }' | xargs %1 -t %4 -D %2 ; fi").arg(cmd, parent, chain, tableName));
|
||||
return execute(QStringLiteral("if ! %1 -L %2 -n --line-numbers -t %4 2> /dev/null | awk 'int($1) == 1 && $2 == \"%3\" { found=1 } END { if(found==1) { exit 0 } else { exit 1 } }' ; then %1 -I %2 -j %3 -t %4 && %1 -L %2 -n --line-numbers -t %4 2> /dev/null | awk 'int($1) > 1 && $2 == \"%3\" { print $1; exit }' | xargs -r %1 -t %4 -D %2 ; fi").arg(cmd, parent, chain, tableName));
|
||||
}
|
||||
else
|
||||
return execute(QStringLiteral("if ! %1 -C %2 -j %3 -t %4 2> /dev/null ; then %1 -A %2 -j %3 -t %4; fi").arg(cmd, parent, chain, tableName));
|
||||
@@ -188,40 +189,6 @@ void LinuxFirewall::uninstallAnchor(LinuxFirewall::IPVersion ip, const QString&
|
||||
deleteChain(ip, actualChain, tableName);
|
||||
}
|
||||
|
||||
QStringList LinuxFirewall::getDNSRules(const QStringList& servers)
|
||||
{
|
||||
QStringList result;
|
||||
for (const QString& server : servers)
|
||||
{
|
||||
result << QStringLiteral("-o amn0+ -d %1 -p udp --dport 53 -j ACCEPT").arg(server);
|
||||
result << QStringLiteral("-o amn0+ -d %1 -p tcp --dport 53 -j ACCEPT").arg(server);
|
||||
result << QStringLiteral("-o tun0+ -d %1 -p udp --dport 53 -j ACCEPT").arg(server);
|
||||
result << QStringLiteral("-o tun0+ -d %1 -p tcp --dport 53 -j ACCEPT").arg(server);
|
||||
result << QStringLiteral("-o tun2+ -d %1 -p udp --dport 53 -j ACCEPT").arg(server);
|
||||
result << QStringLiteral("-o tun2+ -d %1 -p tcp --dport 53 -j ACCEPT").arg(server);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
QStringList LinuxFirewall::getAllowRule(const QStringList& servers)
|
||||
{
|
||||
QStringList result;
|
||||
for (const QString& server : servers)
|
||||
{
|
||||
result << QStringLiteral("-d %1 -j ACCEPT").arg(server);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
QStringList LinuxFirewall::getBlockRule(const QStringList& servers)
|
||||
{
|
||||
QStringList result;
|
||||
for (const QString& server : servers)
|
||||
{
|
||||
result << QStringLiteral("-d %1 -j REJECT").arg(server);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
void LinuxFirewall::install()
|
||||
@@ -291,6 +258,8 @@ void LinuxFirewall::install()
|
||||
|
||||
installAnchor(IPv4, QStringLiteral("110.allowNets"), {});
|
||||
|
||||
installAnchor(Both, QStringLiteral("400.allowPIA"), {});
|
||||
|
||||
installAnchor(Both, QStringLiteral("100.blockAll"), {
|
||||
QStringLiteral("-j REJECT"),
|
||||
});
|
||||
@@ -454,16 +423,33 @@ void LinuxFirewall::updateDNSServers(const QStringList& servers)
|
||||
static QStringList existingServers {};
|
||||
|
||||
existingServers = servers;
|
||||
execute(QStringLiteral("iptables -F %1.320.allowDNS").arg(kAnchorName));
|
||||
for (const QString& rule : getDNSRules(servers))
|
||||
execute(QStringLiteral("iptables -A %1.320.allowDNS %2").arg(kAnchorName, rule));
|
||||
const QString chain = QStringLiteral("%1.320.allowDNS").arg(kAnchorName);
|
||||
executeIptables(QStringLiteral("iptables"), {QStringLiteral("-F"), chain});
|
||||
const QStringList ifaces = {
|
||||
QStringLiteral("amn0+"), QStringLiteral("tun0+"), QStringLiteral("tun2+")
|
||||
};
|
||||
for (const QString& server : servers) {
|
||||
for (const QString& iface : ifaces) {
|
||||
executeIptables(QStringLiteral("iptables"),
|
||||
{QStringLiteral("-A"), chain, QStringLiteral("-o"), iface,
|
||||
QStringLiteral("-d"), server, QStringLiteral("-p"), QStringLiteral("udp"),
|
||||
QStringLiteral("--dport"), QStringLiteral("53"), QStringLiteral("-j"), QStringLiteral("ACCEPT")});
|
||||
executeIptables(QStringLiteral("iptables"),
|
||||
{QStringLiteral("-A"), chain, QStringLiteral("-o"), iface,
|
||||
QStringLiteral("-d"), server, QStringLiteral("-p"), QStringLiteral("tcp"),
|
||||
QStringLiteral("--dport"), QStringLiteral("53"), QStringLiteral("-j"), QStringLiteral("ACCEPT")});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void LinuxFirewall::updateAllowNets(const QStringList& servers)
|
||||
{
|
||||
execute(QStringLiteral("iptables -F %1.110.allowNets").arg(kAnchorName));
|
||||
for (const QString& rule : getAllowRule(servers))
|
||||
execute(QStringLiteral("iptables -A %1.110.allowNets %2").arg(kAnchorName, rule));
|
||||
const QString chain = QStringLiteral("%1.110.allowNets").arg(kAnchorName);
|
||||
executeIptables(QStringLiteral("iptables"), {QStringLiteral("-F"), chain});
|
||||
for (const QString& server : servers)
|
||||
executeIptables(QStringLiteral("iptables"),
|
||||
{QStringLiteral("-A"), chain, QStringLiteral("-d"), server,
|
||||
QStringLiteral("-j"), QStringLiteral("ACCEPT")});
|
||||
}
|
||||
|
||||
void LinuxFirewall::updateBlockNets(const QStringList& servers)
|
||||
@@ -471,9 +457,12 @@ void LinuxFirewall::updateBlockNets(const QStringList& servers)
|
||||
static QStringList existingServers {};
|
||||
|
||||
existingServers = servers;
|
||||
execute(QStringLiteral("iptables -F %1.120.blockNets").arg(kAnchorName));
|
||||
for (const QString& rule : getBlockRule(servers))
|
||||
execute(QStringLiteral("iptables -A %1.120.blockNets %2").arg(kAnchorName, rule));
|
||||
const QString chain = QStringLiteral("%1.120.blockNets").arg(kAnchorName);
|
||||
executeIptables(QStringLiteral("iptables"), {QStringLiteral("-F"), chain});
|
||||
for (const QString& server : servers)
|
||||
executeIptables(QStringLiteral("iptables"),
|
||||
{QStringLiteral("-A"), chain, QStringLiteral("-d"), server,
|
||||
QStringLiteral("-j"), QStringLiteral("REJECT")});
|
||||
}
|
||||
|
||||
int waitForExitCode(QProcess& process)
|
||||
@@ -506,10 +495,39 @@ int LinuxFirewall::execute(const QString &command, bool ignoreErrors)
|
||||
return exitCode;
|
||||
}
|
||||
|
||||
int LinuxFirewall::executeIptables(const QString &program, const QStringList &args, bool ignoreErrors)
|
||||
{
|
||||
QProcess p;
|
||||
p.start(program, args, QProcess::ReadOnly);
|
||||
p.closeWriteChannel();
|
||||
|
||||
int exitCode = waitForExitCode(p);
|
||||
auto out = p.readAllStandardOutput().trimmed();
|
||||
auto err = p.readAllStandardError().trimmed();
|
||||
if ((exitCode != 0 || !err.isEmpty()) && !ignoreErrors)
|
||||
logger.warning() << "(" << exitCode << ") $ " << program << args.join(QLatin1Char(' '));
|
||||
if (!out.isEmpty())
|
||||
logger.info() << out;
|
||||
if (!err.isEmpty())
|
||||
logger.warning() << err;
|
||||
return exitCode;
|
||||
}
|
||||
|
||||
void LinuxFirewall::setupTrafficSplitting()
|
||||
{
|
||||
const QString cgroupBase = QStringLiteral("/sys/fs/cgroup/net_cls");
|
||||
if (!QFileInfo::exists(cgroupBase)) {
|
||||
logger.warning() << "net_cls cgroup v1 not available, traffic splitting disabled";
|
||||
return;
|
||||
}
|
||||
|
||||
execute(QStringLiteral(
|
||||
"if ! grep -qE '^[0-9]+[[:space:]]+%1$' /etc/iproute2/rt_tables 2>/dev/null ; then "
|
||||
"echo '200 %1' >> /etc/iproute2/rt_tables ; fi"
|
||||
).arg(kRtableName));
|
||||
|
||||
auto cGroupDir = "/sys/fs/cgroup/net_cls/" BRAND_CODE "vpnexclusions/";
|
||||
logger.info() << "Should be setting up cgroup in" << cGroupDir << "for traffic splitting";
|
||||
logger.info() << "Setting up cgroup in" << cGroupDir << "for traffic splitting";
|
||||
execute(QStringLiteral("if [ ! -d %1 ] ; then mkdir %1 ; sleep 0.1 ; echo %2 > %1/net_cls.classid ; fi").arg(cGroupDir).arg(kCGroupId));
|
||||
// Set a rule with priority 100 (lower priority than local but higher than main/default, 0 is highest priority)
|
||||
execute(QStringLiteral("if ! ip rule list | grep -q %1 ; then ip rule add from all fwmark %1 lookup %2 pri 100 ; fi").arg(kPacketTag, kRtableName));
|
||||
@@ -518,7 +536,7 @@ void LinuxFirewall::setupTrafficSplitting()
|
||||
void LinuxFirewall::teardownTrafficSplitting()
|
||||
{
|
||||
logger.info() << "Tearing down cgroup and routing rules";
|
||||
execute(QStringLiteral("if ip rule list | grep -q %1; then ip rule del from all fwmark %1 lookup %2 2> /dev/null ; fi").arg(kPacketTag, kRtableName));
|
||||
execute(QStringLiteral("ip route flush table %1").arg(kRtableName));
|
||||
execute(QStringLiteral("if ip rule list | grep -q %1; then ip rule del from all fwmark %1 lookup %2 2>/dev/null ; fi").arg(kPacketTag, kRtableName));
|
||||
execute(QStringLiteral("ip route flush table %1 2>/dev/null || true").arg(kRtableName));
|
||||
execute(QStringLiteral("ip route flush cache"));
|
||||
}
|
||||
|
||||
@@ -79,12 +79,10 @@ private:
|
||||
static int unlinkChain(IPVersion ip, const QString& chain, const QString& parent, const QString& tableName = kFilterTable);
|
||||
static void installAnchor(IPVersion ip, const QString& anchor, const QStringList& rules, const QString& tableName = kFilterTable, const FilterCallbackFunc& enableFunc = {}, const FilterCallbackFunc& disableFunc = {});
|
||||
static void uninstallAnchor(IPVersion ip, const QString& anchor, const QString& tableName = kFilterTable);
|
||||
static QStringList getDNSRules(const QStringList& servers);
|
||||
static QStringList getAllowRule(const QStringList& servers);
|
||||
static QStringList getBlockRule(const QStringList& servers);
|
||||
static void setupTrafficSplitting();
|
||||
static void teardownTrafficSplitting();
|
||||
static int execute(const QString& command, bool ignoreErrors = false);
|
||||
static int executeIptables(const QString& program, const QStringList& args, bool ignoreErrors = false);
|
||||
private:
|
||||
// Chain names
|
||||
static QString kOutputChain, kRootChain, kPostRoutingChain, kPreRoutingChain;
|
||||
|
||||
@@ -167,6 +167,12 @@ bool WireguardUtilsLinux::addInterface(const InterfaceConfig& config) {
|
||||
if (!config.m_maxHandshakeAttempts.isEmpty()) {
|
||||
out << "max_handshake_attempts=" << config.m_maxHandshakeAttempts << "\n";
|
||||
}
|
||||
if (!config.m_randomTrailers.isEmpty()) {
|
||||
out << "random_trailers=" << InterfaceConfig::awgBoolToUapi(config.m_randomTrailers) << "\n";
|
||||
}
|
||||
if (!config.m_disableCookies.isEmpty()) {
|
||||
out << "disable_cookies=" << InterfaceConfig::awgBoolToUapi(config.m_disableCookies) << "\n";
|
||||
}
|
||||
|
||||
int err = uapiErrno(uapiCommand(message));
|
||||
if (err != 0) {
|
||||
|
||||
@@ -165,6 +165,12 @@ bool WireguardUtilsMacos::addInterface(const InterfaceConfig& config) {
|
||||
if (!config.m_maxHandshakeAttempts.isEmpty()) {
|
||||
out << "max_handshake_attempts=" << config.m_maxHandshakeAttempts << "\n";
|
||||
}
|
||||
if (!config.m_randomTrailers.isEmpty()) {
|
||||
out << "random_trailers=" << InterfaceConfig::awgBoolToUapi(config.m_randomTrailers) << "\n";
|
||||
}
|
||||
if (!config.m_disableCookies.isEmpty()) {
|
||||
out << "disable_cookies=" << InterfaceConfig::awgBoolToUapi(config.m_disableCookies) << "\n";
|
||||
}
|
||||
|
||||
int err = uapiErrno(uapiCommand(message));
|
||||
if (err != 0) {
|
||||
|
||||
@@ -17,7 +17,10 @@ using namespace QKeychain;
|
||||
namespace {
|
||||
constexpr const char *settingsKeyTag = "settingsKeyTag";
|
||||
constexpr const char *settingsIvTag = "settingsIvTag";
|
||||
constexpr const char *keyChainName = "AmneziaVPN-Keychain";
|
||||
#ifndef CLIENT_KEYCHAIN_NAME_STR
|
||||
#define CLIENT_KEYCHAIN_NAME_STR "AmneziaVPN-Keychain"
|
||||
#endif
|
||||
constexpr const char *keyChainName = CLIENT_KEYCHAIN_NAME_STR;
|
||||
}
|
||||
|
||||
SecureQSettings::SecureQSettings(const QString &organization, const QString &application, QObject *parent, bool enableEncryption)
|
||||
|
||||
@@ -32,6 +32,8 @@ RekeyTimeout = $REKEY_TIMEOUT
|
||||
RejectAfterTime = $REJECT_AFTER_TIME
|
||||
KeepaliveTimeout = $KEEPALIVE_TIMEOUT
|
||||
MaxHandshakeAttempts = $MAX_HANDSHAKE_ATTEMPTS
|
||||
RandomTrailers = $RANDOM_TRAILERS
|
||||
DisableCookies = $DISABLE_COOKIES
|
||||
# I1 = $SPECIAL_JUNK_1
|
||||
# I2 = $SPECIAL_JUNK_2
|
||||
# I3 = $SPECIAL_JUNK_3
|
||||
|
||||
@@ -25,6 +25,8 @@ RekeyTimeout = $REKEY_TIMEOUT
|
||||
RejectAfterTime = $REJECT_AFTER_TIME
|
||||
KeepaliveTimeout = $KEEPALIVE_TIMEOUT
|
||||
MaxHandshakeAttempts = $MAX_HANDSHAKE_ATTEMPTS
|
||||
RandomTrailers = $RANDOM_TRAILERS
|
||||
DisableCookies = $DISABLE_COOKIES
|
||||
|
||||
[Peer]
|
||||
PublicKey = $WIREGUARD_SERVER_PUBLIC_KEY
|
||||
|
||||
6731
client/translations/amneziavpn_es_ES.ts
Normal file
6731
client/translations/amneziavpn_ko_KR.ts
Normal file
@@ -272,7 +272,7 @@ bool SubscriptionUiController::restoreServiceFromAppStore()
|
||||
return false;
|
||||
}
|
||||
|
||||
emit installServerFromApiFinished(tr("Subscription restored successfully."));
|
||||
emit installServerFromApiFinished(tr("Subscription restored successfully"));
|
||||
if (result.duplicateCount > 0) {
|
||||
qInfo().noquote() << "[IAP] Skipped" << result.duplicateCount
|
||||
<< "duplicate restored transactions for original transaction IDs already processed";
|
||||
@@ -469,7 +469,7 @@ bool SubscriptionUiController::importTrialFromGateway(const QString &email)
|
||||
if (errorCode != ErrorCode::NoError) {
|
||||
if (errorCode == ErrorCode::ApiTrialAlreadyUsedError) {
|
||||
emit trialEmailError(
|
||||
tr("This email address has already been used to activate a trial. If you like the service, you can upgrade to Premium"));
|
||||
tr("This email address has already been used to activate a trial. Like the service? Upgrade to Premium"));
|
||||
} else {
|
||||
emit errorOccurred(errorCode);
|
||||
}
|
||||
@@ -648,7 +648,7 @@ QStringList SubscriptionUiController::availableProtocols(const QString &serverId
|
||||
void SubscriptionUiController::removeApiConfig(const QString &serverId)
|
||||
{
|
||||
m_subscriptionController->removeApiConfig(serverId);
|
||||
emit apiConfigRemoved(tr("Api config removed"));
|
||||
emit apiConfigRemoved(tr("API config removed"));
|
||||
}
|
||||
|
||||
void SubscriptionUiController::removeServer(const QString &serverId)
|
||||
|
||||